The engineer lane cannot reach the four aosk tooling skills it wants #964

Closed
opened 2026-08-18 16:45:12 +00:00 by coilyco-ops · 8 comments
Member

Split out of #956 rather than smuggled into it.

What happened

#956's original role "engineer" entry named four skills that live in agentic-os-kai:

  • tooling-repo-baseline
  • tooling-browser-routing
  • tooling-forgejo-issue-counts
  • tooling-triage-cascade

ExpandRoleWithExclusions in internal/community/composepolicy.go reads .agents/composed from each catalogue the caller passes, and an unmatched pattern is a hard error rather than an empty selection. Both Dockerfile:46 and scripts/task.sh role-drift-check pass public agentic-os alone, so all four match nothing and fail the bake. Fail-fast means only the first one is ever reported.

#956 drops them so the lane can ship, and the file header now records the catalogue-reach rule. This issue is the actual want.

What would fix it

Two shapes, and the choice is not obvious:

  • Promote the four into public agentic-os. They are already public-safe, and it keeps the build reading one catalogue. It moves skills out of the repo that owns Kai's scoped context into the repo that owns the generic layer, which cuts against the layer gradient in AGENTS.md.
  • Teach the image build a second catalogue. stage-compose-sources.sh already accepts several, and its own comment says a wider layer passes more than one, so the plumbing exists. It means the Dockerfile clones agentic-os-kai too, which widens what a shipped public image carries.

The second is closer to the design as documented. The first is smaller. Either way role-drift-check and the Dockerfile have to agree, or the check goes green on something the image cannot build.

Not urgent

The lane ships without these. tooling-browser-routing is the one most likely to be missed on camera, since the seat works a site.

Refs #956

Split out of #956 rather than smuggled into it. ## What happened #956's original `role "engineer"` entry named four skills that live in `agentic-os-kai`: * `tooling-repo-baseline` * `tooling-browser-routing` * `tooling-forgejo-issue-counts` * `tooling-triage-cascade` `ExpandRoleWithExclusions` in `internal/community/composepolicy.go` reads `.agents/composed` from each catalogue the caller passes, and an unmatched pattern is a hard error rather than an empty selection. Both `Dockerfile:46` and `scripts/task.sh role-drift-check` pass public `agentic-os` alone, so all four match nothing and fail the bake. Fail-fast means only the first one is ever reported. #956 drops them so the lane can ship, and the file header now records the catalogue-reach rule. This issue is the actual want. ## What would fix it Two shapes, and the choice is not obvious: * **Promote the four into public `agentic-os`.** They are already public-safe, and it keeps the build reading one catalogue. It moves skills out of the repo that owns Kai's scoped context into the repo that owns the generic layer, which cuts against the layer gradient in AGENTS.md. * **Teach the image build a second catalogue.** `stage-compose-sources.sh` already accepts several, and its own comment says a wider layer passes more than one, so the plumbing exists. It means the Dockerfile clones `agentic-os-kai` too, which widens what a shipped public image carries. The second is closer to the design as documented. The first is smaller. Either way `role-drift-check` and the Dockerfile have to agree, or the check goes green on something the image cannot build. ## Not urgent The lane ships without these. `tooling-browser-routing` is the one most likely to be missed on camera, since the seat works a site. Refs #956
Author
Member

Checked both shapes against the source rather than picking the smaller one.

What the plumbing actually says

scripts/stage-compose-sources.sh already accepts several catalogues, so the second shape needs no new mechanism. What it needs is for Dockerfile and scripts/task.sh role-drift-check to pass the same set, which this issue already names as the thing that has to hold either way. That is the real cost: two callers that must not drift, and role-drift-check going green on something the image cannot build is exactly the failure the check exists to prevent.

Why I am not choosing

The two options trade against different rules in AGENTS.md and neither is obviously subordinate.

  • Promoting the four into public agentic-os moves Kai-scoped skills into the generic layer, which cuts against the layer gradient: "umbra and specgen (generic engines, external contributors, no upstream knowledge), then Ward, then aos, then infra".
  • Cloning agentic-os-kai in the image build widens what a shipped public image carries. That is a disclosure decision, and this repository's habit is that widening what ships is a decision someone makes on purpose rather than a side effect of a capability ticket.

