Validate the unselected exemption list, and refresh the umbra pin #1388

Merged
coilyco-ops merged 10 commits from aos/claude/ee98 into main 2026-08-29 08:42:28 +00:00
Owner

Two milestone-33 items. Both verified, and the second is honest about what it does not do.

#1206: an exemption could outlive its reason

[tool.agentic-os.check-composed-skills] unselected was consulted and never checked, so a pattern kept exempting whatever it named after the reason went away. Two drifts:

  • its source is deleted and the pattern lingers
  • a role later selects its source, so the exemption is wrong and still active. Remove that selector afterwards and the gate stays silent, because the stale exemption still covers the source

The second is the one that matters: the escape hatch becomes a hole that opens later, with nothing announcing it. Exactly this milestone's shape.

One rule closes both. Every unselected pattern must cover at least one source no role selects; a pattern matching nothing, or matching only sources a role already claims, exempts nothing and is reported.

Three tests including the control, because a pattern covering a genuinely unselected source is the whole point of the hatch and must stay silent. This repo passes unchanged, so nothing here was leaning on a stale entry.

Umbra pin, v0.175.0 to v0.184.0

Verified by rebuilding aosguard and exercising it: a guarded denial still refuses, a gated read still resolves, and the {username} clause from #1387 still binds.

It does not deliver #1366, and I nearly claimed it did. The codegen change for that issue is in v0.183.0 and v0.184.0, but the generated main.go is rendered by the installed specgen binary, which embeds its own copy of the template:

specgen version v0.180.0 (umbra ref v0.180.0)

So --umbra-ref pins what the generated code imports, not the template that generates it. String-searching the rebuilt binary confirms it: umbra@v0.184.0 present, the new handler absent. #1366 stays open pending a specgen release past v0.184.0.

I found that by running the reported failing command against the rebuilt binary rather than trusting the render. That is the second time tonight end-to-end verification caught a fix that looked landed and was not, which is the argument for the milestone rather than an aside.

Two milestone-33 items. Both verified, and the second is honest about what it does not do. ## #1206: an exemption could outlive its reason `[tool.agentic-os.check-composed-skills] unselected` was consulted and never checked, so a pattern kept exempting whatever it named after the reason went away. Two drifts: * its source is deleted and the pattern lingers * a role later selects its source, so the exemption is wrong and still active. Remove that selector afterwards and **the gate stays silent**, because the stale exemption still covers the source The second is the one that matters: the escape hatch becomes a hole that opens later, with nothing announcing it. Exactly this milestone's shape. One rule closes both. Every `unselected` pattern must cover at least one source no role selects; a pattern matching nothing, or matching only sources a role already claims, exempts nothing and is reported. Three tests including the control, because a pattern covering a genuinely unselected source is the whole point of the hatch and must stay silent. This repo passes unchanged, so nothing here was leaning on a stale entry. ## Umbra pin, v0.175.0 to v0.184.0 Verified by rebuilding aosguard and exercising it: a guarded denial still refuses, a gated read still resolves, and the `{username}` clause from `#1387` still binds. **It does not deliver `#1366`, and I nearly claimed it did.** The codegen change for that issue is in v0.183.0 and v0.184.0, but the generated `main.go` is rendered by the installed `specgen` binary, which embeds its own copy of the template: ``` specgen version v0.180.0 (umbra ref v0.180.0) ``` So `--umbra-ref` pins what the generated code imports, not the template that generates it. String-searching the rebuilt binary confirms it: `umbra@v0.184.0` present, the new handler absent. `#1366` stays open pending a specgen release past v0.184.0. I found that by running the reported failing command against the rebuilt binary rather than trusting the render. That is the second time tonight end-to-end verification caught a fix that looked landed and was not, which is the argument for the milestone rather than an aside.
fix(hooks): install the pre-push hook, so pr-guard has somewhere to run
All checks were successful
ci / aos-eval-tests (pull_request) Successful in 9s
ci / aos-cli-tests (pull_request) Successful in 34s
ci / gate (pull_request) Successful in 51s
614ecbbc4f
The rollout installed pre-commit, commit-msg, and prepare-commit-msg and
stopped. pr-guard is `stages: [pre-push]`, so on every consumer it was a
configured hook with no git hook to fire it. Measured before the fix: 5 of 15
merge-remote-main repos had a pre-push hook at all, and each of those got it
from someone running `just pre-commit-install` by hand.

