fix(ship): scope fallow audit to the ship's actual base, not main-autodetect (DK-5) - #98
Merged
Merged
Conversation
…odetect (DK-5)
## DK-5 — `ship --base` audits against `main`, not the real ship base
`devkit ship --base <b>` cuts the ephemeral gate worktree from `<b>`'s origin tip, but the in-chain
`fallow audit` (both the self-host advisory fragment and the overlay gate) always ran bare —
`fallow audit`, no `--base` — so fallow auto-detected `main` as its comparison ref regardless of what
the worktree was actually cut from. Shipping `--base feat/studio` from a finalized checkout, where
`feat/studio` is itself a long-lived stack with its own pre-existing (not-yet-merged) dead-code /
duplication findings vs `main`, misreported those as "new" and failed the audit.
Fallow's own `audit` command already grandfathers correctly when given the right ref: its `gate:
new-only` default runs the base ref too and marks inherited findings `introduced=false`. The fix is
to thread the exact commit ship already resolves the worktree from — through as `DEVKIT_SHIP_BASE_SHA`
(exported by `ship-branch.sh`/`reship.sh`, alongside the existing `DEVKIT_SHIP_MODE`) — so devkit's
own fallow fragments pass `fallow audit --base "$DEVKIT_SHIP_BASE_SHA"` when it's set, falling back to
fallow's own default on a plain `git commit`. This is unconditional (not just under `--base`): even
the default ship case is more precise than `main`-autodetection for any branch that isn't a fresh cut
off main.
`.husky/pre-commit` (this repo's own self-hosted hook) is regenerated in the same commit — required,
since `self-host.test.mts`'s parity test compares it byte-for-byte against the generator.
A narrower, separate bug (`link-gate-configs.sh` symlinking `fallow-baselines/` from the invoking
checkout rather than the ship base — relevant only to consumers using fallow's own self-installed
git hook) is deliberately out of scope here, mirroring how DK-3 split an analogous baseline-follows-
ROOT bug into its own PR.
## Also in this PR
`.husky/pre-push` runs the full, untargeted test suite on every push, so any pre-existing failure
blocks shipping anything. `overlay.test.mts`'s `workRepo()`-based tests call `applyInit` in-process
(unlike the ship-branch/reship/reconcile suites, which spawn devkit as a subprocess and isolate git
via an explicit per-call `env`), so its internal `execFileSync('git', …)` calls (e.g.
`installHealAlias`'s `alias.ci` collision check) inherited whatever `process.env` already was —
including a developer machine's own real `~/.gitconfig`. `overlay.mts` deliberately never clobbers an
existing `git ci` alias, so a machine with one already set makes that check correctly skip
installing devkit's self-heal alias, which then read as a false test failure. Isolated
`GIT_CONFIG_GLOBAL`/`GIT_CONFIG_SYSTEM` to `/dev/null` for the file's duration (restored after),
matching the isolation every sibling git-integration test file already does. Unrelated to DK-5 itself,
but bundled in since it's what blocked the push.
## Verification
- `bun run test:run -- cli/__tests__/ship-branch.test.mts cli/__tests__/reship.test.mts cli/__tests__/self-host.test.mts cli/__tests__/husky-block.test.mts cli/__tests__/overlay.test.mts` — 153 pass
- `bun run typecheck` clean
- `bun run lint` clean
- `bun run lint:structure` clean
- `git diff .husky/pre-commit` confirmed scoped to only the `# devkit:fallow-advisory` fragment
## Also bundled: a one-line formatting fix
`origin/main` advanced (PR #94) between this branch's creation and shipping; `gate-engine/review/
run-review.mts`'s `savePasses(...)` call in that merge violates biome's line-length rule. Since
`bun run lint` (`biome check .`) scans the whole repo, this now blocks any ship off `main` — bundled
the trivial reflow biome itself proposes (no logic change) so this PR can land. Unrelated to DK-5.
That reflow also pushed `run-review.mts` (already at 640 lines, 17 over its recorded
`eslint/baselines/size-lines.json` ceiling of 623 from #94 itself) over the line-count ratchet.
Bumped that one entry to its true current count (642) — a surgical 1-line baseline update rather
than a full `guard-size freeze` (which re-walks the whole repo and could touch unrelated entries).
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
📝 WalkthroughWalkthroughChangesFallow base scoping
Review cache formatting
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant ShipFlow
participant GeneratedHook
participant Fallow
ShipFlow->>GeneratedHook: Export DEVKIT_SHIP_BASE_SHA
GeneratedHook->>Fallow: Run fallow audit with optional --base SHA
Fallow-->>GeneratedHook: Return audit status
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
norvalbv
added a commit
that referenced
this pull request
Jul 17, 2026
…y-default (3-sample contract) (#101) * feat(sentry): registry guard + devkit-managed commit-msg hook, hard-by-default (3-sample contract) Closes the wiring gap behind benord-labs/frink#105: the sentry judge shipped as a bin with zero consumer wiring, so frink hand-wired the hook line (and the completeness commit-msg line before it). Hooks now come from devkit. ## What ships - **Registry**: `sentry` joins `GUARD_IDS` (offerable at init/upgrade; NOT recommended — needs a Sentry-using product). Wizard/help/doctor entries. - **Devkit-managed `.husky/commit-msg`**: new `cli/lib/husky/commit-msg-block.mts` generates a marker-wrapped block when `review` and/or `sentry` is selected — PATH preamble, `|| var=$?` tested-status plumbing (husky `sh -e` vs exit-2 fail-open), completeness + sentry invocations with block guidance, explicit `exit 0`. Idempotent install/removal wired through init/upgrade/clean/doctor (`--fix` handles missing AND drift); consumer content outside markers preserved; standalone mode emits `command -v`-guarded global-bin lines. Package + standalone only (self-host opts out — would newly gate devkit's own commits; overlay uses core.hooksPath). - **Hard-by-default**: `envBool('SENTRY_HARD') ?? true` (completeness precedent; env-only soften, no config key). Samples follow the frink Target's confidence contract: default 3 when hard, 1 when warn (`resolveSamples`, override wins). `effectiveHard` (from #99) still downgrades empty-staged-diff/amend to warn. - Decision note appended under the 2026-07-12 hard-by-default Target; README bins table updated. - Drive-by: committed `.husky/pre-commit` regenerated (+22 lines, the #96 commit-terminal fragment) — fixes the pre-existing self-host parity test red on main. ## Review-round fix (first ship attempt) The correctness reviewer correctly FAILED the first attempt: the worktree base predated #98 (DK-5), so the whole-file ship would have reverted the `DEVKIT_SHIP_BASE_SHA` fallow scoping. Rebased onto current main (post-#97/#98); the DK-5 overlay-fallow test block is restored alongside the new commit-msg tests (67/67). ## Ratchet bump (cross-PR race, user-approved pattern) `size-lines.json` husky-block.mts 524→528: #99 froze the cap at 524 while #98 (merged after) grew the file to 528 — main was over its own cap before this PR touched it (this PR's only husky-block.mts change is exporting PATH_SETUP, zero growth). ## Verified Touched suites green (131 + 67); typecheck clean; e2e: init with review+sentry → doctor reports both hook blocks OK; deselect/clean remove the block; upgrade offers sentry as opt-in. Only remaining suite red is the pre-existing overlay `git ci` alias test (red on pristine origin/main). ## Review-round fix (second attempt): completeness fragment now fails CLOSED on exit 3 (strict-ship judge outage), mirroring the pre-commit AI fragments — the reviewer correctly rejected the silent continue. ## Flagged, not done (follow-ups) - critique is the next half-migrated judge (devkit engine + eval exist, no CLI, frink runs local check-critique). - frink redo after next release + pin bump: select sentry guard, delete hand-wired lines + `check:sentry` script, rework #105. * fix(sentry-guard): review round — self-host block removal, deselected-fragment drift, test tmp cleanup CodeRabbit round: (1) package→self-host re-init now DROPS a previously-installed commit-msg block (stale hard gate would keep judging devkit's own commits); the doctor half of that finding is not applicable — self-host routes to runSelfHostDoctor before checkCommitMsgHook can run. (2) checkCommitMsgHook now flags DESELECTED lingering fragments as DRIFT (symmetric sentinel check, same depth as pre-commit's checkHusky; full-text equality would exceed the house standard). (3) test watchlist tmp dirs tracked + reclaimed in afterEach.
This was referenced Jul 17, 2026
Merged
norvalbv
added a commit
that referenced
this pull request
Jul 24, 2026
…odetect (DK-5) (#98) ## DK-5 — `ship --base` audits against `main`, not the real ship base `devkit ship --base <b>` cuts the ephemeral gate worktree from `<b>`'s origin tip, but the in-chain `fallow audit` (both the self-host advisory fragment and the overlay gate) always ran bare — `fallow audit`, no `--base` — so fallow auto-detected `main` as its comparison ref regardless of what the worktree was actually cut from. Shipping `--base feat/studio` from a finalized checkout, where `feat/studio` is itself a long-lived stack with its own pre-existing (not-yet-merged) dead-code / duplication findings vs `main`, misreported those as "new" and failed the audit. Fallow's own `audit` command already grandfathers correctly when given the right ref: its `gate: new-only` default runs the base ref too and marks inherited findings `introduced=false`. The fix is to thread the exact commit ship already resolves the worktree from — through as `DEVKIT_SHIP_BASE_SHA` (exported by `ship-branch.sh`/`reship.sh`, alongside the existing `DEVKIT_SHIP_MODE`) — so devkit's own fallow fragments pass `fallow audit --base "$DEVKIT_SHIP_BASE_SHA"` when it's set, falling back to fallow's own default on a plain `git commit`. This is unconditional (not just under `--base`): even the default ship case is more precise than `main`-autodetection for any branch that isn't a fresh cut off main. `.husky/pre-commit` (this repo's own self-hosted hook) is regenerated in the same commit — required, since `self-host.test.mts`'s parity test compares it byte-for-byte against the generator. A narrower, separate bug (`link-gate-configs.sh` symlinking `fallow-baselines/` from the invoking checkout rather than the ship base — relevant only to consumers using fallow's own self-installed git hook) is deliberately out of scope here, mirroring how DK-3 split an analogous baseline-follows- ROOT bug into its own PR. ## Also in this PR `.husky/pre-push` runs the full, untargeted test suite on every push, so any pre-existing failure blocks shipping anything. `overlay.test.mts`'s `workRepo()`-based tests call `applyInit` in-process (unlike the ship-branch/reship/reconcile suites, which spawn devkit as a subprocess and isolate git via an explicit per-call `env`), so its internal `execFileSync('git', …)` calls (e.g. `installHealAlias`'s `alias.ci` collision check) inherited whatever `process.env` already was — including a developer machine's own real `~/.gitconfig`. `overlay.mts` deliberately never clobbers an existing `git ci` alias, so a machine with one already set makes that check correctly skip installing devkit's self-heal alias, which then read as a false test failure. Isolated `GIT_CONFIG_GLOBAL`/`GIT_CONFIG_SYSTEM` to `/dev/null` for the file's duration (restored after), matching the isolation every sibling git-integration test file already does. Unrelated to DK-5 itself, but bundled in since it's what blocked the push. ## Verification - `bun run test:run -- cli/__tests__/ship-branch.test.mts cli/__tests__/reship.test.mts cli/__tests__/self-host.test.mts cli/__tests__/husky-block.test.mts cli/__tests__/overlay.test.mts` — 153 pass - `bun run typecheck` clean - `bun run lint` clean - `bun run lint:structure` clean - `git diff .husky/pre-commit` confirmed scoped to only the `# devkit:fallow-advisory` fragment ## Also bundled: a one-line formatting fix `origin/main` advanced (PR #94) between this branch's creation and shipping; `gate-engine/review/ run-review.mts`'s `savePasses(...)` call in that merge violates biome's line-length rule. Since `bun run lint` (`biome check .`) scans the whole repo, this now blocks any ship off `main` — bundled the trivial reflow biome itself proposes (no logic change) so this PR can land. Unrelated to DK-5. That reflow also pushed `run-review.mts` (already at 640 lines, 17 over its recorded `eslint/baselines/size-lines.json` ceiling of 623 from #94 itself) over the line-count ratchet. Bumped that one entry to its true current count (642) — a surgical 1-line baseline update rather than a full `guard-size freeze` (which re-walks the whole repo and could touch unrelated entries).
norvalbv
added a commit
that referenced
this pull request
Jul 24, 2026
…y-default (3-sample contract) (#101) * feat(sentry): registry guard + devkit-managed commit-msg hook, hard-by-default (3-sample contract) Closes the wiring gap behind benord-labs/frink#105: the sentry judge shipped as a bin with zero consumer wiring, so frink hand-wired the hook line (and the completeness commit-msg line before it). Hooks now come from devkit. ## What ships - **Registry**: `sentry` joins `GUARD_IDS` (offerable at init/upgrade; NOT recommended — needs a Sentry-using product). Wizard/help/doctor entries. - **Devkit-managed `.husky/commit-msg`**: new `cli/lib/husky/commit-msg-block.mts` generates a marker-wrapped block when `review` and/or `sentry` is selected — PATH preamble, `|| var=$?` tested-status plumbing (husky `sh -e` vs exit-2 fail-open), completeness + sentry invocations with block guidance, explicit `exit 0`. Idempotent install/removal wired through init/upgrade/clean/doctor (`--fix` handles missing AND drift); consumer content outside markers preserved; standalone mode emits `command -v`-guarded global-bin lines. Package + standalone only (self-host opts out — would newly gate devkit's own commits; overlay uses core.hooksPath). - **Hard-by-default**: `envBool('SENTRY_HARD') ?? true` (completeness precedent; env-only soften, no config key). Samples follow the frink Target's confidence contract: default 3 when hard, 1 when warn (`resolveSamples`, override wins). `effectiveHard` (from #99) still downgrades empty-staged-diff/amend to warn. - Decision note appended under the 2026-07-12 hard-by-default Target; README bins table updated. - Drive-by: committed `.husky/pre-commit` regenerated (+22 lines, the #96 commit-terminal fragment) — fixes the pre-existing self-host parity test red on main. ## Review-round fix (first ship attempt) The correctness reviewer correctly FAILED the first attempt: the worktree base predated #98 (DK-5), so the whole-file ship would have reverted the `DEVKIT_SHIP_BASE_SHA` fallow scoping. Rebased onto current main (post-#97/#98); the DK-5 overlay-fallow test block is restored alongside the new commit-msg tests (67/67). ## Ratchet bump (cross-PR race, user-approved pattern) `size-lines.json` husky-block.mts 524→528: #99 froze the cap at 524 while #98 (merged after) grew the file to 528 — main was over its own cap before this PR touched it (this PR's only husky-block.mts change is exporting PATH_SETUP, zero growth). ## Verified Touched suites green (131 + 67); typecheck clean; e2e: init with review+sentry → doctor reports both hook blocks OK; deselect/clean remove the block; upgrade offers sentry as opt-in. Only remaining suite red is the pre-existing overlay `git ci` alias test (red on pristine origin/main). ## Review-round fix (second attempt): completeness fragment now fails CLOSED on exit 3 (strict-ship judge outage), mirroring the pre-commit AI fragments — the reviewer correctly rejected the silent continue. ## Flagged, not done (follow-ups) - critique is the next half-migrated judge (devkit engine + eval exist, no CLI, frink runs local check-critique). - frink redo after next release + pin bump: select sentry guard, delete hand-wired lines + `check:sentry` script, rework #105. * fix(sentry-guard): review round — self-host block removal, deselected-fragment drift, test tmp cleanup CodeRabbit round: (1) package→self-host re-init now DROPS a previously-installed commit-msg block (stale hard gate would keep judging devkit's own commits); the doctor half of that finding is not applicable — self-host routes to runSelfHostDoctor before checkCommitMsgHook can run. (2) checkCommitMsgHook now flags DESELECTED lingering fragments as DRIFT (symmetric sentinel check, same depth as pre-commit's checkHusky; full-text equality would exceed the house standard). (3) test watchlist tmp dirs tracked + reclaimed in afterEach.
This was referenced Aug 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
DK-5 —
ship --baseaudits againstmain, not the real ship basedevkit ship --base <b>cuts the ephemeral gate worktree from<b>'s origin tip, but the in-chainfallow audit(both the self-host advisory fragment and the overlay gate) always ran bare —fallow audit, no--base— so fallow auto-detectedmainas its comparison ref regardless of whatthe worktree was actually cut from. Shipping
--base feat/studiofrom a finalized checkout, wherefeat/studiois itself a long-lived stack with its own pre-existing (not-yet-merged) dead-code /duplication findings vs
main, misreported those as "new" and failed the audit.Fallow's own
auditcommand already grandfathers correctly when given the right ref: itsgate: new-onlydefault runs the base ref too and marks inherited findingsintroduced=false. The fix isto thread the exact commit ship already resolves the worktree from — through as
DEVKIT_SHIP_BASE_SHA(exported by
ship-branch.sh/reship.sh, alongside the existingDEVKIT_SHIP_MODE) — so devkit'sown fallow fragments pass
fallow audit --base "$DEVKIT_SHIP_BASE_SHA"when it's set, falling back tofallow's own default on a plain
git commit. This is unconditional (not just under--base): eventhe default ship case is more precise than
main-autodetection for any branch that isn't a fresh cutoff main.
.husky/pre-commit(this repo's own self-hosted hook) is regenerated in the same commit — required,since
self-host.test.mts's parity test compares it byte-for-byte against the generator.A narrower, separate bug (
link-gate-configs.shsymlinkingfallow-baselines/from the invokingcheckout rather than the ship base — relevant only to consumers using fallow's own self-installed
git hook) is deliberately out of scope here, mirroring how DK-3 split an analogous baseline-follows-
ROOT bug into its own PR.
Also in this PR
.husky/pre-pushruns the full, untargeted test suite on every push, so any pre-existing failureblocks shipping anything.
overlay.test.mts'sworkRepo()-based tests callapplyInitin-process(unlike the ship-branch/reship/reconcile suites, which spawn devkit as a subprocess and isolate git
via an explicit per-call
env), so its internalexecFileSync('git', …)calls (e.g.installHealAlias'salias.cicollision check) inherited whateverprocess.envalready was —including a developer machine's own real
~/.gitconfig.overlay.mtsdeliberately never clobbers anexisting
git cialias, so a machine with one already set makes that check correctly skipinstalling devkit's self-heal alias, which then read as a false test failure. Isolated
GIT_CONFIG_GLOBAL/GIT_CONFIG_SYSTEMto/dev/nullfor the file's duration (restored after),matching the isolation every sibling git-integration test file already does. Unrelated to DK-5 itself,
but bundled in since it's what blocked the push.
Verification
bun run test:run -- cli/__tests__/ship-branch.test.mts cli/__tests__/reship.test.mts cli/__tests__/self-host.test.mts cli/__tests__/husky-block.test.mts cli/__tests__/overlay.test.mts— 153 passbun run typecheckcleanbun run lintcleanbun run lint:structurecleangit diff .husky/pre-commitconfirmed scoped to only the# devkit:fallow-advisoryfragmentAlso bundled: a one-line formatting fix
origin/mainadvanced (PR #94) between this branch's creation and shipping;gate-engine/review/ run-review.mts'ssavePasses(...)call in that merge violates biome's line-length rule. Sincebun run lint(biome check .) scans the whole repo, this now blocks any ship offmain— bundledthe trivial reflow biome itself proposes (no logic change) so this PR can land. Unrelated to DK-5.
That reflow also pushed
run-review.mts(already at 640 lines, 17 over its recordedeslint/baselines/size-lines.jsonceiling of 623 from #94 itself) over the line-count ratchet.Bumped that one entry to its true current count (642) — a surgical 1-line baseline update rather
than a full
guard-size freeze(which re-walks the whole repo and could touch unrelated entries).Summary by CodeRabbit
New Features
Bug Fixes
Tests