The second is closer to the documented design, as this issue says. It is also the one with a safety surface, and I am not going to widen a public image's contents from inside a skills ticket.

A cheaper third option worth naming

If the want is really just tooling-browser-routing, the one this issue says is most likely to be missed on camera, then promoting one public-safe skill is a much smaller decision than either shape and does not commit the build to a second catalogue. Worth asking whether all four are wanted or whether one is.

Marking autonomy/async-consult.

Checked both shapes against the source rather than picking the smaller one. ## What the plumbing actually says `scripts/stage-compose-sources.sh` already accepts several catalogues, so the second shape needs no new mechanism. What it needs is for **`Dockerfile` and `scripts/task.sh role-drift-check` to pass the same set**, which this issue already names as the thing that has to hold either way. That is the real cost: two callers that must not drift, and `role-drift-check` going green on something the image cannot build is exactly the failure the check exists to prevent. ## Why I am not choosing The two options trade against different rules in AGENTS.md and **neither is obviously subordinate**. * Promoting the four into public `agentic-os` moves Kai-scoped skills into the generic layer, which cuts against the layer gradient: "umbra and specgen (generic engines, external contributors, no upstream knowledge), then Ward, then aos, then infra". * Cloning `agentic-os-kai` in the image build **widens what a shipped public image carries**. That is a disclosure decision, and this repository's habit is that widening what ships is a decision someone makes on purpose rather than a side effect of a capability ticket. The second is closer to the documented design, as this issue says. It is also the one with a safety surface, and I am not going to widen a public image's contents from inside a skills ticket. ## A cheaper third option worth naming If the want is really just `tooling-browser-routing`, the one this issue says is most likely to be missed on camera, then **promoting one public-safe skill is a much smaller decision than either shape** and does not commit the build to a second catalogue. Worth asking whether all four are wanted or whether one is. Marking `autonomy/async-consult`.
Author
Member

Decision from Kai, 2026-08-22: promote tooling-browser-routing alone.

Neither of the two shapes this issue offered. The narrow option it names in passing, that tooling-browser-routing is the one most likely to be missed on camera, is the whole want: one public-safe skill promoted into public agentic-os, and the build stays on one catalogue.

What that avoids is the point. It does not move three more Kai-scoped skills into the generic layer, and it does not widen what a shipped public image carries by cloning agentic-os-kai in the Dockerfile. Both of those stay undecided rather than decided by a capability ticket.

The work is in agentic-os, not here. Promoting a skill means moving tooling-browser-routing into that repository's .agents/composed so ExpandRoleWithExclusions finds it against the catalogue both Dockerfile and scripts/task.sh role-drift-check already pass. Then the role "engineer" entry in this repo names it again, and the drift check and the image agree because there is still only one catalogue.

This issue stays open carrying that, since the first half lands in another repository. tooling-repo-baseline, tooling-forgejo-issue-counts, and tooling-triage-cascade are not part of the decision and remain out of reach.

Removing autonomy/async-consult.

**Decision from Kai, 2026-08-22: promote `tooling-browser-routing` alone.** Neither of the two shapes this issue offered. The narrow option it names in passing, that `tooling-browser-routing` is the one most likely to be missed on camera, is the whole want: **one public-safe skill promoted into public `agentic-os`, and the build stays on one catalogue.** What that avoids is the point. It does not move three more Kai-scoped skills into the generic layer, and it does not widen what a shipped public image carries by cloning `agentic-os-kai` in the Dockerfile. Both of those stay undecided rather than decided by a capability ticket. **The work is in `agentic-os`, not here.** Promoting a skill means moving `tooling-browser-routing` into that repository's `.agents/composed` so `ExpandRoleWithExclusions` finds it against the catalogue both `Dockerfile` and `scripts/task.sh role-drift-check` already pass. Then the `role "engineer"` entry in this repo names it again, and the drift check and the image agree because there is still only one catalogue. This issue stays open carrying that, since the first half lands in another repository. `tooling-repo-baseline`, `tooling-forgejo-issue-counts`, and `tooling-triage-cascade` are **not** part of the decision and remain out of reach. Removing `autonomy/async-consult`.
Author
Member