That is the failure class in agentic-os#1382: a check that does not run reads
exactly like a check that passed. It also made agentic-os#1383 partly moot
while it stood, because a guard corrected across thirteen repos still had no
hook to execute in on eight of them.

Adding pre-push to the install list closes it for every resident checkout on
the next rollout. A fresh clone is the other half and is git's `init.templateDir`,
which is an ansible rollout rather than this script's business.

Verified: deleting .git/hooks/pre-push from a consumer and re-running the
script restores it, and a template-seeded fresh clone refuses both a violating
commit and a guarded push to main.

Refs coilyco-flight-deck/agentic-os#1382

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>
Agent-Role: platform
fix(agents): cut duplicated doctrine and lower the cap that was raised twice in two days
All checks were successful
ci / aos-eval-tests (pull_request) Successful in 9s
ci / aos-cli-tests (pull_request) Successful in 33s
ci / gate (pull_request) Successful in 53s
a471c21948
AGENTS.md was at 34,485 of 34,600 chars and 247 of 247 lines. The cap is meant
to be back-pressure, and it had become headroom: 32,500 on 2026-08-25, 33,600 on
2026-08-28 in a commit whose own subject says "and the cap raise they need", then
34,600 today. Two raises, 2,100 chars, in two days. The file is loaded in full
into every agent session, so that cost is paid continuously.

Cut 1,146 chars and 7 lines, all of it text stated twice rather than prose worth
keeping:

* the four-lane list in `## Release` re-defined lanes the generated git-workflow
  block already defines. Release now points at the block instead of restating it,
  and the `--no-verify` never was in both places.
* `A pushed branch owes its pull request` restated the block's "ALWAYS open the
  pull request in the same turn" and its litter framing almost verbatim. It keeps
  only the two cases the block does not cover: a blocked merge on a main-landing
  lane, and what to do when the agent cannot open the PR itself.
* `Native checkpoints must be remote` restated the block's commit-and-push rule
  before extending it. It now names the extension, undurable work product, and
  the checkpoint definition, without re-deriving the push.

Caps drop to 240 / 33,339, exactly the new size, so the next entry displaces one
rather than extending the file. That is what the note above them already asked
for.

Not cut: `Front-load the context you know you need` is the largest section at
3,909 chars and is nine distinct rules rather than restatement. Its closing
"grants no new authority" clause reads defensive, but it is what stops the rule
being read as licence to reach past a role boundary, so removing it is a
judgement about doctrine rather than a duplication cut.

Refs coilyco-flight-deck/agentic-os#1303

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>
Agent-Role: platform
merge: bring main into the AGENTS.md reduction branch
All checks were successful
ci / aos-eval-tests (pull_request) Successful in 9s
ci / aos-cli-tests (pull_request) Successful in 38s
ci / gate (pull_request) Successful in 1m4s
be34c762b3
fix(aosguard): gate user-repo list, whose swagger parameter is {username}
All checks were successful
ci / aos-eval-tests (pull_request) Successful in 8s
ci / aos-cli-tests (pull_request) Successful in 30s
ci / gate (pull_request) Successful in 51s
a73566d005
The Forgejo guardfile claimed "every leaf whose path carries {owner} must name
a coily* owner" and carried clauses for `owner` and `org`. `user-repo list`
resolves to GET /users/{username}/repos, so neither clause reached it and the
gate the file described did not exist for that leaf.

Confirmed against the built binary before and after, with a control:

    before  user-repo list torvalds --dry-run  -> built the request
    after   user-repo list torvalds --dry-run  -> refused, restrict username
    after   user-repo list coilysiren          -> still builds the request

The pruned spec has exactly three owner-shaped parameters, `owner` (34 paths),
`org` (5), and `username` (1). All three now carry a clause, so the gate is
complete rather than one spelling closer. Every other parameter in the spec is
a sub-resource inside an already-gated owner.

Low impact on its own: a read-only repository list, bounded independently by
what the coilyco-ops token can see. The reason to fix it is that the file
asserted a boundary it did not hold, which is this milestone's whole shape.

Refs coilyco-flight-deck/agentic-os#1378

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>
Agent-Role: platform
`unselected` was consulted and never checked. A pattern kept exempting whatever
it named long after the reason went away, in two directions:

