Config-driven ward: WARD_CONFIG_REF grammar + the shared syncGitRef TTL resolver (#650-2) #654

Closed
opened 2026-07-08 03:33:07 +00:00 by coilyco-ops · 3 comments
Member

Blocked on #653 (the fs.FS seam).

Breakdown of the config-driven ward epic (#650). Depends on the fs.FS seam (the foundational issue). Delivers the resolver that turns WARD_CONFIG_REF into the local path the seam consumes.

Do

The var grammar (pure parser, table-tested)

WARD_CONFIG_REF = <host>/<owner>/<repo>[@<ref>]//<subpath>

Example: forgejo.coilysiren.me/coilyco-flight-deck/agentic-os@main//.ward

Parse order (self-describing, no forge assumptions):

  • Split once on the first // - left = repo-spec, right = subpath. // cannot appear in a host/owner/repo, so the split is safe.
  • Split left once on @ - repospec (host/owner/repo) + ref. No @ -> ref defaults to the remote default branch.
  • Clone URL = https://<repospec>.git. The ref is passed to git untouched - branch, tag, or sha, ward does not classify it (settled decision 3).
  • The resolved fs.FS is os.DirFS(filepath.Join(checkout, subpath)).

Mirror the shape of parseConfigOverrides (container_compute.go:576) - ~20-line pure function, table-driven test.

The shared TTL-cache resolver

Reuse the substrate warmer, do not add a new fetch path (settled decision 3). Factor the mirror-ensure-and-freshen core of warmSubstrateRepo (container_bootstrap.go:945) into a shared syncGitRef(ctx, spec, ttl) returning a local working-checkout path. Both the substrate warmer and this config-bundle resolver call it. Same properties:

  • TTL gate via substrateMirrorStale (:934) keyed on FETCH_HEAD mtime - a burst of ward invocations inside the TTL window does zero network I/O.
  • flock serialization via r.withFlock so concurrent ward processes do not corrupt the shared mirror.
  • Cache-fallback - on remote update failure, log and proceed on the cached mirror (never brick offline).

Cache location: ~/.cache/ward/config-bundle/<hash-of-ref>/ on host, the ward-gitcache volume in a container. TTL default 600s (match WARD_SUBSTRATE_TTL), overridable by WARD_CONFIG_TTL.

Transport is git shell-out over a bare mirror (settled decision 1 recommendation), reusing git_auth.go - not the forge archive API. Reasoning is in the epic design comment.

Filed from the read-only director surface (she/her).

**Blocked on #653** (the fs.FS seam). Breakdown of the [config-driven ward epic (#650)](https://forgejo.coilysiren.me/coilyco-flight-deck/ward/issues/650). **Depends on the fs.FS seam (the foundational issue).** Delivers the resolver that turns `WARD_CONFIG_REF` into the local path the seam consumes. ## Do ### The var grammar (pure parser, table-tested) `WARD_CONFIG_REF = <host>/<owner>/<repo>[@<ref>]//<subpath>` Example: `forgejo.coilysiren.me/coilyco-flight-deck/agentic-os@main//.ward` Parse order (self-describing, no forge assumptions): * Split once on the first `//` - left = repo-spec, right = subpath. `//` cannot appear in a host/owner/repo, so the split is safe. * Split `left` once on `@` - repospec (`host/owner/repo`) + ref. No `@` -> ref defaults to the remote default branch. * Clone URL = `https://<repospec>.git`. The ref is passed to git untouched - branch, tag, or sha, ward does not classify it (settled decision 3). * The resolved `fs.FS` is `os.DirFS(filepath.Join(checkout, subpath))`. Mirror the shape of `parseConfigOverrides` (`container_compute.go:576`) - ~20-line pure function, table-driven test. ### The shared TTL-cache resolver Reuse the substrate warmer, do not add a new fetch path (settled decision 3). Factor the mirror-ensure-and-freshen core of `warmSubstrateRepo` (`container_bootstrap.go:945`) into a shared `syncGitRef(ctx, spec, ttl)` returning a local working-checkout path. Both the substrate warmer and this config-bundle resolver call it. Same properties: * **TTL gate** via `substrateMirrorStale` (`:934`) keyed on `FETCH_HEAD` mtime - a burst of ward invocations inside the TTL window does zero network I/O. * **`flock` serialization** via `r.withFlock` so concurrent ward processes do not corrupt the shared mirror. * **Cache-fallback** - on `remote update` failure, log and proceed on the cached mirror (never brick offline). Cache location: `~/.cache/ward/config-bundle/<hash-of-ref>/` on host, the `ward-gitcache` volume in a container. TTL default 600s (match `WARD_SUBSTRATE_TTL`), overridable by `WARD_CONFIG_TTL`. Transport is **git shell-out over a bare mirror** (settled decision 1 recommendation), reusing `git_auth.go` - not the forge archive API. Reasoning is in the epic design comment. Filed from the read-only director surface (she/her).
Author
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-ward-654 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-08T04:16:54Z). 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).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/ward#654 · branch issue-654 · driver claude · workflow direct-main
  • Run: engineer-claude-ward-654 · ward v0.439.0 · dispatched 2026-07-08T04:16:54Z
  • Comment thread: 0 included in the pre-flight read, 0 stripped (ward's own automated comments).

Issue body as seeded:

**Blocked on #653** (the fs.FS seam).

Breakdown of the [config-driven ward epic (#650)](https://forgejo.coilysiren.me/coilyco-flight-deck/ward/issues/650). **Depends on the fs.FS seam (the foundational issue).** Delivers the resolver that turns `WARD_CONFIG_REF` into the local path the seam consumes.

## Do

### The var grammar (pure parser, table-tested)

`WARD_CONFIG_REF = <host>/<owner>/<repo>[@<ref>]//<subpath>`

Example: `forgejo.coilysiren.me/coilyco-flight-deck/agentic-os@main//.ward`

Parse order (self-describing, no forge assumptions):

* Split once on the first `//` - left = repo-spec, right = subpath. `//` cannot appear in a host/owner/repo, so the split is safe.
* Split `left` once on `@` - repospec (`host/owner/repo`) + ref. No `@` -> ref defaults to the remote default branch.
* Clone URL = `https://<repospec>.git`. The ref is passed to git untouched - branch, tag, or sha, ward does not classify it (settled decision 3).
* The resolved `fs.FS` is `os.DirFS(filepath.Join(checkout, subpath))`.

Mirror the shape of `parseConfigOverrides` (`container_compute.go:576`) - ~20-line pure function, table-driven test.

### The shared TTL-cache resolver

Reuse the substrate warmer, do not add a new fetch path (settled decision 3). Factor the mirror-ensure-and-freshen core of `warmSubstrateRepo` (`container_bootstrap.go:945`) into a shared `syncGitRef(ctx, spec, ttl)` returning a local working-checkout path. Both the substrate warmer and this config-bundle resolver call it. Same properties:

* **TTL gate** via `substrateMirrorStale` (`:934`) keyed on `FETCH_HEAD` mtime - a burst of ward invocations inside the TTL window does zero network I/O.
* **`flock` serialization** via `r.withFlock` so concurrent ward processes do not corrupt the shared mirror.
* **Cache-fallback** - on `remote update` failure, log and proceed on the cached mirror (never brick offline).

Cache location: `~/.cache/ward/config-bundle/<hash-of-ref>/` on host, the `ward-gitcache` volume in a contai

… (truncated to 2000 chars; full body is on this issue)

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.439.0).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-ward-654` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-08T04:16:54Z). 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). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/ward#654` · branch `issue-654` · driver `claude` · workflow `direct-main` - **Run:** `engineer-claude-ward-654` · ward `v0.439.0` · dispatched `2026-07-08T04:16:54Z` - **Comment thread:** 0 included in the pre-flight read, 0 stripped (ward's own automated comments). **Issue body as seeded:** ``` **Blocked on #653** (the fs.FS seam). Breakdown of the [config-driven ward epic (#650)](https://forgejo.coilysiren.me/coilyco-flight-deck/ward/issues/650). **Depends on the fs.FS seam (the foundational issue).** Delivers the resolver that turns `WARD_CONFIG_REF` into the local path the seam consumes. ## Do ### The var grammar (pure parser, table-tested) `WARD_CONFIG_REF = <host>/<owner>/<repo>[@<ref>]//<subpath>` Example: `forgejo.coilysiren.me/coilyco-flight-deck/agentic-os@main//.ward` Parse order (self-describing, no forge assumptions): * Split once on the first `//` - left = repo-spec, right = subpath. `//` cannot appear in a host/owner/repo, so the split is safe. * Split `left` once on `@` - repospec (`host/owner/repo`) + ref. No `@` -> ref defaults to the remote default branch. * Clone URL = `https://<repospec>.git`. The ref is passed to git untouched - branch, tag, or sha, ward does not classify it (settled decision 3). * The resolved `fs.FS` is `os.DirFS(filepath.Join(checkout, subpath))`. Mirror the shape of `parseConfigOverrides` (`container_compute.go:576`) - ~20-line pure function, table-driven test. ### The shared TTL-cache resolver Reuse the substrate warmer, do not add a new fetch path (settled decision 3). Factor the mirror-ensure-and-freshen core of `warmSubstrateRepo` (`container_bootstrap.go:945`) into a shared `syncGitRef(ctx, spec, ttl)` returning a local working-checkout path. Both the substrate warmer and this config-bundle resolver call it. Same properties: * **TTL gate** via `substrateMirrorStale` (`:934`) keyed on `FETCH_HEAD` mtime - a burst of ward invocations inside the TTL window does zero network I/O. * **`flock` serialization** via `r.withFlock` so concurrent ward processes do not corrupt the shared mirror. * **Cache-fallback** - on `remote update` failure, log and proceed on the cached mirror (never brick offline). Cache location: `~/.cache/ward/config-bundle/<hash-of-ref>/` on host, the `ward-gitcache` volume in a contai ``` … (truncated to 2000 chars; full body is on this issue) Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.439.0). </details> <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

⚠️ Reopened: this run's work did not land on main

An ephemeral ward container (claude mode) dispatched for this issue finished but its work was not merged to main, so the reaper preserved it on a branch before teardown and reopened the issue (its closes #654 never reached main). Recover from the salvage branch below.

  • Repo: coilyco-flight-deck/ward
  • Salvage branch: ward-salvage/ward-9686d657
  • Reason: missing same-repo closing reference
  • Container uptime at reap: 23m (age of the baked Forgejo PAT snapshot; a long-lived container is likelier to carry a rotated token)

Reap diagnostics

--- reap diagnostics ---
ward version:      v0.439.0
version source:    pinned via WARD_VERSION/--ward-version (v0.439.0)
HEAD:              3623e7ccfb18
origin/main:       16c8d082ce79
ancestry:          HEAD is NOT yet on origin/main - residual work remains to land
decision gate:     missing same-repo closing reference
reason:            missing same-repo closing reference
provenance:        present
run-owned landed:  yes
working tree:      1 dirty path(s)
container uptime:  23m (baked Forgejo PAT age proxy)
--- end reap diagnostics ---

Recover

git fetch https://forgejo.coilysiren.me/coilyco-flight-deck/ward.git ward-salvage/ward-9686d657
git checkout -b ward-salvage/ward-9686d657 FETCH_HEAD

Working tree at reap time

?? .ward-run-provenance.json

— Claude (she/her), via ward agent

## ⚠️ Reopened: this run's work did not land on `main` An ephemeral `ward container` (claude mode) dispatched for this issue finished but its work was **not merged to `main`**, so the reaper preserved it on a branch before teardown and reopened the issue (its `closes #654` never reached `main`). Recover from the salvage branch below. - **Repo:** `coilyco-flight-deck/ward` - **Salvage branch:** `ward-salvage/ward-9686d657` - **Reason:** missing same-repo closing reference - **Container uptime at reap:** 23m (age of the baked Forgejo PAT snapshot; a long-lived container is likelier to carry a rotated token) ## Reap diagnostics ``` --- reap diagnostics --- ward version: v0.439.0 version source: pinned via WARD_VERSION/--ward-version (v0.439.0) HEAD: 3623e7ccfb18 origin/main: 16c8d082ce79 ancestry: HEAD is NOT yet on origin/main - residual work remains to land decision gate: missing same-repo closing reference reason: missing same-repo closing reference provenance: present run-owned landed: yes working tree: 1 dirty path(s) container uptime: 23m (baked Forgejo PAT age proxy) --- end reap diagnostics --- ``` ## Recover ```bash git fetch https://forgejo.coilysiren.me/coilyco-flight-deck/ward.git ward-salvage/ward-9686d657 git checkout -b ward-salvage/ward-9686d657 FETCH_HEAD ``` ## Working tree at reap time ``` ?? .ward-run-provenance.json ``` <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Member

Re-closing: this run's work landed on main (closes #654 commit is present). The reopen was the reaper regression captured in #662 - it committed the untracked .ward-run-provenance.json as a trailing residual and salvaged+reopened despite run-owned landed: yes. The salvage branch holds only that provenance-file residual, no lost work. Closing. Filed from the read-only director surface (she/her).

Re-closing: this run's work landed on `main` (`closes #654` commit is present). The reopen was the reaper regression captured in #662 - it committed the untracked `.ward-run-provenance.json` as a trailing residual and salvaged+reopened despite `run-owned landed: yes`. The salvage branch holds only that provenance-file residual, no lost work. Closing. Filed from the read-only director surface (she/her).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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#654
No description provided.