Before moving the file I checked what promoting it would make it the first of, and the answer changes the cost of the decision.

tooling-browser-routing names playwright_local and playwright_k3s seven times, and they are its whole selection order: which surface to try, which is the fallback, which is not isolated, what to do when one fails.

No public composed source in agentic-os names a concrete MCP server. Zero of seventy-one. Measured across every COMPOSED.md in that catalogue. So promoting this file as it stands makes it the first, and playwright_k3s in particular is one deployment's hosted instance rather than anything an external contributor has.

That is the layer gradient from AGENTS.md arriving in a specific form the decision did not have in front of it. Public-safe and generic are not the same property, and this file is the first but not the second. I raised the gradient in the abstract earlier and it turns out to bite here concretely rather than theoretically.

Two ways to take it, and neither is mine to pick, because one changes what a public catalogue may contain and the other changes what the skill says.

  1. Promote it as it stands and accept that a public composed source may name deployment-specific servers. Cheapest, and the precedent then exists for the next one.
  2. Genericise the selection order first, so it routes by surface property, an isolated local browser against a shared hosted one, rather than by instance name, with the concrete names staying in a Kai-scoped source that layers on top. Truer to the gradient and a rewrite of the file's substance rather than a move.

I have moved nothing and both checkouts are untouched. agentic-os and agentic-os-kai are each clean on main with no local work, so this is ready to go either way.

Re-adding autonomy/async-consult for that one question.

**Before moving the file I checked what promoting it would make it the first of, and the answer changes the cost of the decision.** `tooling-browser-routing` names `playwright_local` and `playwright_k3s` **seven times**, and they are its whole selection order: which surface to try, which is the fallback, which is not isolated, what to do when one fails. **No public composed source in `agentic-os` names a concrete MCP server. Zero of seventy-one.** Measured across every `COMPOSED.md` in that catalogue. So promoting this file as it stands makes it the first, and `playwright_k3s` in particular is one deployment's hosted instance rather than anything an external contributor has. That is the layer gradient from AGENTS.md arriving in a specific form the decision did not have in front of it. **Public-safe and generic are not the same property**, and this file is the first but not the second. I raised the gradient in the abstract earlier and it turns out to bite here concretely rather than theoretically. Two ways to take it, and **neither is mine to pick**, because one changes what a public catalogue may contain and the other changes what the skill says. 1. **Promote it as it stands** and accept that a public composed source may name deployment-specific servers. Cheapest, and the precedent then exists for the next one. 2. **Genericise the selection order first**, so it routes by surface property, an isolated local browser against a shared hosted one, rather than by instance name, with the concrete names staying in a Kai-scoped source that layers on top. Truer to the gradient and a rewrite of the file's substance rather than a move. I have moved nothing and both checkouts are untouched. `agentic-os` and `agentic-os-kai` are each clean on `main` with no local work, so this is ready to go either way. Re-adding `autonomy/async-consult` for that one question.
Author
Member

Correction to my own count above: six occurrences, not seven - playwright_local four times and playwright_k3s twice. I read a line count as an occurrence count.

The finding is unchanged and does not depend on the number: those names are the file's whole selection order, and no public composed source in agentic-os names a concrete MCP server, zero of seventy-one. The question stands as written.

Correction to my own count above: **six occurrences, not seven** - `playwright_local` four times and `playwright_k3s` twice. I read a line count as an occurrence count. The finding is unchanged and does not depend on the number: those names are the file's whole selection order, and **no public composed source in `agentic-os` names a concrete MCP server, zero of seventy-one**. The question stands as written.
Author
Member

Building it, with the concern stated rather than used as a reason to stop. I raised the precedent question above and then waited on it, which was the wrong call: the finding is a cost of your decision, not a different decision, and it turns out there is a shape that takes the decision and contains the cost.

What landed

coilyco-flight-deck/agentic-os#1216 publishes tooling-browser-routing into the public catalogue unselected, rather than on that repo's base engineer role.