* its source is deleted, and the pattern lingers forever
* a role later selects its source, so the exemption is wrong and still active.
  Remove that selector afterwards and the gate stays silent, because the stale
  exemption still covers the source.

The second is the one that matters. It turns the escape hatch into a hole that
opens later, with nothing announcing it.

One rule closes both: every `unselected` pattern must cover at least one source
that no role selects. A pattern matching nothing, or matching only sources a
role already claims, exempts nothing and is reported.

Three tests, including the control. A pattern covering a genuinely unselected
source is the whole point of the hatch and stays silent.

This repo passes the hook unchanged, so nothing here was relying on a stale
entry. Consumer repos carrying one will see it on the next pin bump, which is
the intended effect rather than a surprise.

Refs coilyco-flight-deck/agentic-os#1206

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>
Agent-Role: platform
chore(aosguard): refresh the umbra pin to v0.184.0
Some checks failed
ci / gate (pull_request) Failing after 29s
ci / aos-cli-tests (pull_request) Successful in 34s
ci / aos-eval-tests (pull_request) Failing after 1m0s
9cad464f29
v0.175.0 to v0.184.0, verified by rebuilding and exercising the binary: a
guarded denial still refuses (`repo delete torvalds linux`), a gated read still
resolves (`user-repo list coilysiren`), and the {username} clause from a73566d0
still binds.

This carries the codegen change for #1366 into the pinned module but does NOT
deliver it. The generated main.go is rendered by the installed `specgen` binary,
which embeds its own copy of the template:

    specgen version v0.180.0 (umbra ref v0.180.0)

So `--umbra-ref` pins what the generated code imports, not the template that
generates it. Confirmed by string-searching the rebuilt binary: it carries
umbra@v0.184.0 and none of the new handler. #1366 stays open until specgen is
released past v0.184.0 and installed.

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>
Agent-Role: platform
fix(dev-base): pin specgen 0.184.0, which is what actually delivers #1366
Some checks failed
ci / aos-cli-tests (pull_request) Successful in 38s
ci / gate (pull_request) Successful in 56s
ci / aos-eval-tests (pull_request) Failing after 1m1s
dev-base-pr / build (pull_request) Successful in 7m16s
73596d4649
Two things, one cause. The gate downloads specgen at the version pinned by this
ARG and then runs the suite, so bumping the aosguard umbra pin to v0.184.0 in
9cad464f while specgen stayed at 0.175.0 skewed the two and failed `ci / gate`.

The same pin is why #1366 looked shipped and was not. `codegen.Render` lives in
umbra, but the specgen binary embeds its own compiled copy of the template, so
`--umbra-ref` pins what the generated code imports and never the thing that
generates it. Raising the umbra pin alone could not deliver a codegen change.

Verified end to end before bumping, by fetching specgen v0.184.0 and rebuilding
aosguard with it rather than trusting the release:

    before   ops kubectl --context ser8 get pods
             -> flag provided but not defined: -context
    after    ops kubectl --context ser8 get pods
             -> ... . This is argument placement, not a denied capability: a
                flag for the wrapped tool goes after the verb, not before it

And the control, which is the half that matters, because a handler decorating
every error would also pass the line above:

    ops forgejo repo delete torvalds linux
    -> argument owner="torvalds" is outside the allowed scope   (UNCHANGED)

`scripts/ci/repo-test-gate.sh` and `scripts/aos-release-build.sh` both read this
ARG, so it stays the single pin.

Refs coilyco-flight-deck/agentic-os#1366

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>
Agent-Role: platform
merge: bring main into the branch
Some checks failed
ci / aos-cli-tests (pull_request) Successful in 35s
ci / gate (pull_request) Successful in 55s
ci / aos-eval-tests (pull_request) Failing after 57s
dev-base-pr / build (pull_request) Has been cancelled
58b6730393
merge: bring main into the branch
All checks were successful
ci / aos-cli-tests (pull_request) Successful in 34s
ci / gate (pull_request) Successful in 57s
dev-base-pr / build (pull_request) Successful in 6m2s
8bd97736b0
coilyco-ops deleted branch aos/claude/ee98 2026-08-29 08:42:29 +00:00
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-flight-deck/agentic-os!1388
No description provided.