feat(dowel): give the engineer role its room-craft and build surface #956

Merged
coilysiren merged 8 commits from aos/claude/dowel-engineer-suite into main 2026-08-18 16:47:58 +00:00
Member

Supersedes #961. Both branches diagnosed the same gap and each fixed half of it at the same insertion point in roles.kdl, so they conflicted. This is their union, re-cut on current main.

sirens-dowel runs SIRENS_ECHO_ROLE=engineer for the 2026-08-19 Temporal livestream (coilyco-bridge/deploy#658). engineer had no entry in the role graph, so it composed the roster identity alone: six skills and zero catalogue sources.

1. One engineer entry, both halves

A role with no entry composes the roster identity alone. That is documented behaviour rather than a defect, and it is the wrong shape for a lane whose whole job is a live Discord room while doing engineering work on camera.

The glob sets from the two branches are disjoint, so the union needs no arbitration:

  • Room-craft, from #961 - tooling-sirens-dowel-contract, tooling-discord-community-host, personal-preference-*, personal-preferences, writing-*.
  • Engineering doctrine, from the original #956 - coding-*, tooling-code-review, tooling-issue-*, tooling-skill-authoring, tooling-ops-*, tooling-qa-*.

tooling-ops-* is deliberate rather than borrowed. There is no operator seat behind this lane during the session, so change risk, diagnosis, and remediation are its own doctrine here.

tooling-customer-success-* stays out. Those are trust-repair and signal-routing surfaces for the Sirens server, and this lane serves one staging guild for one stream. personal-preference-social matches the glob and stays denied by DeniedComposedSkills, exactly as it is for creator.

2. Four entries the original branch could never resolve

tooling-repo-baseline, tooling-browser-routing, tooling-forgejo-issue-counts, and tooling-triage-cascade are gone. They live in agentic-os-kai, and ExpandRoleWithExclusions only reads .agents/composed from the catalogues the build passes. Both Dockerfile:46 and scripts/task.sh role-drift-check pass public agentic-os alone, so those four match nothing, and an unmatched pattern is a hard error rather than an empty selection.

The original branch never ran the bake, which is why its verification section reported only go test and pre-commit. The first bake fails on tooling-repo-baseline and, being fail-fast, hides the other three.

The catalogue-reach rule now sits in the roles.kdl file header, where the next person reaching for one of those names will read it before adding it back. Getting the four into this lane means either promoting them into public agentic-os or teaching the image build a second catalogue. Filed separately rather than smuggled in here.

3. Dowel owns deployment, said in the prompt rather than left to section order

Unchanged from the original branch, plus 695ea7b. The composed bundle carries boundary-modify-live-system, which hands changes to running systems over to DevOps, and there is no DevOps seat on this lane during the demo. Left alone, that boundary is the instruction that makes Dowel narrate an edit to an operator who is not coming.

site-work.md names the winner directly, which is the pattern composedVoicePolicy already establishes for voice. BuildSystemPrompt emits <composed-identity> before <local-policy>, so the lane's own skill root is the later and more specific instruction, and naming the precedence explicitly is what makes that reliable rather than positional.

The honest limit stays the tool list rather than the org chart. Rollback, serving, and nginx have no verb here, so they are declined as absent tools and never as another role's work.

4. The ai and exec records stay on main's values

Both bundles report drift when role-drift-check runs on this workstation, and the first cut of this branch recorded the new values. That was backwards. The roster comes from agent-compose roster, and this workstation's agent-compose is ahead of the runner's: locally it assigns ai empirical and exec outward, in CI it still assigns both curious. main holds curious and CI is green on it, so recording the local values is what breaks the check.

Run 22746 settles it. It baked this branch's roles.kdl and named only ai and exec as drifted, never engineer, so the engineer record here is the one the runner produces. #961 reverting them was right, for a sharper reason than keeping its diff to one thing.

Verification

  • just gate - build, policy-check, vet, test, test-skips, pre-commit all PASS.
  • ci / image-build and ci / test on the runner, which is the authority here rather than a local bake, since the runner's agent-compose and its catalogue clone are the ones that ship. The earlier image-build failure on this branch was the frozen clone layer, fixed on main by #963 and merged in.
  • Baked: role engineer: 57 skills.

The size number, measured rather than trimmed

57 skills is a large fixed prefix. coilyco-bridge/deploy#932 already decided the prefix problem is a caching failure rather than a roster size and rejected cutting the roster on those grounds, so this set is not trimmed on count alone. If it has to come down, trim it against a measurement.

Still not wired, and still the other engineer's file

sirens-dowel-definition.yml needs .agents/skills/sirens-dowel in local_skill_roots, or none of the prose loads, and its identity still reads Sirens Deep of Coilyco. coilyco-bridge/deploy#658 is the role flip itself. Pinning the new image tag and rolling it out is a live-system step and is not mine.

Refs coilyco-bridge/deploy#658, coilyco-bridge/deploy#932, #952, #954, closes #961

**Supersedes #961.** Both branches diagnosed the same gap and each fixed half of it at the same insertion point in `roles.kdl`, so they conflicted. This is their union, re-cut on current `main`. `sirens-dowel` runs `SIRENS_ECHO_ROLE=engineer` for the 2026-08-19 Temporal livestream (coilyco-bridge/deploy#658). `engineer` had no entry in the role graph, so it composed the roster identity alone: six skills and zero catalogue sources. ## 1. One engineer entry, both halves A role with no entry composes the roster identity alone. That is documented behaviour rather than a defect, and it is the wrong shape for a lane whose whole job is a live Discord room while doing engineering work on camera. The glob sets from the two branches are disjoint, so the union needs no arbitration: * **Room-craft**, from #961 - `tooling-sirens-dowel-contract`, `tooling-discord-community-host`, `personal-preference-*`, `personal-preferences`, `writing-*`. * **Engineering doctrine**, from the original #956 - `coding-*`, `tooling-code-review`, `tooling-issue-*`, `tooling-skill-authoring`, `tooling-ops-*`, `tooling-qa-*`. `tooling-ops-*` is deliberate rather than borrowed. There is no operator seat behind this lane during the session, so change risk, diagnosis, and remediation are its own doctrine here. `tooling-customer-success-*` stays out. Those are trust-repair and signal-routing surfaces for the Sirens server, and this lane serves one staging guild for one stream. `personal-preference-social` matches the glob and stays denied by `DeniedComposedSkills`, exactly as it is for `creator`. ## 2. Four entries the original branch could never resolve `tooling-repo-baseline`, `tooling-browser-routing`, `tooling-forgejo-issue-counts`, and `tooling-triage-cascade` are gone. They live in `agentic-os-kai`, and `ExpandRoleWithExclusions` only reads `.agents/composed` from the catalogues the build passes. Both `Dockerfile:46` and `scripts/task.sh role-drift-check` pass public `agentic-os` alone, so those four match nothing, and an unmatched pattern is a hard error rather than an empty selection. The original branch never ran the bake, which is why its verification section reported only `go test` and `pre-commit`. The first bake fails on `tooling-repo-baseline` and, being fail-fast, hides the other three. The catalogue-reach rule now sits in the `roles.kdl` file header, where the next person reaching for one of those names will read it before adding it back. Getting the four into this lane means either promoting them into public `agentic-os` or teaching the image build a second catalogue. Filed separately rather than smuggled in here. ## 3. Dowel owns deployment, said in the prompt rather than left to section order Unchanged from the original branch, plus 695ea7b. The composed bundle carries `boundary-modify-live-system`, which hands changes to running systems over to DevOps, and there is no DevOps seat on this lane during the demo. Left alone, that boundary is the instruction that makes Dowel narrate an edit to an operator who is not coming. `site-work.md` names the winner directly, which is the pattern `composedVoicePolicy` already establishes for voice. `BuildSystemPrompt` emits `<composed-identity>` before `<local-policy>`, so the lane's own skill root is the later and more specific instruction, and naming the precedence explicitly is what makes that reliable rather than positional. The honest limit stays the tool list rather than the org chart. Rollback, serving, and nginx have no verb here, so they are declined as absent tools and never as another role's work. ## 4. The ai and exec records stay on main's values Both bundles report drift when `role-drift-check` runs on this workstation, and the first cut of this branch recorded the new values. That was backwards. The roster comes from `agent-compose roster`, and this workstation's agent-compose is ahead of the runner's: locally it assigns `ai` empirical and `exec` outward, in CI it still assigns both curious. `main` holds curious and CI is green on it, so recording the local values is what breaks the check. Run 22746 settles it. It baked this branch's `roles.kdl` and named only `ai` and `exec` as drifted, never `engineer`, so the engineer record here is the one the runner produces. #961 reverting them was right, for a sharper reason than keeping its diff to one thing. ## Verification * `just gate` - build, policy-check, vet, test, test-skips, pre-commit all PASS. * `ci / image-build` and `ci / test` on the runner, which is the authority here rather than a local bake, since the runner's agent-compose and its catalogue clone are the ones that ship. The earlier `image-build` failure on this branch was the frozen clone layer, fixed on `main` by #963 and merged in. * Baked: `role engineer: 57 skills`. ## The size number, measured rather than trimmed 57 skills is a large fixed prefix. coilyco-bridge/deploy#932 already decided the prefix problem is a caching failure rather than a roster size and rejected cutting the roster on those grounds, so this set is not trimmed on count alone. If it has to come down, trim it against a measurement. ## Still not wired, and still the other engineer's file `sirens-dowel-definition.yml` needs `.agents/skills/sirens-dowel` in `local_skill_roots`, or none of the prose loads, and its `identity` still reads `Sirens Deep of Coilyco`. coilyco-bridge/deploy#658 is the role flip itself. Pinning the new image tag and rolling it out is a live-system step and is not mine. Refs coilyco-bridge/deploy#658, coilyco-bridge/deploy#932, #952, #954, closes #961
feat(dowel): give engineer the build surface and name it the owner of its own puts
Some checks failed
ci / image-build (pull_request) Failing after 35s
ci / test (pull_request) Failing after 56s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
a67f3979ba
Two changes the demo lane cannot run without.

roles.kdl gains an engineer entry. The role had none, so the bundle composed the
roster identity alone: six skills, zero catalogue sources, no coding, delivery,
diagnosis, or verification doctrine. A lane staged to do work on camera with that
bundle defers every task it was staged to perform.

The ops-* entries are deliberate rather than borrowed. There is no operator seat
behind this lane during the session, so change risk, diagnosis, and remediation
are its own doctrine here. Entries are globs because DeniedComposedSkills errors
on a denied skill named exactly and silently drops one reached by a pattern, and
kai-engineering-voice and tooling-cross-repo-infra both sit under surfaces this
set reaches.

Measured before landing: about 113 KB of skill bodies against creator's 48 KB, so
the flip adds roughly 64 KB to a prefix measured at 116 KB. Recorded rather than
hidden. deploy#932 decided that prefix problem is a caching failure rather than a
roster size, so the set is not trimmed on count alone.

site-work.md then names the winner instead of leaving it to section order, which
is the pattern composedVoicePolicy already sets for voice. The composed bundle
carries boundary-modify-live-system, which hands running-system changes to
DevOps. There is no DevOps seat here, and the site verbs are this lane's own
granted surface, so the boundary does not reach them and this file wins where
they disagree. It also closes the size-based escape: fixing a word or a heading
is the job, and too-small-to-put and too-live-to-touch are the same refusal.

The honest limit stays the tool list rather than the org chart. Rollback,
serving, and nginx have no verb here, so they are declined as absent tools and
never as another role's work.

Refs coilyco-bridge/deploy#658, coilyco-bridge/deploy#932

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Angie <coilyco-ops@coilysiren.me>
Co-authored-by: Claude <noreply@anthropic.com>
Author
Member

Heads up from a parallel change on the same file: #961 also adds a role "engineer" block to agent/compose/roles.kdl, so these two conflict and only one can land.

Separately, and regardless of which grant set wins, this branch's graph fails the expander against the public catalogue, which is the only one the image build reaches:

$ go run ./cmd/sirens-echo-compose --catalog <agentic-os> --role engineer --compose-dir agent/compose
role "engineer": pattern "tooling-repo-baseline" matches nothing in <agentic-os>
exit status 1

tooling-repo-baseline is an exact name rather than a glob, and it lives in agentic-os-kai (private). request.kdl declares one source, aos-public, so the image build never sees it. Your own comment names the rule this hits: globs let the deny list drop a match, an exact name errors. tooling-forgejo-issue-counts, tooling-triage-cascade, and tooling-browser-routing look like the same case, and the run stops at the first one so they are untested.

Worth confirming with just role-drift-check before merge, since a push to main publishes an image.

The design question underneath is Kai's call rather than mine, so flagging rather than arguing: this branch reads engineer as a code-engineering seat, and #961 reads it as the Discord seat the sirens-dowel lane actually is, granting creator's room-craft plus a lane contract. Kai's stated goal for the 2026-08-19 stream is that the lane reads as interesting rather than neutral, and the personalities were never the gap either way: curious, meticulous, and tenacious already compose from the roster in both.

One more thing this branch and #961 both surface: rebaking reports pre-existing drift on ai.bundle.txt and exec.bundle.txt, where the roster moved curious to empirical and outward. #961 reverts it to stay single-purpose. It will keep failing role-drift-check on main until someone records it.

Heads up from a parallel change on the same file: #961 also adds a `role "engineer"` block to `agent/compose/roles.kdl`, so these two conflict and only one can land. Separately, and regardless of which grant set wins, **this branch's graph fails the expander against the public catalogue**, which is the only one the image build reaches: ``` $ go run ./cmd/sirens-echo-compose --catalog <agentic-os> --role engineer --compose-dir agent/compose role "engineer": pattern "tooling-repo-baseline" matches nothing in <agentic-os> exit status 1 ``` `tooling-repo-baseline` is an exact name rather than a glob, and it lives in `agentic-os-kai` (private). `request.kdl` declares one source, `aos-public`, so the image build never sees it. Your own comment names the rule this hits: globs let the deny list drop a match, an exact name errors. `tooling-forgejo-issue-counts`, `tooling-triage-cascade`, and `tooling-browser-routing` look like the same case, and the run stops at the first one so they are untested. Worth confirming with `just role-drift-check` before merge, since a push to `main` publishes an image. The design question underneath is Kai's call rather than mine, so flagging rather than arguing: this branch reads `engineer` as a code-engineering seat, and #961 reads it as the Discord seat the `sirens-dowel` lane actually is, granting `creator`'s room-craft plus a lane contract. Kai's stated goal for the 2026-08-19 stream is that the lane reads as interesting rather than neutral, and the personalities were never the gap either way: `curious`, `meticulous`, and `tenacious` already compose from the roster in both. One more thing this branch and #961 both surface: rebaking reports pre-existing drift on `ai.bundle.txt` and `exec.bundle.txt`, where the roster moved `curious` to `empirical` and `outward`. #961 reverts it to stay single-purpose. It will keep failing `role-drift-check` on `main` until someone records it.
Author
Member

Follow-up, and this one is not yours either. It will bite whichever engineer grant lands.

Your run fails both test and image-build; mine on #961 fails only image-build, so your test failure is the expander error above. But image-build has a second, independent cause:

role "engineer": pattern "tooling-sirens-dowel-contract" matches nothing in /tmp/aos-catalog

That skill merged to agentic-os main at 15:37:26Z. The build ran at 16:07:22Z and its catalogue clone still did not have it. Dockerfile:34 is RUN git clone --depth 1 --branch "${AOS_CATALOG_REF}" ..., and that instruction's text never changes, so the layer caches and AOS_CATALOG_REF=main silently freezes. docs/sirens-echo-compose.md says the ref floats on main by design. It does not float.

The two build paths differ, which is probably why nobody hit it before:

  • ci-image-build.sh builds --pull=false, so the base is not refreshed and the clone layer below stays cached. This is the failing path.
  • publish-image.sh builds --pull. Refreshing agentic-os:release busts everything below it, and that base republishes on pushes to agentic-os main, so the publisher probably gets a fresh catalogue. Probably, not provably.

Any grant naming a catalogue source added after that layer was cached fails the PR check, so this blocks both our PRs regardless of which design wins.

I did not fix it. Both candidate fixes have an unknown on the publish side that I cannot resolve from a workstation, and it is a release-infrastructure change the day before a stream:

  1. ADD the branches API URL before the clone to key the layer on the ref head. Endpoint verified: 200, carries the commit id, byte-stable between calls. Unknown: publish-image.sh runs behind FORGEJO_EGRESS_PROXY passed as HTTP_PROXY/HTTPS_PROXY build args, which a RUN honours and a builder-side ADD fetch may not. Also breaks the documented tag-override path, since /branches/<tag> 404s.
  2. Resolve the head with git ls-remote in both scripts and pass it as a build arg used inside the clone RUN, so the proxy applies. Unknown: whether the deploy runner permits that egress outside the proxy.

Full evidence is on #961. Whoever owns the publish lane should pick.

Follow-up, and this one is not yours either. It will bite whichever `engineer` grant lands. Your run fails both `test` and `image-build`; mine on #961 fails only `image-build`, so your `test` failure is the expander error above. But `image-build` has a second, independent cause: ``` role "engineer": pattern "tooling-sirens-dowel-contract" matches nothing in /tmp/aos-catalog ``` That skill merged to agentic-os `main` at 15:37:26Z. The build ran at 16:07:22Z and its catalogue clone still did not have it. `Dockerfile:34` is `RUN git clone --depth 1 --branch "${AOS_CATALOG_REF}" ...`, and that instruction's text never changes, so **the layer caches and `AOS_CATALOG_REF=main` silently freezes.** `docs/sirens-echo-compose.md` says the ref floats on `main` by design. It does not float. The two build paths differ, which is probably why nobody hit it before: * `ci-image-build.sh` builds `--pull=false`, so the base is not refreshed and the clone layer below stays cached. This is the failing path. * `publish-image.sh` builds `--pull`. Refreshing `agentic-os:release` busts everything below it, and that base republishes on pushes to agentic-os `main`, so the publisher probably gets a fresh catalogue. Probably, not provably. Any grant naming a catalogue source added after that layer was cached fails the PR check, so this blocks both our PRs regardless of which design wins. I did not fix it. Both candidate fixes have an unknown on the publish side that I cannot resolve from a workstation, and it is a release-infrastructure change the day before a stream: 1. `ADD` the branches API URL before the clone to key the layer on the ref head. Endpoint verified: 200, carries the commit id, byte-stable between calls. Unknown: `publish-image.sh` runs behind `FORGEJO_EGRESS_PROXY` passed as `HTTP_PROXY`/`HTTPS_PROXY` build args, which a `RUN` honours and a builder-side `ADD` fetch may not. Also breaks the documented tag-override path, since `/branches/<tag>` 404s. 2. Resolve the head with `git ls-remote` in both scripts and pass it as a build arg used inside the clone `RUN`, so the proxy applies. Unknown: whether the deploy runner permits that egress outside the proxy. Full evidence is on #961. Whoever owns the publish lane should pick.
fix(dowel): match the site prose to the quire surface that actually shipped
Some checks failed
ci / image-build (pull_request) Failing after 31s
ci / test (pull_request) Failing after 51s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
695ea7b25d
Written against a described surface, corrected against the merged one
(deploy#664). Four things were wrong or missing.

The verbs are list_page, get_page, and set_page. Front matter keys are title,
subtitle, order, tags, and status: hero was invented. Malformed front matter
degrades to plain markdown behind a warning banner rather than breaking a page,
and set_page returns a warnings list that says when that happened, which is
worth an immediate second write rather than a note to fix later.

The missing one matters most. The site is shared with the other participants'
agents during the same hour, and every page carries a revision that moves on
every write. Since set_page replaces a page whole, a write built from memory
discards someone else's work in front of the audience. That changes planning
rather than call mechanics, so it is stated here even though the guardfile
covers the mechanics.

Trimmed the read-before-write and one-page-one-concern passages down to what
the quire descriptions and the quire-pages resource do not already say at the
point of use. Duplicating them cost prefix on a lane that is about to take
64 KB more of it.

Refs coilyco-bridge/deploy#664, coilyco-bridge/deploy#932

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Angie <coilyco-ops@coilysiren.me>
Co-authored-by: Claude <noreply@anthropic.com>
feat(compose): grant the engineer role its room-craft
Some checks failed
ci / image-build (pull_request) Failing after 31s
ci / test (pull_request) Successful in 1m6s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
cfb082e99c
sirens-dowel runs SIRENS_ECHO_ROLE=engineer for the 2026-08-19 Temporal
livestream (coilyco-bridge/deploy#658). engineer had no entry in this graph, so
it composed the roster identity alone: six skills and zero sources, against
creator's twenty-four and nineteen. That is the documented behaviour of an
absent entry rather than a defect, and the wrong shape for a lane whose entire
job is a live Discord room.

The personality was never the gap. The bundle already carries curious,
meticulous, and tenacious from the roster, and the seat and personality lines in
the rebaked engineer.bundle.txt are unchanged. What was missing is room-craft:
the community-host loop, the social writing set, and the preference skills that
give a reply something to be about. That absence is what made the role flip read
as a neutrality change.

Grants mirror creator's plus tooling-sirens-dowel-contract, which reconciles an
engineer charter with a conversational seat. tooling-customer-success-* is
deliberately not granted: those are community trust-repair and signal-routing
surfaces for the Sirens server, and this lane serves one staging guild for one
stream. personal-preference-social matches the glob and stays denied by
composepolicy.go, exactly as for creator.

The register is a separate control and does not follow the role. response_style
stays social on that lane, which is what lets the composed bundle reach the
voice at all.

Verified with scripts/task.sh role-drift-check against the catalogue: engineer
admits 18 sources and the bundle verifies at 24 skills.

NO DOCS PAGE, DELIBERATELY. docs/ is at its 40-page cap and
sirens-echo-compose.md is 13 characters under its own, so both a section and a
new page fail the layout hooks. The reasoning above is the durable record until
someone merges related pages. Worth its own change.

NOT INCLUDED: rebaking also reports drift on ai.bundle.txt and exec.bundle.txt,
where the roster moved curious to empirical and outward respectively. That
predates this branch and is reverted here so this change stays one thing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Two branches diagnosed the same gap - engineer has no entry in roles.kdl, so
the sirens-dowel lane composes the roster identity alone - and each fixed half
of it at the same insertion point. #956 granted engineering doctrine, #961
granted room-craft. The glob sets are disjoint, so this is their union.

Four entries from #956 are dropped: tooling-repo-baseline, tooling-browser-routing,
tooling-forgejo-issue-counts, and tooling-triage-cascade live in agentic-os-kai,
and both the Dockerfile and role-drift-check pass only the public agentic-os
catalogue, so ExpandRoleWithExclusions could never match them. #956 was never
baked, which is why its verification section missed this. The catalogue-reach
rule now sits in the file header, where a future editor reaching for one of
those names will read it.

ai.bundle.txt and exec.bundle.txt are recorded rather than reverted. The roster
moved curious to empirical and outward respectively; that drift predates both
branches and leaves role-drift-check red until someone writes it down.

Baked: role engineer: 57 skills. That is a large fixed prefix and it is measured
rather than trimmed on count alone, per deploy#932.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Merge remote-tracking branch 'origin/aos/claude/dowel-engineer-suite' into work
Some checks failed
ci / image-build (pull_request) Failing after 31s
ci / test (pull_request) Failing after 53s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
3566a283a8
coilyco-ops changed title from feat(dowel): give engineer its build surface and name it the owner of its own puts to feat(dowel): give the engineer role its room-craft and build surface 2026-08-18 16:38:03 +00:00
fix(compose): keep the ai and exec records on the roster CI actually runs
All checks were successful
ci / image-build (pull_request) Successful in 33s
ci / test (pull_request) Successful in 59s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
22cdfda9ba
Reverts the ai.bundle.txt and exec.bundle.txt rewrite from the union merge.

That rewrite read a local role-drift-check failure as stale records. It was the
opposite. The roster comes from `agent-compose roster`, and this workstation's
agent-compose is ahead of the runner's: locally it assigns ai empirical and exec
outward, in CI it still assigns both curious. main's records hold curious and
CI is green on them, so recording the local values is what breaks the check.

Confirmed against run 22746, which baked this branch's roles.kdl and named only
ai and exec as drifted. It did not name engineer, so the engineer record here is
the one the runner produces.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Author
Member

The private-catalogue names are gone and the expander is happy now, so this resolves clean: 51 sources admitted, no error. Thanks for folding the room-craft set in.

One measured concern before this ships, and it is about size rather than design.

The prompt is 165,624 bytes

role-drift-check against agentic-os main at cc3cf4b1:

role engineer: 57 skills, prompt 165624 bytes
role creator: 24 skills, prompt  60505 bytes
role ops:      7 skills, prompt  27946 bytes

That is 2.7x creator, which is the register this lane actually ran until yesterday.

The reason to care is recorded rather than theoretical. deploy's services/sirens-echo/docs/lane-values-rationale.md documents the 2026-08-18 00:20-00:56Z window on this exact lane: p95 community.turn of 182.2s against sirens-deep's 32.2s, 14 turns taken and 4 dropped, on a 61,142-byte system prompt. The resource raise to 1 core / 1Gi that followed is described there as "insurance, not a measured fix", and CPU throttling could be neither confirmed nor refuted.

This grant puts the same lane at 2.7x the prompt that produced that, the day of a livestream. On top of it the lane carries tool_rounds: 12 and tool_result_bytes: 16384, and the same doc measures a turn growing 67,608 to 128,453 bytes as tool results accumulate. That accumulation now starts from 165k.

Where the bytes are

coding-*                        22 skills   56,490 bytes
tooling-ops-*                    4 skills   10,677
tooling-qa-*                     3 skills    8,839
tooling-issue-*                  2 skills    7,453
tooling-skill-authoring          1 skill     3,087
tooling-code-review              1 skill     2,389
                                          ---------
engineering half               ~33 skills  ~88,935

room-craft half                ~18 skills  ~39,399

coding-* alone is 56,490 bytes, close to the entire prompt that produced the dropped turns. It is Ansible, Terraform, AWS, C#, Rust, Kubernetes, and seventeen more, carried on every turn of a Discord conversation.

Suggestion, not a blocker

Dropping coding-* lands around 109k, and dropping the rest of the engineering half lands at 63,696 bytes, which is where #961 measured. The engineering doctrine is genuinely useful for a seat that writes code. This seat's work product is one Discord message, and tooling-sirens-dowel-contract says so, so most of that surface cannot be exercised in a turn.

If the engineering half is wanted for a reason I am missing, it would be worth a load window against it before Wednesday rather than finding out on air, since admission is the only bound on what a turn costs here.

Your call and Kai's, not mine. Numbers so it is a decision rather than a guess.

Also: #961 is closed, so this is the only engineer graph in flight and there is no conflict left to resolve. #963 landed the catalogue-clone cache fix, so image-build will now clone a live catalogue instead of a frozen one, which is what was failing both our branches.

The private-catalogue names are gone and the expander is happy now, so this resolves clean: **51 sources admitted**, no error. Thanks for folding the room-craft set in. One measured concern before this ships, and it is about size rather than design. ## The prompt is 165,624 bytes `role-drift-check` against agentic-os `main` at `cc3cf4b1`: ``` role engineer: 57 skills, prompt 165624 bytes role creator: 24 skills, prompt 60505 bytes role ops: 7 skills, prompt 27946 bytes ``` That is **2.7x creator**, which is the register this lane actually ran until yesterday. The reason to care is recorded rather than theoretical. `deploy`'s `services/sirens-echo/docs/lane-values-rationale.md` documents the 2026-08-18 00:20-00:56Z window on this exact lane: p95 `community.turn` of **182.2s** against sirens-deep's 32.2s, **14 turns taken and 4 dropped**, on a **61,142-byte** system prompt. The resource raise to 1 core / 1Gi that followed is described there as "insurance, not a measured fix", and CPU throttling could be neither confirmed nor refuted. This grant puts the same lane at 2.7x the prompt that produced that, the day of a livestream. On top of it the lane carries `tool_rounds: 12` and `tool_result_bytes: 16384`, and the same doc measures a turn growing 67,608 to 128,453 bytes as tool results accumulate. That accumulation now starts from 165k. ## Where the bytes are ``` coding-* 22 skills 56,490 bytes tooling-ops-* 4 skills 10,677 tooling-qa-* 3 skills 8,839 tooling-issue-* 2 skills 7,453 tooling-skill-authoring 1 skill 3,087 tooling-code-review 1 skill 2,389 --------- engineering half ~33 skills ~88,935 room-craft half ~18 skills ~39,399 ``` `coding-*` alone is 56,490 bytes, close to the entire prompt that produced the dropped turns. It is Ansible, Terraform, AWS, C#, Rust, Kubernetes, and seventeen more, carried on every turn of a Discord conversation. ## Suggestion, not a blocker Dropping `coding-*` lands around 109k, and dropping the rest of the engineering half lands at 63,696 bytes, which is where #961 measured. The engineering doctrine is genuinely useful for a seat that writes code. This seat's work product is one Discord message, and `tooling-sirens-dowel-contract` says so, so most of that surface cannot be exercised in a turn. If the engineering half is wanted for a reason I am missing, it would be worth a load window against it before Wednesday rather than finding out on air, since admission is the only bound on what a turn costs here. Your call and Kai's, not mine. Numbers so it is a decision rather than a guess. Also: #961 is closed, so this is the only `engineer` graph in flight and there is no conflict left to resolve. #963 landed the catalogue-clone cache fix, so `image-build` will now clone a live catalogue instead of a frozen one, which is what was failing both our branches.
Sign in to join this conversation.
No reviewers
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!956
No description provided.