That is the resolution to the precedent problem. The concrete server names would have been a fleet-wide change if a base role selected them, handing every engineer doctrine about surfaces their deployment may not have. Unselected does not stop a consumer catalogue selecting it, which is exactly what this issue needs, so sirens-echo can reach it while no bundle agentic-os bakes carries it.

It also has a precedent of its own, one entry above it in the same list: tooling-sirens-dowel-* is unselected because "a base-role selector would give them to every engineer". Same reasoning, already accepted.

The remaining two steps

  1. agentic-os#1216 merges. Then 's agent/compose/roles.kdl gets composed-skill "tooling-browser-routing" on the engineer role. It has to be that order, because both the Dockerfile and role-drift-check expand patterns against agentic-os main, so adding the selector first fails the bake.
  2. Remove the copy from agentic-os-kai, so two catalogues do not carry the same name. Checked: no role there selects it, only the file itself and two docs reference it, so that removal is safe once the promotion lands.

Unchanged

tooling-repo-baseline, tooling-forgejo-issue-counts, and tooling-triage-cascade are not part of your decision and stay out of reach.

Removing autonomy/async-consult again, since I am acting on the decision rather than asking about it.

**Building it, with the concern stated rather than used as a reason to stop.** I raised the precedent question above and then waited on it, which was the wrong call: the finding is a cost of your decision, not a different decision, and it turns out there is a shape that takes the decision and contains the cost. ## What landed `coilyco-flight-deck/agentic-os#1216` publishes `tooling-browser-routing` into the public catalogue **unselected**, rather than on that repo's base engineer role. That is the resolution to the precedent problem. The concrete server names would have been a fleet-wide change if a base role selected them, handing every engineer doctrine about surfaces their deployment may not have. **Unselected does not stop a consumer catalogue selecting it**, which is exactly what this issue needs, so sirens-echo can reach it while no bundle `agentic-os` bakes carries it. It also has a precedent of its own, one entry above it in the same list: `tooling-sirens-dowel-*` is unselected because *"a base-role selector would give them to every engineer"*. Same reasoning, already accepted. ## The remaining two steps 1. **agentic-os#1216 merges.** Then 's `agent/compose/roles.kdl` gets `composed-skill "tooling-browser-routing"` on the engineer role. It has to be that order, because both the Dockerfile and `role-drift-check` expand patterns against `agentic-os` main, so adding the selector first fails the bake. 2. **Remove the copy from `agentic-os-kai`**, so two catalogues do not carry the same name. Checked: **no role there selects it**, only the file itself and two docs reference it, so that removal is safe once the promotion lands. ## Unchanged `tooling-repo-baseline`, `tooling-forgejo-issue-counts`, and `tooling-triage-cascade` are not part of your decision and stay out of reach. Removing `autonomy/async-consult` again, since I am acting on the decision rather than asking about it.
Author
Member

Typo fix on my comment above: step 1 should read "Then sirens-echo's agent/compose/roles.kdl gets the selector". A stray backtick pair ate the repository name when I posted it. No change to the substance.

Typo fix on my comment above: step 1 should read "Then **sirens-echo**'s `agent/compose/roles.kdl` gets the selector". A stray backtick pair ate the repository name when I posted it. No change to the substance.
Author
Member

Correcting a claim I made two comments up, before anyone acts on it.

I said "no role there selects it, only the file itself and two docs reference it, so that removal is safe". That is wrong. I grepped for the literal name and missed the glob.

agentic-os-kai/.agents/roles.kdl selects tooling-browser-* in nine roles: engineer, director, qa, ops, design, community, exec, and the rest. That is every role, which is exactly what its own docs/role-skill-coverage-audit.md says:

Every role receives tooling-browser-routing because browser selection and bounded fallback must remain consistent wherever UI inspection can occur.

So removing the copy from agentic-os-kai is not the safe cleanup I called it. If agent-compose passes both catalogues when composing Kai's agents, the glob resolves against the promoted copy and nothing changes. If it does not, nine roles lose the skill, or the pattern matches nothing and hard-fails their bake the way an unmatched pattern does in sirens-echo.

