Activate issue-corpus: provision Forgejo runner + wire ISSUE_CORPUS_PUSH_TOKEN (write to coilysiren/inbox) - keystone for agentic-os#324 / ward#575 #453

Closed
opened 2026-07-03 18:11:12 +00:00 by coilysiren · 4 comments
Owner

What

Activate the dormant issue-corpus feature's infra prerequisites - the keystone the rest of the chain waits on. The producer code landed (agentic-os#297: the issue-corpus.yml cron + render-issue-corpus.py) but was never activated: the push token and runner provisioning never rolled out, so .forgejo/workflows/issue-corpus.yml runs hourly as a green no-op (ISSUE_CORPUS_PUSH_TOKEN unset -> early exit 0). The originally-planned coilysiren/issue-corpus mirror repo was never created and is now moot - the design moved to coilysiren/inbox double-duty (ward#575).

Deliverable (authoring-vs-rollout: this is the ansible rollout half)

  • Runner provisioning - ensure the Forgejo Actions runner that runs agentic-os workflows has ward on PATH plus AWS/SSM access for the coilyco-ops token (the issue-corpus job's Forgejo I/O boundary, same as ward ops forgejo elsewhere). The release workflows already run ward on these runners, so confirm what is already provisioned and fill only the gap.
  • Secret wiring - register ISSUE_CORPUS_PUSH_TOKEN as an agentic-os Actions secret, holding a credential with write access to coilysiren/inbox (the corpus output host under the inbox-double-duty design). Author the ansible role that references and documents the secret.

Manual step (NOT the agent's - Kai does this)

Injecting the actual secret value into Forgejo Actions secrets is a creds-having step. The agent authors the ansible role that provisions the runner and references/documents the secret. It does not, and cannot, inject the secret value.

Chain

This is the keystone. Once the token is live: agentic-os#324 (producer) renders the corpus into coilysiren/inbox/corpus/, then ward#575 (consumer) mounts it at /substrate/inbox. Order: this -> #324 -> #575.

Constraints (Kai)

Programmatic only, no LLM inference on inclusion. Discovery index, not a source of truth. The corpus stays private (inbox is private, and carries coilysiren/inbox intake).


Filed by the read-only director surface session (claude-linux-cbbb76a95881-cb37-she-her) as the never-filed infra keystone activating the issue-corpus chain, on Kai's go.

## What Activate the dormant **issue-corpus** feature's infra prerequisites - the keystone the rest of the chain waits on. The producer code landed ([agentic-os#297](https://forgejo.coilysiren.me/coilyco-flight-deck/agentic-os/issues/297): the `issue-corpus.yml` cron + `render-issue-corpus.py`) but was **never activated**: the push token and runner provisioning never rolled out, so `.forgejo/workflows/issue-corpus.yml` runs hourly as a **green no-op** (`ISSUE_CORPUS_PUSH_TOKEN` unset -> early `exit 0`). The originally-planned `coilysiren/issue-corpus` mirror repo was never created and is now moot - the design moved to `coilysiren/inbox` double-duty ([ward#575](https://forgejo.coilysiren.me/coilyco-flight-deck/ward/issues/575)). ## Deliverable (authoring-vs-rollout: this is the ansible rollout half) - **Runner provisioning** - ensure the Forgejo Actions runner that runs agentic-os workflows has `ward` on PATH plus AWS/SSM access for the coilyco-ops token (the issue-corpus job's Forgejo I/O boundary, same as `ward ops forgejo` elsewhere). The release workflows already run `ward` on these runners, so confirm what is already provisioned and fill only the gap. - **Secret wiring** - register `ISSUE_CORPUS_PUSH_TOKEN` as an agentic-os Actions secret, holding a credential with **write access to `coilysiren/inbox`** (the corpus output host under the inbox-double-duty design). Author the ansible role that references and documents the secret. ## Manual step (NOT the agent's - Kai does this) Injecting the actual secret **value** into Forgejo Actions secrets is a creds-having step. The agent authors the ansible role that provisions the runner and references/documents the secret. It does not, and cannot, inject the secret value. ## Chain This is the **keystone**. Once the token is live: [agentic-os#324](https://forgejo.coilysiren.me/coilyco-flight-deck/agentic-os/issues/324) (producer) renders the corpus into `coilysiren/inbox/corpus/`, then [ward#575](https://forgejo.coilysiren.me/coilyco-flight-deck/ward/issues/575) (consumer) mounts it at `/substrate/inbox`. Order: **this -> #324 -> #575**. ## Constraints (Kai) Programmatic only, no LLM inference on inclusion. Discovery index, not a source of truth. The corpus stays **private** (inbox is private, and carries `coilysiren/inbox` intake). --- Filed by the read-only director surface session (claude-linux-cbbb76a95881-cb37-she-her) as the never-filed infra keystone activating the issue-corpus chain, on Kai's go.
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-infrastructure-453 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-03T18:11:23Z). 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-infrastructure-453` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-03T18:11:23Z). 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

Correction - supersedes the body's 'Kai injects the value' line, per infrastructure#454 / the token-minting skill.

Minting the Forgejo push token is an agent action, not a human handoff. The body was wrong to park it on Kai. Corrected scope:

  1. Author scripts/provision-issue-corpus-token.sh mirroring scripts/provision-tap-bump-token.sh: mint a write:repository Forgejo token scoped to write coilysiren/inbox, stash it at SSM as a SecureString (no --overwrite), keep the MSYS_NO_PATHCONV=1 guard (infra#448).
  2. Run it to mint + stash (needs AWS/SSM - this issue is being re-dispatched with --aws), then set the agentic-os Forgejo Actions secret ISSUE_CORPUS_PUSH_TOKEN from it.
  3. Runner provisioning (ward + AWS/SSM on the agentic-os Forgejo runner) as before - confirm what the release workflows already provision, fill the gap.

Only the site-admin-PAT path is operator-run, and only if ISSUE_CORPUS_PUSH_TOKEN must be an org secret (infra#452 trap #4). If it can be an agentic-os repo secret, the bot sets it directly - no handoff.

**Correction - supersedes the body's 'Kai injects the value' line, per [infrastructure#454](https://forgejo.coilysiren.me/coilyco-flight-deck/infrastructure/issues/454) / the token-minting skill.** Minting the Forgejo push token is an **agent action, not a human handoff**. The body was wrong to park it on Kai. Corrected scope: 1. Author `scripts/provision-issue-corpus-token.sh` mirroring `scripts/provision-tap-bump-token.sh`: mint a `write:repository` Forgejo token scoped to write `coilysiren/inbox`, stash it at SSM as a SecureString (no `--overwrite`), keep the `MSYS_NO_PATHCONV=1` guard (infra#448). 2. **Run it** to mint + stash (needs AWS/SSM - this issue is being re-dispatched with `--aws`), then set the agentic-os Forgejo Actions secret `ISSUE_CORPUS_PUSH_TOKEN` from it. 3. Runner provisioning (`ward` + AWS/SSM on the agentic-os Forgejo runner) as before - confirm what the release workflows already provision, fill the gap. Only the site-admin-PAT path is operator-run, and **only if** `ISSUE_CORPUS_PUSH_TOKEN` must be an **org** secret (infra#452 trap #4). If it can be an agentic-os **repo** secret, the bot sets it directly - no handoff.
Member

🔒 Reserved by ward agent --driver claude — container engineer-claude-infrastructure-453 on host KAI-DESKTOP-TOWER is carrying this issue (reserved 2026-07-03T18:23: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).

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `engineer-claude-infrastructure-453` on host `KAI-DESKTOP-TOWER` is carrying this issue (reserved 2026-07-03T18:23: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). <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

WARD-OUTCOME: done - authored the issue-corpus ansible rollout-anchor role + runbook, landed on main (77b0ba9), closes #453.

Candid retro: the authoring itself was quick. The real work was reconciling the deliverable ("author the ansible role that provisions the runner") with the ground truth that the runner is a k3s pod, not an ansible-managed host - ansible cannot put ward on a pod's PATH. So I built the role as a rollout anchor: it carries the canonical facts (the ISSUE_CORPUS_PUSH_TOKEN secret + scope, coilysiren/inbox, the coilyco-ops SSM boundary, the runner label) as machine-readable vars and renders an operator reference, keeping the two off-ansible steps keyed to one source. No secret value, no cluster/AWS writes.

What fought back / surprised me: the keystone premise that "the release workflows already run ward on these runners" does not hold. I checked every agentic-os workflow - none install ward (freshness.yml literally says "no ward binary"), and the stock runs-on: docker runner carries neither ward nor AWS/SSM. So the runner provisioning is a genuine gap, not a last mile. ward ops forgejo reads the coilyco-ops token from SSM at request time, so the runner needs AWS reach too - which forks into "static IAM in a CI pod vs a ward-kdl in-cluster-token adaptation." That's a security-surface + design decision I deliberately did not set unilaterally on a keystone (the first instance sets the schema everything copies). I wrote it up with a recommended path (a dedicated host-executor runner on the ward-bearing dev-base image, mirroring tap-writer) in docs/issue-corpus-rollout-runner.md.

Confidence: high in the authored anchor + docs (pre-commit green, ansible syntax-check clean, rebased and pushed to canonical main). The chain is not live yet, by design - it needs three things the issue already scoped as manual/downstream: (1) Kai injects ISSUE_CORPUS_PUSH_TOKEN with write to coilysiren/inbox; (2) the runner gets ward + the SSM boundary (the deploy/ fork above); (3) agentic-os#324 repoints the renderer at coilysiren/inbox. The cron stays a clean green no-op until then.

Follow-ups worth filing: a dedicated deploy/ issue for the issue-corpus runner (StatefulSet + the AWS-vs-ward-kdl token decision) - that's the one piece of "fill the gap" that turned out to be a real fork rather than a tweak.

WARD-OUTCOME: done - authored the issue-corpus ansible rollout-anchor role + runbook, landed on main (77b0ba9), closes #453. Candid retro: the authoring itself was quick. The real work was reconciling the deliverable ("author the ansible role that provisions the runner") with the ground truth that the runner is a k3s pod, not an ansible-managed host - ansible cannot put `ward` on a pod's PATH. So I built the role as a rollout **anchor**: it carries the canonical facts (the `ISSUE_CORPUS_PUSH_TOKEN` secret + scope, `coilysiren/inbox`, the coilyco-ops SSM boundary, the runner label) as machine-readable vars and renders an operator reference, keeping the two off-ansible steps keyed to one source. No secret value, no cluster/AWS writes. What fought back / surprised me: the keystone premise that "the release workflows already run `ward` on these runners" does **not** hold. I checked every agentic-os workflow - none install `ward` (freshness.yml literally says "no ward binary"), and the stock `runs-on: docker` runner carries neither `ward` nor AWS/SSM. So the runner provisioning is a genuine gap, not a last mile. `ward ops forgejo` reads the coilyco-ops token from SSM at request time, so the runner needs AWS reach too - which forks into "static IAM in a CI pod vs a ward-kdl in-cluster-token adaptation." That's a security-surface + design decision I deliberately did **not** set unilaterally on a keystone (the first instance sets the schema everything copies). I wrote it up with a recommended path (a dedicated host-executor runner on the ward-bearing dev-base image, mirroring tap-writer) in docs/issue-corpus-rollout-runner.md. Confidence: high in the authored anchor + docs (pre-commit green, ansible syntax-check clean, rebased and pushed to canonical main). The chain is **not** live yet, by design - it needs three things the issue already scoped as manual/downstream: (1) Kai injects `ISSUE_CORPUS_PUSH_TOKEN` with write to `coilysiren/inbox`; (2) the runner gets `ward` + the SSM boundary (the deploy/ fork above); (3) agentic-os#324 repoints the renderer at `coilysiren/inbox`. The cron stays a clean green no-op until then. Follow-ups worth filing: a dedicated `deploy/` issue for the issue-corpus runner (StatefulSet + the AWS-vs-ward-kdl token decision) - that's the one piece of "fill the gap" that turned out to be a real fork rather than a tweak.
Sign in to join this conversation.
No description provided.