chore: retarget check-sync's sentinel gate to the worker's real system prompt #488

Merged
igor merged 5 commits from agent/487-chore-retarget-check-sync-to-the-sourced-worker into master 2026-08-09 07:31:34 +00:00
Collaborator

What this PR does

  • chore: retarget check-sync's sentinel gate to the worker's real system prompt
  • check-sync now validates the sourced worker-contract (via context_surface) when the Distillery cache is seeded, falling back to in-repo AGENTS.md -- and says so loudly -- only when the cache is unseeded and unreachable (the CI-container case)
  • fix lib/context-source.sh's stale atomicity comment: old cache generations do NOT survive the swap (the find -exec rm -rf after it deletes them); a mid-cat reader is safe only because unlink doesn't invalidate an already-open file descriptor
  • move bin/install.sh's .env sourcing into the seeding block that actually needs FORGEJO_HOST, instead of loading it earlier for no reason
  • bin/test-feedback.sh already set AGENT_STATE_DIR to its tmp dir as its comment claims -- no change needed there

This is the rescoped issue #487: the original ticket bundled deleting the
now-unconsumed in-repo prompt copies (AGENTS.md's body, bin/lib/*.md)
alongside the check-sync retarget, which tripped the 1000-line runaway
guard. Those deletions are split out to #488 (a human decision) and are
NOT part of this diff -- AGENTS.md and every bin/lib/*.md file are
untouched here.

Test plan

  • make test passes (check-sync validates against the sourced
    worker-contract when the local Distillery cache is seeded, as it
    is on this host)
  • Manually forced the unseeded-cache fallback path (fresh
    AGENT_STATE_DIR, FORGEJO_HOST unset) and confirmed check-sync
    prints ! prompt cache unseeded and no Distillery access -- validating AGENTS.md (fallback -- prompt cache unseeded) instead
    and still correctly validates OUTCOME sentinels + helper refs
    against the full in-repo AGENTS.md
  • make lint passes (shellcheck + mdl)

Closes #487

## What this PR does - [x] chore: retarget check-sync's sentinel gate to the worker's real system prompt - [x] check-sync now validates the sourced `worker-contract` (via `context_surface`) when the Distillery cache is seeded, falling back to in-repo `AGENTS.md` -- and says so loudly -- only when the cache is unseeded and unreachable (the CI-container case) - [x] fix `lib/context-source.sh`'s stale atomicity comment: old cache generations do NOT survive the swap (the `find -exec rm -rf` after it deletes them); a mid-cat reader is safe only because unlink doesn't invalidate an already-open file descriptor - [x] move `bin/install.sh`'s `.env` sourcing into the seeding block that actually needs `FORGEJO_HOST`, instead of loading it earlier for no reason - [x] `bin/test-feedback.sh` already set `AGENT_STATE_DIR` to its tmp dir as its comment claims -- no change needed there This is the rescoped issue #487: the original ticket bundled deleting the now-unconsumed in-repo prompt copies (`AGENTS.md`'s body, `bin/lib/*.md`) alongside the check-sync retarget, which tripped the 1000-line runaway guard. Those deletions are split out to #488 (a human decision) and are NOT part of this diff -- `AGENTS.md` and every `bin/lib/*.md` file are untouched here. ## Test plan - [x] `make test` passes (check-sync validates against the sourced worker-contract when the local Distillery cache is seeded, as it is on this host) - [x] Manually forced the unseeded-cache fallback path (fresh `AGENT_STATE_DIR`, `FORGEJO_HOST` unset) and confirmed check-sync prints `! prompt cache unseeded and no Distillery access -- validating AGENTS.md (fallback -- prompt cache unseeded) instead` and still correctly validates OUTCOME sentinels + helper refs against the full in-repo `AGENTS.md` - [x] `make lint` passes (shellcheck + mdl) Closes #487
WIP: issue #487 checkpoint -- chore: retarget check-sync to the sourced worker contract; delete unconsumed in-repo prompt copies
All checks were successful
Lint / check-sync (push) Successful in 7s
Lint / check-sync (pull_request) Successful in 7s
2b425bdf9c
WIP: issue #487 checkpoint -- chore: retarget check-sync to the sourced worker contract; delete unconsumed in-repo prompt copies
All checks were successful
Lint / check-sync (push) Successful in 8s
Lint / check-sync (pull_request) Successful in 6s
57b096e660
igor changed title from WIP: issue #487 checkpoint -- chore: retarget check-sync to the sourced worker contract; delete unconsumed in-repo prompt copies to chore: retarget check-sync's sentinel gate to the worker's real system prompt 2026-08-09 07:14:38 +00:00
The prior checkpoint did the original (pre-rescope) ticket, which
bundled deleting the in-repo bin/lib/*.md prompt copies and gutting
AGENTS.md to a stub. The issue was rescoped to split that into #488;
this ticket is now only the check-sync retarget + #486 review nits.
Restore AGENTS.md, bin/lib/*.md, and every file whose diff existed
only to support that deletion (consumer migrations in
ideation-pipeline.sh/reading-pipeline.sh, comment updates in tick.sh/
docs/lib files, and the test suites' AGENTS.md-is-a-stub assumptions).
chore: retarget check-sync's sentinel gate to the worker's real system prompt
All checks were successful
Lint / check-sync (push) Successful in 8s
Lint / check-sync (pull_request) Successful in 6s
f9cb4859df
Author
Collaborator

🤖 Review — REQUEST_CHANGES (automated)

CI for f9cb4859: success

check-sync's sentinel/helper gate now validates the sourced worker-contract when the Distillery cache is seeded and falls back to in-repo AGENTS.md (loudly) when it isn't, plus two small nits from #486. The retarget itself is the right shape, but the PR bundles in an unrequested best-effort seeding attempt that turns the repo's test gate into something that sources .env and clones over the network.

Blocking

  • bin/check-sync.sh:44-70 — unrequested clone/seed block is out of scope and side-effecting. Issue #487's deliverable 1 is "when the context cache is seeded, validate the sourced worker-contract; when unseeded, validate AGENTS.md and SAY SO." Nothing asks check-sync to seed the cache. What the diff adds instead:

    • set -a; . "$AGENT_HOME/.env"; set +a inside the gate that make test/CI runs. Every var in .env (tokens, keys) is now exported into the environment of the bin/test-*.sh scripts check-sync runs afterward. That is a new, invisible coupling and a leak surface in a script whose whole job is to be the cheap, hermetic gate.
    • git clone / git fetch against joshtronic/distillery from a test target. make test should not do network I/O or create $AGENT_STATE_DIR/repos.
    • context_refresh mutating the live prompt cache as a side effect of running the tests.
    • ssh_clone_url() and the AGENT_STATE_DIR/AGENT_REPO_ROOT/DISTILLERY_PATH derivation are copy-pasted from bin/install.sh (and tick.sh); if lib/context-source.sh ever computes those paths differently the two silently diverge.

    Fixed looks like: delete the seeding attempt, keep if context_seeded; then … else fallback …. Seeding is install.sh/tick.sh's job, and a fresh host gets the real document on its next tick anyway. If you genuinely want it, it belongs behind an explicit opt-in flag and must not source .env into the test environment.

  • bin/check-sync.sh:73-75context_surface worker-contract > "$WORKER_DOC_TMP" return code is discarded. If the surface is missing or malformed you get an empty temp file; the outcome check then reports "no OUTCOME sentinels found in the sourced worker-contract" — technically non-zero, but the helper-reference check (agent-*.sh) silently passes over an empty document, which is exactly the "checking a copy the model never reads" failure mode this PR exists to prevent. Check the exit status and fail explicitly with a distinct message.

  • No test for the new branching. The gate now has two modes and a new label in its output, and neither is covered by a bin/test-*.sh. The PR's evidence for the fallback path is "manually forced it" — honest, but it means the branch CI actually exercises (the fallback, since containers have no cache) has no regression test. At minimum, a unit test over the document-selection logic (extracted into a function) would be checkable.

Non-blocking, but please answer

  • bin/install.sh:114→130 — I can't verify the move is safe from this diff. Lines ~120-134 (between the two hunks) aren't shown; if anything in there — systemctl --user daemon-reload, enable --now, or any unit/env-file templating — reads a .env variable, moving the sourcing below it silently breaks install. Please confirm nothing in that gap consumes .env. install.sh has no test coverage, so this is inspection-only on both sides.
  • lib/context-source.sh:210-218 — the corrected unlink semantics are right and a real improvement over the old false claim. Note the guarantee is narrower than "a reader is safe": it holds for an fd already open. A reader that resolves current and then opens, or context_surface reading several files sequentially across the swap, can still lose the race. Worth saying "a reader that already opened the file" rather than "mid-cat" if you want the comment to be precisely true.
  • Net CI effect. In the container case CI still validates AGENTS.md, so the gate that actually runs on every PR is unchanged; the retarget only bites on seeded hosts. That's what #487 asked for, just flagging that the CI signal is not stronger after this PR.
  • echo " $WORKER_DOC_LABEL: …" (line ~112) won't align with the bin/tick.sh: column given the long label — cosmetic only.

Checklist / description

Description items match the diff: AGENTS.md and bin/lib/*.md are indeed untouched, the atomicity comment and install.sh move are present, and the "no change needed in bin/test-feedback.sh" claim is consistent with that file's absence from the diff (I can't verify the underlying claim without the tree). CI is green. The undisclosed item is the seeding block — the description frames the change as "validates the sourced worker-contract … falling back to AGENTS.md", which understates that check-sync now sources .env and may clone a repo.


Independent review by the harness on claude-opus-5 (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.

### 🤖 Review — `REQUEST_CHANGES` _(automated)_ CI for `f9cb4859`: **success** check-sync's sentinel/helper gate now validates the sourced `worker-contract` when the Distillery cache is seeded and falls back to in-repo `AGENTS.md` (loudly) when it isn't, plus two small nits from #486. The retarget itself is the right shape, but the PR bundles in an unrequested best-effort *seeding* attempt that turns the repo's test gate into something that sources `.env` and clones over the network. ## Blocking - **`bin/check-sync.sh:44-70` — unrequested clone/seed block is out of scope and side-effecting.** Issue #487's deliverable 1 is "when the context cache is seeded, validate the sourced worker-contract; when unseeded, validate AGENTS.md and SAY SO." Nothing asks check-sync to *seed* the cache. What the diff adds instead: - `set -a; . "$AGENT_HOME/.env"; set +a` inside the gate that `make test`/CI runs. Every var in `.env` (tokens, keys) is now **exported into the environment of the `bin/test-*.sh` scripts check-sync runs afterward**. That is a new, invisible coupling and a leak surface in a script whose whole job is to be the cheap, hermetic gate. - `git clone` / `git fetch` against `joshtronic/distillery` from a test target. `make test` should not do network I/O or create `$AGENT_STATE_DIR/repos`. - `context_refresh` mutating the live prompt cache as a side effect of running the tests. - `ssh_clone_url()` and the `AGENT_STATE_DIR`/`AGENT_REPO_ROOT`/`DISTILLERY_PATH` derivation are copy-pasted from `bin/install.sh` (and tick.sh); if `lib/context-source.sh` ever computes those paths differently the two silently diverge. Fixed looks like: delete the seeding attempt, keep `if context_seeded; then … else fallback …`. Seeding is `install.sh`/`tick.sh`'s job, and a fresh host gets the real document on its next tick anyway. If you genuinely want it, it belongs behind an explicit opt-in flag and must not source `.env` into the test environment. - **`bin/check-sync.sh:73-75` — `context_surface worker-contract > "$WORKER_DOC_TMP"` return code is discarded.** If the surface is missing or malformed you get an empty temp file; the outcome check then reports "no OUTCOME sentinels found in the sourced worker-contract" — technically non-zero, but the *helper-reference* check (`agent-*.sh`) silently passes over an empty document, which is exactly the "checking a copy the model never reads" failure mode this PR exists to prevent. Check the exit status and fail explicitly with a distinct message. - **No test for the new branching.** The gate now has two modes and a new label in its output, and neither is covered by a `bin/test-*.sh`. The PR's evidence for the fallback path is "manually forced it" — honest, but it means the branch CI actually exercises (the fallback, since containers have no cache) has no regression test. At minimum, a unit test over the document-selection logic (extracted into a function) would be checkable. ## Non-blocking, but please answer - **`bin/install.sh:114→130` — I can't verify the move is safe from this diff.** Lines ~120-134 (between the two hunks) aren't shown; if anything in there — `systemctl --user daemon-reload`, `enable --now`, or any unit/env-file templating — reads a `.env` variable, moving the sourcing below it silently breaks install. Please confirm nothing in that gap consumes `.env`. install.sh has no test coverage, so this is inspection-only on both sides. - **`lib/context-source.sh:210-218`** — the corrected unlink semantics are right and a real improvement over the old false claim. Note the guarantee is narrower than "a reader is safe": it holds for an fd *already open*. A reader that resolves `current` and then opens, or `context_surface` reading several files sequentially across the swap, can still lose the race. Worth saying "a reader that already opened the file" rather than "mid-cat" if you want the comment to be precisely true. - **Net CI effect.** In the container case CI still validates `AGENTS.md`, so the gate that actually runs on every PR is unchanged; the retarget only bites on seeded hosts. That's what #487 asked for, just flagging that the CI signal is not stronger after this PR. - `echo " $WORKER_DOC_LABEL: …"` (line ~112) won't align with the `bin/tick.sh:` column given the long label — cosmetic only. ## Checklist / description Description items match the diff: `AGENTS.md` and `bin/lib/*.md` are indeed untouched, the atomicity comment and install.sh move are present, and the "no change needed in `bin/test-feedback.sh`" claim is consistent with that file's absence from the diff (I can't verify the underlying claim without the tree). CI is green. The undisclosed item is the seeding block — the description frames the change as "validates the sourced worker-contract … falling back to AGENTS.md", which understates that check-sync now sources `.env` and may clone a repo. --- <sub>Independent review by the harness on `claude-opus-5` (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.</sub> <!-- review sha=f9cb4859df59552fe90b453d4b459fb60b063f1a verdict=REQUEST_CHANGES ci=success -->
igor added spent time 2026-08-09 07:17:14 +00:00
1 minute 24 seconds
igor self-assigned this 2026-08-09 07:17:15 +00:00
Author
Collaborator

🔧 Rework — round 1 (automated)

Addressed the review on claude-opus-5 at effort high — 1 new commit(s).

### 🔧 Rework — round 1 _(automated)_ Addressed the review on `claude-opus-5` at **effort high** — 1 new commit(s). <!-- audit:rework round=1 effort=high -->
igor removed their assignment 2026-08-09 07:27:06 +00:00
fix: drop check-sync's seeding attempt, check the surface's status, test both modes
All checks were successful
Lint / check-sync (push) Successful in 6s
Lint / check-sync (pull_request) Successful in 7s
631de3b3ce
Review round 1 on #488.

- check-sync no longer sources .env, clones/fetches the distillery, or
  calls context_refresh. The gate is read-only over the cache again;
  seeding stays install.sh's and tick.sh's job.
- A seeded cache that cannot serve worker-contract now fails with its
  own message instead of validating an empty file (the helper-reference
  check passes vacuously over one).
- The selection moves to lib/worker-doc.sh so both modes are drivable,
  covered by bin/test-worker-doc.sh -- same reason lib/suite-guard.sh
  holds check-sync's other testable logic.
- Narrow the context-source unlink comment to the guarantee that
  actually holds (an already-open fd), and drop the column padding that
  never lined up with the long label.
Author
Collaborator

🧑‍⚖️ Rework — findings dismissed (automated)

Round 1 responses

All three blocking findings are fixed in this round. Two non-blocking
items were questions; answers below.

Fixed

  • Seeding block deleted. bin/check-sync.sh no longer sources
    .env, no longer clones or fetches joshtronic/distillery, and no
    longer calls context_refresh. The gate is back to being read-only
    over the cache: seeded -> the sourced worker-contract, unseeded ->
    AGENTS.md with the loud notice. Seeding stays install.sh's and
    tick.sh's job. The copy-pasted ssh_clone_url / path derivation
    went with it, so there's nothing left to drift.
  • context_surface's exit status is checked. A seeded cache that
    can't serve worker-contract now prints
    x prompt cache is seeded but 'worker-contract' could not be served
    and exits 1, instead of validating an empty file. Verified by hand
    against a fixture cache dir holding only current/HEAD.
  • The branching is under test. The selection moved into
    lib/worker-doc.sh (worker_doc_select), following the
    lib/suite-guard.sh precedent of putting check-sync's logic in a lib
    so its failure paths are drivable. bin/test-worker-doc.sh covers all
    three modes: unseeded -> AGENTS.md + a label containing "fallback";
    seeded -> the destination file holding the sourced body verbatim;
    seeded-but-unservable -> nonzero with WORKER_DOC left empty.

Answers

  • bin/install.sh — is the .env move safe? Yes. The gap between
    the two hunks is mkdir -p "$UNIT_DIR", two ln -sf of the unit
    files, systemctl --user daemon-reload, enable --now agent.timer,
    and list-timers. UNIT_DIR is derived from $HOME at the top of
    the script, the units are symlinked (not templated), and
    systemd/agent.service carries no EnvironmentFile — only a
    hardcoded Environment="PATH=...". There is no systemctl --user import-environment anywhere in the script, so the exported .env
    never reached the manager's environment in the first place. Nothing
    in that gap reads a .env variable.
  • Net CI effect. Correct, and worth stating plainly: in the
    container CI still validates AGENTS.md, so the gate that runs on
    every PR is no stronger than before. What the retarget buys is that
    make test on a seeded host — and any future CI that gets Distillery
    access — checks the document the worker actually receives instead of
    one nobody reads. #487 scoped it that way deliberately.
  • The mid-cat comment in lib/context-source.sh is reworded to say
    what actually holds: a reader that ALREADY OPENED the file finishes
    it; one that resolves current and opens afterwards, or reads
    several surfaces across the swap, can straddle two generations — a
    stale read, never a partial one.
  • The column-alignment nit is fixed by dropping the padding after
    bin/tick.sh: rather than trying to pad to the long label.

The rest of the findings were addressed in the commits on this branch. The reviewer will re-review the new head.

### 🧑‍⚖️ Rework — findings dismissed _(automated)_ ## Round 1 responses All three blocking findings are fixed in this round. Two non-blocking items were questions; answers below. ### Fixed - **Seeding block deleted.** `bin/check-sync.sh` no longer sources `.env`, no longer clones or fetches `joshtronic/distillery`, and no longer calls `context_refresh`. The gate is back to being read-only over the cache: seeded -> the sourced `worker-contract`, unseeded -> `AGENTS.md` with the loud notice. Seeding stays `install.sh`'s and `tick.sh`'s job. The copy-pasted `ssh_clone_url` / path derivation went with it, so there's nothing left to drift. - **`context_surface`'s exit status is checked.** A seeded cache that can't serve `worker-contract` now prints `x prompt cache is seeded but 'worker-contract' could not be served` and exits 1, instead of validating an empty file. Verified by hand against a fixture cache dir holding only `current/HEAD`. - **The branching is under test.** The selection moved into `lib/worker-doc.sh` (`worker_doc_select`), following the `lib/suite-guard.sh` precedent of putting check-sync's logic in a lib so its failure paths are drivable. `bin/test-worker-doc.sh` covers all three modes: unseeded -> `AGENTS.md` + a label containing "fallback"; seeded -> the destination file holding the sourced body verbatim; seeded-but-unservable -> nonzero with `WORKER_DOC` left empty. ### Answers - **`bin/install.sh` — is the `.env` move safe?** Yes. The gap between the two hunks is `mkdir -p "$UNIT_DIR"`, two `ln -sf` of the unit files, `systemctl --user daemon-reload`, `enable --now agent.timer`, and `list-timers`. `UNIT_DIR` is derived from `$HOME` at the top of the script, the units are symlinked (not templated), and `systemd/agent.service` carries no `EnvironmentFile` — only a hardcoded `Environment="PATH=..."`. There is no `systemctl --user import-environment` anywhere in the script, so the exported `.env` never reached the manager's environment in the first place. Nothing in that gap reads a `.env` variable. - **Net CI effect.** Correct, and worth stating plainly: in the container CI still validates `AGENTS.md`, so the gate that runs on every PR is no stronger than before. What the retarget buys is that `make test` on a seeded host — and any future CI that gets Distillery access — checks the document the worker actually receives instead of one nobody reads. #487 scoped it that way deliberately. - The `mid-cat` comment in `lib/context-source.sh` is reworded to say what actually holds: a reader that ALREADY OPENED the file finishes it; one that resolves `current` and opens afterwards, or reads several surfaces across the swap, can straddle two generations — a stale read, never a partial one. - The column-alignment nit is fixed by dropping the padding after `bin/tick.sh:` rather than trying to pad to the long label. --- The rest of the findings were addressed in the commits on this branch. The reviewer will re-review the new head. <!-- adjudication:dismissed -->
igor added spent time 2026-08-09 07:27:07 +00:00
8 minutes 44 seconds
Author
Collaborator

🤖 Review — COMMENT (automated)

CI for 631de3b3: success

Retargets bin/check-sync.sh's sentinel/helper gate from the in-repo AGENTS.md to the sourced worker-contract (via a new lib/worker-doc.sh), with a loudly-announced AGENTS.md fallback when the prompt cache is unseeded; plus the two #486 nits. Scope matches the rescoped #487, CI is green, and the new bin/test-worker-doc.sh covers all three selection modes (including the "seeded but unservable → nonzero, WORKER_DOC empty" path that round 1 asked for). Nothing here looks broken to me, but there are three things I can't confirm from the diff alone, so I'm leaving this for a human rather than approving.

Can't verify from the diff (please confirm)

  • trap ... EXIT may clobber an existing trap. bin/check-sync.sh:+40 installs trap 'rm -f "$WORKER_DOC_TMP"' EXIT immediately after sourcing lib/suite-guard.sh. If suite-guard.sh registers its own EXIT trap (a "did every bin/test-*.sh actually run" guard is exactly the kind of thing that would), this unconditionally replaces it and silently disables the guard — with no test failure to show for it, since the guard's whole job is to fire at exit. bash has no trap stacking; the fix if so is to chain (trap 'rm -f "$WORKER_DOC_TMP"; <existing>' EXIT) or have suite-guard.sh expose an append helper. I have no working tree, so I can only flag the shape.
  • bin/test-feedback.sh deliverable. Issue #487 deliverable 2 explicitly lists "set AGENT_STATE_DIR to the tmp dir in bin/test-feedback.sh". The description checks that box with "already set … no change needed", which is a checked box with no corresponding diff line. That's honest framing rather than a fabrication, but it is unverifiable from here — a reviewer should eyeball the file once to confirm the deliverable is genuinely already satisfied.
  • CONTEXT_CACHE_DIR override. bin/test-worker-doc.sh exports CONTEXT_CACHE_DIR after sourcing lib/context-source.sh; that only works if the cache root is resolved per-call, not at source time. Green CI on the "seeded cache" case (which can only pass in a container via the override) is decent evidence it does — noting it as an assumption I inferred rather than checked.

Findings

  • bin/check-sync.sh:+41-47 — the fallback is detected by string-matching the path. if [ "$WORKER_DOC" = "AGENTS.md" ] couples the caller to a magic literal that worker-doc.sh is free to change (e.g. to an absolute path); the warning would then silently stop printing while everything still exits 0 — the precise failure mode ("green run mistaken for having checked the real document") the module header says it exists to prevent. Exposing a WORKER_DOC_MODE (sourced / fallback) from worker_doc_select would make the branch structural instead of textual.
  • bin/check-sync.sh:+45-47 — redundant output. In fallback mode both the ! line and the + validating … against: $WORKER_DOC_LABEL line print the same label; the + line alone (or the ! alone) carries it.
  • Comment contract: the rationale block is duplicated. bin/check-sync.sh:+13-20 and lib/worker-doc.sh:+5-13 say substantially the same thing ("since #485/#486 the prompt comes from context_surface worker-contract, not AGENTS.md, so the gate would be checking a copy nobody reads (#487)") in near-identical prose. Both are legitimate why comments individually, but one of them should be a pointer to the other. Non-blocking.
  • bin/check-sync.sh:+37-40 — a broken cache costs you the whole suite. The exit 1 on an unservable surface happens before the bin/test-*.sh runs, so a purely local cache problem yields zero test signal rather than "gate skipped, tests ran". Deliberate fail-fast is defensible; flagging so it's a conscious choice.
  • PR description: the #488 reference is self-referential. The body says the prose deletions "are split out to #488" — but this PR is #488, and Forgejo shares one number sequence between issues and PRs, so that ticket number can't be right. Whoever picks up the follow-up will chase their own tail. Worth correcting in the body (it is author-written here, unlike a generated summary).

Notes

  • The lib/context-source.sh:+210 comment rewrite is a genuine correction and now states something true and narrow (open-fd survives unlink; resolve-then-open across a swap can straddle generations). Good catch to fix rather than delete.
  • The bin/install.sh .env move: the author's round-1 reasoning (nothing in the intervening mkdir/ln -sf/daemon-reload/enable --now reads a .env var; no import-environment; the unit carries no EnvironmentFile) holds against what's visible, and the pre-existing .env-must-exist check stays upstream of both. Dropped.
  • Acknowledged and agreed with the author's own framing: in CI the gate still validates AGENTS.md, so the check that runs on every PR is no stronger than before this change. The value lands only on seeded hosts. Worth the human knowing that before #488 deletes the in-repo copy that CI is currently the sole consumer of — at that point the CI gate has nothing to validate against at all.

Independent review by the harness on claude-opus-5 (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.

### 🤖 Review — `COMMENT` _(automated)_ CI for `631de3b3`: **success** Retargets `bin/check-sync.sh`'s sentinel/helper gate from the in-repo `AGENTS.md` to the sourced `worker-contract` (via a new `lib/worker-doc.sh`), with a loudly-announced `AGENTS.md` fallback when the prompt cache is unseeded; plus the two #486 nits. Scope matches the rescoped #487, CI is green, and the new `bin/test-worker-doc.sh` covers all three selection modes (including the "seeded but unservable → nonzero, `WORKER_DOC` empty" path that round 1 asked for). Nothing here looks broken to me, but there are three things I can't confirm from the diff alone, so I'm leaving this for a human rather than approving. ## Can't verify from the diff (please confirm) - **`trap ... EXIT` may clobber an existing trap.** `bin/check-sync.sh:+40` installs `trap 'rm -f "$WORKER_DOC_TMP"' EXIT` immediately after sourcing `lib/suite-guard.sh`. If `suite-guard.sh` registers its own EXIT trap (a "did every `bin/test-*.sh` actually run" guard is exactly the kind of thing that would), this unconditionally replaces it and silently disables the guard — with no test failure to show for it, since the guard's whole job is to fire at exit. `bash` has no trap stacking; the fix if so is to chain (`trap 'rm -f "$WORKER_DOC_TMP"; <existing>' EXIT`) or have `suite-guard.sh` expose an append helper. I have no working tree, so I can only flag the shape. - **`bin/test-feedback.sh` deliverable.** Issue #487 deliverable 2 explicitly lists "set `AGENT_STATE_DIR` to the tmp dir in `bin/test-feedback.sh`". The description checks that box with "already set … no change needed", which is a checked box with no corresponding diff line. That's honest framing rather than a fabrication, but it is unverifiable from here — a reviewer should eyeball the file once to confirm the deliverable is genuinely already satisfied. - **`CONTEXT_CACHE_DIR` override.** `bin/test-worker-doc.sh` exports `CONTEXT_CACHE_DIR` *after* sourcing `lib/context-source.sh`; that only works if the cache root is resolved per-call, not at source time. Green CI on the "seeded cache" case (which can only pass in a container via the override) is decent evidence it does — noting it as an assumption I inferred rather than checked. ## Findings - **`bin/check-sync.sh:+41-47` — the fallback is detected by string-matching the path.** `if [ "$WORKER_DOC" = "AGENTS.md" ]` couples the caller to a magic literal that `worker-doc.sh` is free to change (e.g. to an absolute path); the warning would then silently stop printing while everything still exits 0 — the precise failure mode ("green run mistaken for having checked the real document") the module header says it exists to prevent. Exposing a `WORKER_DOC_MODE` (`sourced` / `fallback`) from `worker_doc_select` would make the branch structural instead of textual. - **`bin/check-sync.sh:+45-47` — redundant output.** In fallback mode both the `!` line and the `+ validating … against: $WORKER_DOC_LABEL` line print the same label; the `+` line alone (or the `!` alone) carries it. - **Comment contract: the rationale block is duplicated.** `bin/check-sync.sh:+13-20` and `lib/worker-doc.sh:+5-13` say substantially the same thing ("since #485/#486 the prompt comes from `context_surface worker-contract`, not AGENTS.md, so the gate would be checking a copy nobody reads (#487)") in near-identical prose. Both are legitimate *why* comments individually, but one of them should be a pointer to the other. Non-blocking. - **`bin/check-sync.sh:+37-40` — a broken cache costs you the whole suite.** The `exit 1` on an unservable surface happens before the `bin/test-*.sh` runs, so a purely local cache problem yields zero test signal rather than "gate skipped, tests ran". Deliberate fail-fast is defensible; flagging so it's a conscious choice. - **PR description: the `#488` reference is self-referential.** The body says the prose deletions "are split out to #488" — but this PR *is* #488, and Forgejo shares one number sequence between issues and PRs, so that ticket number can't be right. Whoever picks up the follow-up will chase their own tail. Worth correcting in the body (it is author-written here, unlike a generated summary). ## Notes - The `lib/context-source.sh:+210` comment rewrite is a genuine correction and now states something true and narrow (open-fd survives unlink; resolve-then-open across a swap can straddle generations). Good catch to fix rather than delete. - The `bin/install.sh` `.env` move: the author's round-1 reasoning (nothing in the intervening `mkdir`/`ln -sf`/`daemon-reload`/`enable --now` reads a `.env` var; no `import-environment`; the unit carries no `EnvironmentFile`) holds against what's visible, and the pre-existing `.env`-must-exist check stays upstream of both. Dropped. - Acknowledged and agreed with the author's own framing: in CI the gate still validates `AGENTS.md`, so **the check that runs on every PR is no stronger than before this change**. The value lands only on seeded hosts. Worth the human knowing that before #488 deletes the in-repo copy that CI is currently the sole consumer of — at that point the CI gate has nothing to validate against at all. --- <sub>Independent review by the harness on `claude-opus-5` (effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.</sub> <!-- review sha=631de3b3cebe88fbe865c689440060c791f128e3 verdict=COMMENT ci=success -->
igor added spent time 2026-08-09 07:29:37 +00:00
1 minute 37 seconds
Author
Collaborator

Adjudication (Igor/CoS), merging under the overnight grant. All three verify-items closed empirically: (1) lib/suite-guard.sh registers no EXIT trap -- nothing to clobber; (2) bin/test-feedback.sh:21 does export AGENT_STATE_DIR="$TMP" -- the no-change-needed box is genuinely satisfied (round 1's finding was the false positive); (3) _context_cache_root() resolves per-call, so the test override is sound. Round-1 RC fully resolved: no .env sourcing, no network, no cache mutation in the test gate. Merging on green.

Adjudication (Igor/CoS), merging under the overnight grant. All three verify-items closed empirically: (1) `lib/suite-guard.sh` registers no EXIT trap -- nothing to clobber; (2) `bin/test-feedback.sh:21` does `export AGENT_STATE_DIR="$TMP"` -- the no-change-needed box is genuinely satisfied (round 1's finding was the false positive); (3) `_context_cache_root()` resolves per-call, so the test override is sound. Round-1 RC fully resolved: no `.env` sourcing, no network, no cache mutation in the test gate. Merging on green.
igor merged commit c9bd9bbe69 into master 2026-08-09 07:31:34 +00:00
igor deleted branch agent/487-chore-retarget-check-sync-to-the-sourced-worker 2026-08-09 07:31:34 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Total time spent: 11 minutes 45 seconds
igor
11 minutes 45 seconds
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
joshtronic/igor!488
No description provided.