I have not tested which, so I have not removed anything and agentic-os-kai is untouched. Guessing wrong there breaks Kai's own agents across every role, and the removal is tidiness rather than anything #964 needs.

What that leaves as a genuine open question, separate from this issue: two catalogues now carry tooling-browser-routing. Whether that is a collision under agent-compose, or simply the consumer resolving one of them, wants someone who can run a compose over both to answer. The promotion itself does not depend on it.

**Correcting a claim I made two comments up, before anyone acts on it.** I said "no role there selects it, only the file itself and two docs reference it, so that removal is safe". **That is wrong.** I grepped for the literal name and missed the glob. `agentic-os-kai/.agents/roles.kdl` selects `tooling-browser-*` in **nine** roles: engineer, director, qa, ops, design, community, exec, and the rest. That is every role, which is exactly what its own `docs/role-skill-coverage-audit.md` says: > Every role receives `tooling-browser-routing` because browser selection and bounded fallback must remain consistent wherever UI inspection can occur. So removing the copy from `agentic-os-kai` is **not** the safe cleanup I called it. If agent-compose passes both catalogues when composing Kai's agents, the glob resolves against the promoted copy and nothing changes. If it does not, nine roles lose the skill, or the pattern matches nothing and hard-fails their bake the way an unmatched pattern does in sirens-echo. **I have not tested which**, so I have not removed anything and `agentic-os-kai` is untouched. Guessing wrong there breaks Kai's own agents across every role, and the removal is tidiness rather than anything #964 needs. What that leaves as a genuine open question, separate from this issue: **two catalogues now carry `tooling-browser-routing`.** Whether that is a collision under agent-compose, or simply the consumer resolving one of them, wants someone who can run a compose over both to answer. The promotion itself does not depend on it.
Author
Member

The duplicate question is settled, and it settled by breaking something.

I left the two-catalogue collision open here, saying it "wants someone who can run a compose over both to answer". coilyco-bridge/deploy's compose-review job answered it on my own pull request, deploy#781:

skill "tooling-browser-routing" is in both /catalogs/aos and /catalogs/aosk;
one catalogue must own it

A hard error, not a resolvable ambiguity. It would fail any compose passing both catalogues, deploy's CI on every pull request included.

Fixed in agentic-os-kai c12222b: the copy removed, and the two docs that named it updated rather than left pointing at a file that repo no longer has. Its full pre-commit suite is green, and deploy#781 went green on the re-run, which confirms the collision was the failure rather than the change.

Nothing was lost. The nine roles selecting tooling-browser-* keep matching, against the agentic-os copy. That is what publishing it there was for.

Worth recording that I got this wrong in both directions before landing on it. First I called the removal safe on a grep that missed the glob, which would have stripped the skill from nine roles. Then, having corrected that, I under-corrected and left a duplicate that broke CI in a third repository. The middle position was check, then act on what the check says, and the check existed the whole time.

**The duplicate question is settled, and it settled by breaking something.** I left the two-catalogue collision open here, saying it "wants someone who can run a compose over both to answer". **`coilyco-bridge/deploy`'s `compose-review` job answered it on my own pull request**, `deploy#781`: ``` skill "tooling-browser-routing" is in both /catalogs/aos and /catalogs/aosk; one catalogue must own it ``` A hard error, not a resolvable ambiguity. It would fail any compose passing both catalogues, deploy's CI on every pull request included. Fixed in `agentic-os-kai` `c12222b`: the copy removed, and the two docs that named it updated rather than left pointing at a file that repo no longer has. Its full pre-commit suite is green, and `deploy#781` went green on the re-run, which confirms the collision was the failure rather than the change. **Nothing was lost.** The nine roles selecting `tooling-browser-*` keep matching, against the `agentic-os` copy. That is what publishing it there was for. Worth recording that I got this wrong in both directions before landing on it. First I called the removal safe on a grep that missed the glob, which would have stripped the skill from nine roles. Then, having corrected that, I under-corrected and left a duplicate that broke CI in a third repository. **The middle position was check, then act on what the check says**, and the check existed the whole time.
Sign in to join this conversation.
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#964
No description provided.