Epic: a third bot leaves no trace in this repository, so bot configuration moves to deploy #836

Open
opened 2026-08-15 20:12:44 +00:00 by coilyco-ops · 2 comments
Member

Filed at Kai's direction from coilyco-gaming/sirens-echo#826 (comment). Epic. This repository has no epic label, so the title carries it.

The goal, stated as a test

A third bot is being set up. No trace of it may appear in this repository. Not one file, not one line, not its name.

That is the acceptance test for the whole epic, and it is checkable: after this lands, adding a bot touches coilyco-bridge/deploy only, and git grep -i '<new bot name>' in this repository returns nothing forever.

Kai's words:

we need to remove, to the greatest extent reasonable at this time, configure the bots inside of the deploy repo. I'm going to setup a 3rd bot, and I would sincerely prefer that no hint of it ever show up in the bridge/siren-echo repo. At all. Not even its name.

"The bridge/siren-echo repo" means this repository, coilyco-gaming/sirens-echo. Kai confirmed it when asked. Config moves to coilyco-bridge/deploy and nothing constrains how deploy arranges it internally.

"To the greatest extent reasonable at this time" is doing real work in that sentence. Some of what follows is cheap and some is not, so the child issues are ordered by cost and the expensive tail is explicitly optional.

What it costs to add a bot today, measured

The second bot is the evidence. Sirens Deep was added to a repository that already had Sirens Echo, and this is what that cost here:

  • 24 tracked files carry the second bot's name in their filename.
  • 87 tracked files name it in their contents.
  • 30 test files and 17 docs name it.
  • 4 shipped Go files hardcode it.

A third bot on today's layout costs the same again, which is exactly what this epic exists to prevent.

The sharpest example

internal/community/decision.go:75:

const continuingWorkClaimPattern = `(?i)\b(?:the system|the service|this service|sirens echo|sirens deep)\s+...`

Two bot names, compiled into a grounding validator. Adding a third bot means editing a security-adjacent regex in shipped code to add its name, or shipping a bot the continuing-work check does not cover.

The fix is already in the same file, about 140 lines down. selfReferencePattern(identity, aliases) builds the equivalent alternation from the configured identity and its declared aliases, and genericSelfNouns holds only the identity-free forms. One validator derives what the other hardcodes. This epic is largely the work of making the rest of the repository resemble the one that got it right.

Where the bot names are compiled in

  • internal/community/config.go:18 - defaultDefinitionPath = "agent/sirens-echo.yaml", a bot name as the shipped default.
  • internal/community/decision.go:75 - the validator above.
  • cmd/sirens-echo-prompt/main.go:19 - trackedDefinitions, a hardcoded list of every bot.
  • cmd/sirens-echo-prompt/main.go:41 - composedDefinition = "agent/sirens-deep.yaml", one bot singled out by name.
  • cmd/sirens-echo-policy-check/main.go:16 - the same hardcoded list again.

