Skip to content

feat: add track-latest dev install mode to ahoy install#139

Open
REPPL wants to merge 3 commits into
fix/iss-101-102-lockless-lmw-classfrom
feat/iss-75-dev-install-mode
Open

feat: add track-latest dev install mode to ahoy install#139
REPPL wants to merge 3 commits into
fix/iss-101-102-lockless-lmw-classfrom
feat/iss-75-dev-install-mode

Conversation

@REPPL

@REPPL REPPL commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Adds the always-latest dev install mode for dogfooding (ledger issue iss-75, minor): abcd ahoy install --dev installs a rebuild-from-source shim at the PATH target instead of the pinned-binary symlink, so the dogfooded binary is always the tip build and the hand-rolled wrapper the issue captured is retired.

Chained PR: base is fix/iss-101-102-lockless-lmw-class (#138) — this branch edits the same ahoy install files and ledger-resolves with the chained --impact verb. Merge order #136#137#138 → this; GitHub retargets automatically.

What changed

  • Dev mode writes a POSIX-sh shim (via the atomic no-follow writer, 0755) that runs go build against the resolved plugin root and execs the fresh binary on every invocation. A broken build prints loudly to stderr and exits 1 before the exec — a stale binary is never silently run.
  • The mode is surfaced from the filesystem, not recorded in config: status/detect recognise the shim on disk and report "dev (tip build)". One deliberate deviation from the original direction is documented here: recording the mode in .abcd/config.json was dropped — nothing reads that section, the file is git-tracked (machine-local state does not belong in a committed file), and the on-disk signal cannot go stale.
  • Transitions apply-as-update in both directions (pinned ↔ dev) with an install_mode change echo, per the established install-over-install semantics; uninstall removes the shim; normal install behaviour is pinned by a regression test.
  • Wired end to end: CLI --dev flag, plugin surface docs, regenerated CLI reference and surface registry, CHANGELOG (Added).
  • Scope notes reported, not silently expanded: plugin hooks invoke the plugin-root binary directly and therefore track the tip lagging by one CLI call; --dev pointed at a packaged (non-source) plugin root fails loudly on every call — dogfood-only by design, documented.

Verification

  • Test-first throughout, watched to fail: shim shape + loud-fail path, normal-install regression pin, both transition directions, the real rendered shim executed against a failing toolchain (loud error, no stale exec) and a succeeding one (exec with args), and the detect/status signal.
  • Gate run independently by the orchestrator: make preflight exit 0 (build, gofmt, vet, tests, race), record-lint exit 0.
  • iss-75 resolved open/ → resolved/ on this branch with impact: additive.
  • Independent reviews before this PR opened: security APPROVE with zero findings (the '\'' escaping was verified empirically against live /bin/sh with adversarial paths; provenance, foreign-file and uninstall guards all held; the shim narrows exposure versus the retired wrapper). Correctness initially FIX-FIRST on one confirmed defect — a fresh --dev install wrote the machine-scope shim even when the ConfigChange (PATH) approval was declined, a consent bypass the plain install doesn't have — fixed in the third commit (the forced-mode check narrowed to the genuine symlink→shim switch, with a watched-fail reproduction, the approved path re-verified, and the mirror direction confirmed hole-free), then re-reviewed PROMOTE.

REPPL added 3 commits July 25, 2026 17:04
`abcd ahoy install` symlinks the pinned built binary, so dogfooding live
development meant hand-rolling a `~/.local/bin/abcd` wrapper that ran
`go build -C <repo> && exec` on every call. This retires that workaround.

`--dev` installs a POSIX-sh shim at the same PATH target that rebuilds abcd
from the source tip on every invocation and execs the fresh binary. A broken
build fails loudly and never execs a stale binary (loud-staging). The mode is
detected from the installed shim itself and surfaced by `abcd ahoy` status as
`install: dev (tip build)` — never recorded in the tracked repo config, so it
can never go stale or dirty a committed file. Installing over an existing
install applies-as-update in either direction; a foreign occupant is never
clobbered, and uninstall removes the shim (it is ours).

Wired through the CLI flag, the ahoy plugin surface, and the regenerated CLI
reference and compatibility surface. The shim is written with the store's
no-follow atomic writer and recognised by an exact prefix, per the security
review; the config-recording mechanism the original design proposed was dropped
as dead (nothing reads it) per the code review.

Assisted-by: Claude:claude-opus-4-8
The track-latest dev install mode (abcd ahoy install --dev) settles the open
fork: build the mode, not document the wrapper.

Assisted-by: Claude:claude-opus-4-8
modeWouldChange's --dev branch returned true for an absent PATH target
(kind != binTargetDevShim), setting modeForced on a fresh install. stepSymlink
then wrote the machine-scope shim even when the user declined the ConfigChange
(PATH) approval — a consent bypass a plain install does not have.

Narrow the --dev branch to the genuine switch (kind == binTargetOwnedSymlink):
a fresh --dev install now flows through the symlink.missing gap, whose
gapDriven path respects a declined ConfigChange. Transitions (owned symlink ->
shim) stay forced and idempotence (dev shim -> already_up_to_date) is unchanged.

The mirror non-dev branch already returns false for an absent target, so it has
no equivalent hole and is left as-is.

Assisted-by: Claude:claude-opus-4-8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant