catalog.dependsOn context should resolve inside the container from the fresh clone, not the host cwd #580

Closed
opened 2026-07-03 18:44:14 +00:00 by coilysiren · 2 comments
Owner

Follow-up from ward#573

ward#573 landed read-only catalog.dependsOn auto-context for all roles, but inherited a correctness gap from the advisor design: context resolution reads the host cwd's catalog, not the target repo's. For a warded engineer dispatch the host cwd may not be the target repo, so the auto-mounted deps can come from the wrong repo or be silently absent.

Fix direction

Resolve catalog.dependsOn inside the container, from the fresh clone of the target repo, rather than from the host cwd before launch. That is strictly more correct for every role and removes the advisor-cwd assumption.

Sequencing

Touches the same container context-resolution path as ward#578 (in flight). Dispatch after #578 lands to avoid a collision.

ward#573 (the feature + this flagged gap, commit 3723957), ward#578 (same launch path, in flight).

## Follow-up from ward#573 ward#573 landed read-only `catalog.dependsOn` auto-context for all roles, but inherited a correctness gap from the advisor design: **context resolution reads the *host cwd*'s catalog**, not the target repo's. For a `warded engineer` dispatch the host cwd may not be the target repo, so the auto-mounted deps can come from the wrong repo or be silently absent. ## Fix direction Resolve `catalog.dependsOn` **inside the container, from the fresh clone** of the target repo, rather than from the host cwd before launch. That is strictly more correct for every role and removes the advisor-cwd assumption. ## Sequencing Touches the same container context-resolution path as ward#578 (in flight). **Dispatch after #578 lands** to avoid a collision. ## Related ward#573 (the feature + this flagged gap, commit 3723957), ward#578 (same launch path, in flight).
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-ward-580 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-03T19:23:55Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-ward-580` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-03T19:23:55Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

WARD-OUTCOME: done - catalog.dependsOn context now resolves in-container from the fresh clone, not the host cwd (landed on main as e06d4c0).

Honest retro: this one looked like a tidy one-liner and mostly was, but the load-bearing surprise was discovering the Go container bootstrap port is dormant - GoBootstrap is never set true, so entrypoint.sh (bash) is the LIVE path. Fixing only the Go side would have shipped a no-op. So the real fix had to land in bash too, which meant a way to run the same parse+dedup from a shell. Rather than reimplement fragile YAML parsing in bash, I added a hidden ward container resolve-context <clone> that reuses the exact Go resolver, and had the entrypoint fill WARD_CONTEXT_REPOS from it after cloneTarget. One source of truth, both paths resolve off the clone.

The host side got simpler on the way: dropped upPlan.ContextRepos, the WARD_CONTEXT_REPOS emission, and the now-dead dropExtraRepos. The pre-launch gate can no longer name the set (the host genuinely does not know it pre-clone), so it now says "resolved in-container" - honest, if slightly less informative than the old cwd-derived line that could be wrong anyway.

Confidence is high: build/vet/tests/pre-commit all green, and I exercised resolve-context end-to-end (substrate dep dropped, writable-grant overlap dropped, kept dep printed). The one thing not exercised here is a real container run - the bash resolution is covered by hand-testing the CLI plus reading the flow, not an integration test. Possible follow-up: fold the Go and bash context-clone paths together once the Go bootstrap stops being experimental, so this stays a single codepath rather than two kept in sync.

WARD-OUTCOME: done - catalog.dependsOn context now resolves in-container from the fresh clone, not the host cwd (landed on main as e06d4c0). Honest retro: this one looked like a tidy one-liner and mostly was, but the load-bearing surprise was discovering the Go `container bootstrap` port is dormant - `GoBootstrap` is never set true, so `entrypoint.sh` (bash) is the LIVE path. Fixing only the Go side would have shipped a no-op. So the real fix had to land in bash too, which meant a way to run the same parse+dedup from a shell. Rather than reimplement fragile YAML parsing in bash, I added a hidden `ward container resolve-context <clone>` that reuses the exact Go resolver, and had the entrypoint fill WARD_CONTEXT_REPOS from it after cloneTarget. One source of truth, both paths resolve off the clone. The host side got simpler on the way: dropped upPlan.ContextRepos, the WARD_CONTEXT_REPOS emission, and the now-dead dropExtraRepos. The pre-launch gate can no longer name the set (the host genuinely does not know it pre-clone), so it now says "resolved in-container" - honest, if slightly less informative than the old cwd-derived line that could be wrong anyway. Confidence is high: build/vet/tests/pre-commit all green, and I exercised resolve-context end-to-end (substrate dep dropped, writable-grant overlap dropped, kept dep printed). The one thing not exercised here is a real container run - the bash resolution is covered by hand-testing the CLI plus reading the flow, not an integration test. Possible follow-up: fold the Go and bash context-clone paths together once the Go bootstrap stops being experimental, so this stays a single codepath rather than two kept in sync.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
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
coilyco-flight-deck/ward#580
No description provided.