Where the per-bot artifacts are

  • agent/<bot>.yaml - the definition. 17 to 22 lines of identity, audit role, response style, issue tracker, channel, context size, and model budget.
  • agent/rendered/<bot>.prompt.txt - the rendered prompt, 295 lines for Deep, tracked and gated by prompt-check. This is the worst one for "not even its name", because it is the bot's whole prompt including its identity, committed to git.
  • agent/rate-<bot>.yaml, agent/board-<bot>.yaml, agent/evaluation-<bot>.yaml - per-bot packs.
  • evaluations/* - 13 files naming the second bot, run records and probes.
  • assets/<bot>*.png and .svg - 4 brand assets.

Why this is the correct direction, not only Kai's preference

agentic-os/CLAUDE.md already decides it, twice.

Config placement. Config lives at the lowest layer that fully determines it and is never fetched downward. A shipped product does not reach up into a source repository for its own runtime config.

Deployment boundary, aos#778. The three config axes are named there, and one of them is deployment tuning: identity, model, endpoint, attribution, roster defaults. Read the definition file against that list. identity, model_budget, issue_tracker, channel, response_style are deployment tuning by that definition, item for item. They are in the wrong repository today.

The deploy repository has already reached the same conclusion by convention rather than by rule: services/sirens-echo/deploy/ carries sirens-deep-access-policy.yml, sirens-deep-mcp-roster.yml, sirens-deep-namespace.yml, and a dozen more per-bot values files. Deploy is already where a bot is configured. This repository is the leak.

Child issues

Ordered by cost. The first three are the epic's actual promise and the rest is the tail.

1. A definition is supplied by deployment, not tracked here. Remove defaultDefinitionPath's bot name, require the definition to arrive by path or mount, and move agent/sirens-echo.yaml and agent/sirens-deep.yaml into coilyco-bridge/deploy. Blocks everything else, and carries the rollout hazard already documented on #826: deploy pins SIRENS_ECHO_DEFINITION to an in-image path, so image and deploy must change in a known order or Deep crashloops.

2. No validator, tool, or gate may name a bot. Derive the continuing-work alternation from the configured identity the way selfReferencePattern already does. Replace trackedDefinitions and composedDefinition with discovery over whatever definitions are present, so the list is a consequence of the deployment rather than a literal.

3. Rendered prompt snapshots stop being tracked per bot. prompt-check currently gates a committed rendering of each bot's full prompt. Decide what it becomes: a snapshot of a fixture definition that names no real bot, or a check that runs against whatever definition is supplied. This is the one that most directly violates "not even its name".

4. Per-bot packs and evaluation records. Rate packs, board packs, evaluation packs, and the run records under evaluations/. Some of this is provenance that must not move, per the reasoning already recorded in docs/sirens-echo-agent-folders.md, so this needs a real decision rather than a sweep.

5. Tests stop enumerating bots by name. 30 files. #826 already converted two of them to derive from the layout instead of naming files, which is the pattern to follow.

6. Docs and assets. 17 docs and 4 brand assets. Lowest value and highest volume, and plausibly the part that "to the greatest extent reasonable" is meant to exclude.

Acceptance

  • Adding a bot requires no commit to this repository.
  • git grep -i for a bot's name returns nothing outside deliberately retained history and provenance records.
  • No shipped Go file names a bot.
  • ward gate passes with no bot definition present in the tree at all, which is the honest test that the repository no longer assumes one.
  • The existing two bots keep working throughout, with the #826 ordering hazard handled rather than discovered.

Decisions Kai owns

Settled: which repository. This one. The target is coilyco-gaming/sirens-echo, and deploy's internal layout is not in scope. Today services/sirens-echo/deploy/ holds both bots with Deep as a sirens-deep- filename prefix, and that stays deploy's business. Recorded because the original phrasing read three ways and the next reader should not have to re-derive it.

How much of the tail is in scope. Children 4, 5, and 6 are 47 files of docs, tests, and records. They do not block a third bot from existing invisibly. They only decide whether the two existing bots stay named here.

Provenance. Evaluation run records name the definition they were produced against, deliberately. Those are historical records and the pronoun rule for marked history applies to them too. Presumably they stay. Confirm.

  • #826 - the agent-folder restructure, and the SIRENS_ECHO_DEFINITION rollout hazard this epic inherits.
  • aos#778 - the deployment boundary that makes identity a deployment concern.
**Filed at Kai's direction from coilyco-gaming/sirens-echo#826 (comment).** Epic. This repository has no epic label, so the title carries it. ## The goal, stated as a test A third bot is being set up. **No trace of it may appear in this repository. Not one file, not one line, not its name.** That is the acceptance test for the whole epic, and it is checkable: after this lands, adding a bot touches `coilyco-bridge/deploy` only, and `git grep -i '<new bot name>'` in this repository returns nothing forever. Kai's words: > we need to remove, to the greatest extent reasonable at this time, configure the bots inside of the deploy repo. I'm going to setup a 3rd bot, and I would sincerely prefer that no hint of it ever show up in the bridge/siren-echo repo. At all. Not even its name. "The bridge/siren-echo repo" means **this repository**, `coilyco-gaming/sirens-echo`. Kai confirmed it when asked. Config moves to `coilyco-bridge/deploy` and nothing constrains how deploy arranges it internally. "To the greatest extent reasonable at this time" is doing real work in that sentence. Some of what follows is cheap and some is not, so the child issues are ordered by cost and the expensive tail is explicitly optional. ## What it costs to add a bot today, measured The second bot is the evidence. Sirens Deep was added to a repository that already had Sirens Echo, and this is what that cost here: * **24 tracked files** carry the second bot's name in their filename. * **87 tracked files** name it in their contents. * **30 test files** and **17 docs** name it. * **4 shipped Go files** hardcode it. A third bot on today's layout costs the same again, which is exactly what this epic exists to prevent. ## The sharpest example `internal/community/decision.go:75`: ```go const continuingWorkClaimPattern = `(?i)\b(?:the system|the service|this service|sirens echo|sirens deep)\s+...` ``` Two bot names, compiled into a **grounding validator**. Adding a third bot means editing a security-adjacent regex in shipped code to add its name, or shipping a bot the continuing-work check does not cover. The fix is already in the same file, about 140 lines down. `selfReferencePattern(identity, aliases)` builds the equivalent alternation from the **configured** identity and its declared aliases, and `genericSelfNouns` holds only the identity-free forms. One validator derives what the other hardcodes. This epic is largely the work of making the rest of the repository resemble the one that got it right. ## Where the bot names are compiled in * `internal/community/config.go:18` - `defaultDefinitionPath = "agent/sirens-echo.yaml"`, a bot name as the shipped default. * `internal/community/decision.go:75` - the validator above. * `cmd/sirens-echo-prompt/main.go:19` - `trackedDefinitions`, a hardcoded list of every bot. * `cmd/sirens-echo-prompt/main.go:41` - `composedDefinition = "agent/sirens-deep.yaml"`, one bot singled out by name. * `cmd/sirens-echo-policy-check/main.go:16` - the same hardcoded list again. ## Where the per-bot artifacts are * `agent/<bot>.yaml` - the definition. 17 to 22 lines of identity, audit role, response style, issue tracker, channel, context size, and model budget. * `agent/rendered/<bot>.prompt.txt` - the **rendered prompt**, 295 lines for Deep, tracked and gated by `prompt-check`. This is the worst one for "not even its name", because it is the bot's whole prompt including its identity, committed to git. * `agent/rate-<bot>.yaml`, `agent/board-<bot>.yaml`, `agent/evaluation-<bot>.yaml` - per-bot packs. * `evaluations/*` - 13 files naming the second bot, run records and probes. * `assets/<bot>*.png` and `.svg` - 4 brand assets. ## Why this is the correct direction, not only Kai's preference `agentic-os/CLAUDE.md` already decides it, twice. **Config placement.** Config lives at the lowest layer that fully determines it and is never fetched downward. A shipped product does not reach up into a source repository for its own runtime config. **Deployment boundary, aos#778.** The three config axes are named there, and one of them is **deployment tuning: identity, model, endpoint, attribution, roster defaults**. Read the definition file against that list. `identity`, `model_budget`, `issue_tracker`, `channel`, `response_style` are deployment tuning by that definition, item for item. They are in the wrong repository today. The deploy repository has already reached the same conclusion by convention rather than by rule: `services/sirens-echo/deploy/` carries `sirens-deep-access-policy.yml`, `sirens-deep-mcp-roster.yml`, `sirens-deep-namespace.yml`, and a dozen more per-bot values files. Deploy is already where a bot is configured. This repository is the leak. ## Child issues Ordered by cost. The first three are the epic's actual promise and the rest is the tail. **1. A definition is supplied by deployment, not tracked here.** Remove `defaultDefinitionPath`'s bot name, require the definition to arrive by path or mount, and move `agent/sirens-echo.yaml` and `agent/sirens-deep.yaml` into `coilyco-bridge/deploy`. Blocks everything else, and carries the rollout hazard already documented on #826: deploy pins `SIRENS_ECHO_DEFINITION` to an in-image path, so image and deploy must change in a known order or Deep crashloops. **2. No validator, tool, or gate may name a bot.** Derive the continuing-work alternation from the configured identity the way `selfReferencePattern` already does. Replace `trackedDefinitions` and `composedDefinition` with discovery over whatever definitions are present, so the list is a consequence of the deployment rather than a literal. **3. Rendered prompt snapshots stop being tracked per bot.** `prompt-check` currently gates a committed rendering of each bot's full prompt. Decide what it becomes: a snapshot of a fixture definition that names no real bot, or a check that runs against whatever definition is supplied. This is the one that most directly violates "not even its name". **4. Per-bot packs and evaluation records.** Rate packs, board packs, evaluation packs, and the run records under `evaluations/`. Some of this is provenance that must not move, per the reasoning already recorded in `docs/sirens-echo-agent-folders.md`, so this needs a real decision rather than a sweep. **5. Tests stop enumerating bots by name.** 30 files. #826 already converted two of them to derive from the layout instead of naming files, which is the pattern to follow. **6. Docs and assets.** 17 docs and 4 brand assets. Lowest value and highest volume, and plausibly the part that "to the greatest extent reasonable" is meant to exclude. ## Acceptance * Adding a bot requires no commit to this repository. * `git grep -i` for a bot's name returns nothing outside deliberately retained history and provenance records. * No shipped Go file names a bot. * `ward gate` passes with no bot definition present in the tree at all, which is the honest test that the repository no longer assumes one. * The existing two bots keep working throughout, with the #826 ordering hazard handled rather than discovered. ## Decisions Kai owns **Settled: which repository.** This one. The target is `coilyco-gaming/sirens-echo`, and deploy's internal layout is not in scope. Today `services/sirens-echo/deploy/` holds both bots with Deep as a `sirens-deep-` filename prefix, and that stays deploy's business. Recorded because the original phrasing read three ways and the next reader should not have to re-derive it. **How much of the tail is in scope.** Children 4, 5, and 6 are 47 files of docs, tests, and records. They do not block a third bot from existing invisibly. They only decide whether the two existing bots stay named here. **Provenance.** Evaluation run records name the definition they were produced against, deliberately. Those are historical records and the pronoun rule for marked history applies to them too. Presumably they stay. Confirm. ## Related * #826 - the agent-folder restructure, and the `SIRENS_ECHO_DEFINITION` rollout hazard this epic inherits. * aos#778 - the deployment boundary that makes identity a deployment concern.
Author
Member

Child 4 has a decision, in #847. Lucia (AI Engineer seat), 2026-08-15.

This epic recorded that per-bot packs and evaluation records "needs a real decision rather than a sweep". docs/sirens-echo-eval-board.md in #847 is that decision:

  • The evaluation layer goes bot-neutral. No case, boundary, or baseline names a bot. The board is derived from a boundaries declaration rather than from per-bot packs, so the Echo and Deep axes collapse entirely at this layer.
  • Existing run records under evaluations/ stay exactly as they are. They name the definition they were produced against deliberately, which matches this epic's own note that they are historical provenance. The answer to the "Presumably they stay. Confirm." line is yes.

There is a second, independent reason the layer has to be neutral, and it is worth recording here because it is not an epic-836 argument. Counted from source, this repository carries tens of boundaries: 13 content classes, 9 reply validators, and prose clauses across five policy skill roots. Paired for scoring, that is 60 to 90 cases, which is about 40 minutes of human grading. Keeping the bot dimension multiplies that past what a human can grade. So neutrality here is a feasibility constraint as well as your acceptance test.

Tracked by #846. Nothing in #847 is built, so this closes no child.

**Child 4 has a decision, in #847.** Lucia (AI Engineer seat), 2026-08-15. This epic recorded that per-bot packs and evaluation records "needs a real decision rather than a sweep". `docs/sirens-echo-eval-board.md` in #847 is that decision: * **The evaluation layer goes bot-neutral.** No case, boundary, or baseline names a bot. The board is derived from a boundaries declaration rather than from per-bot packs, so the Echo and Deep axes collapse entirely at this layer. * **Existing run records under `evaluations/` stay exactly as they are.** They name the definition they were produced against deliberately, which matches this epic's own note that they are historical provenance. The answer to the "Presumably they stay. Confirm." line is yes. There is a second, independent reason the layer has to be neutral, and it is worth recording here because it is not an epic-836 argument. Counted from source, this repository carries tens of boundaries: 13 content classes, 9 reply validators, and prose clauses across five policy skill roots. Paired for scoring, that is 60 to 90 cases, which is about 40 minutes of human grading. **Keeping the bot dimension multiplies that past what a human can grade.** So neutrality here is a feasibility constraint as well as your acceptance test. Tracked by #846. Nothing in #847 is built, so this closes no child.
Author
Member

The command-surface half of child 4 landed in #853. Lucia (AI Engineer seat), 2026-08-15.

Relevant to this epic in two ways.

Bot names. eval/boundaries.yaml names no bot. It is the first eval-layer artifact that is neutral by construction rather than by discipline, and it is what the per-bot rate packs retire into, boundary by boundary.

A new pin, worth recording here. .ward/ward.yaml could not be deleted when the 30 dev verbs moved to a justfile. check_catalog_block.py pins that exact path and catalog-trifecta requires README, AGENTS, and FEATURES to each link it. Both are authored in agentic-os, so this repo cannot fix them. Filed as agentic-os#1081.

That does not block this epic's acceptance test, since .ward/ward.yaml names no bot. Recording it because it is the same class of coupling the epic exists to remove, pointed at a different file.

Run records under evaluations/ were left alone, keeping their ward exec wording, per this epic's note that they are historical provenance.

**The command-surface half of child 4 landed in #853.** Lucia (AI Engineer seat), 2026-08-15. Relevant to this epic in two ways. **Bot names.** `eval/boundaries.yaml` names no bot. It is the first eval-layer artifact that is neutral by construction rather than by discipline, and it is what the per-bot rate packs retire into, boundary by boundary. **A new pin, worth recording here.** `.ward/ward.yaml` could not be deleted when the 30 dev verbs moved to a justfile. `check_catalog_block.py` pins that exact path and `catalog-trifecta` requires README, AGENTS, and FEATURES to each link it. Both are authored in agentic-os, so this repo cannot fix them. Filed as agentic-os#1081. That does not block this epic's acceptance test, since `.ward/ward.yaml` names no bot. Recording it because it is the same class of coupling the epic exists to remove, pointed at a different file. **Run records under `evaluations/` were left alone**, keeping their `ward exec` wording, per this epic's note that they are historical provenance.
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-gaming/sirens-echo#836
No description provided.