Gate user-repo list, whose swagger parameter is {username} #1387

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

Closes #1378. First execution item off milestone 33.

The gap

The Forgejo guardfile asserted a boundary it did not hold:

Scope gate: every leaf whose path carries {owner} must name a coily* owner.

It carried clauses for owner and org. user-repo list resolves to GET /users/{username}/repos, so neither reached it.

Verified against the built binary, with a control

before   user-repo list torvalds --dry-run    -> built the request
after    user-repo list torvalds --dry-run    -> refused: restrict username matches [coily*]
after    user-repo list coilysiren --dry-run  -> still builds the request

The control matters: a clause that refuses everything would also make the first line pass.

The gate is now complete, not just one spelling closer

Counted the owner-shaped parameters across the pruned spec rather than fixing the one I tripped over:

owner      34 paths
org         5
username    1

All three now carry a clause. Every other parameter in the spec (repo, index, id, run_id, ref, job_id, workflowfilename, identifier, position) is a sub-resource inside an already-gated owner, so none needs one.

Why it was worth doing

Low impact taken alone: a read-only repository list, bounded independently by what the coilyco-ops token can see. The reason it is in this milestone is the shape rather than the blast radius. The file described a gate, the gate did not exist for one leaf, and nothing said so.

It also names the general rule, which is the part worth keeping: a spec-resolved surface cannot rename its path parameters, so it needs one clause per spelling the vendor chose. The MCP guardfile avoids this entirely by hand-writing {owner} everywhere, which is why the same gate binds there with a single clause. That asymmetry is recorded on #1365, and it is a trap for the vocabulary migration Kai chose there.

Not established

Whether the other wrapped entities have the same shape. aws, kubectl, netlify, signoz, tailscale, and forgejo-admin all declare restrict clauses and none has been checked against its resolved parameter names. That sweep is #1378's own open question and is not in this change.

Closes `#1378`. First execution item off milestone 33. ## The gap The Forgejo guardfile asserted a boundary it did not hold: > Scope gate: every leaf whose path carries {owner} must name a coily* owner. It carried clauses for `owner` and `org`. `user-repo list` resolves to `GET /users/{username}/repos`, so neither reached it. ## Verified against the built binary, with a control ``` before user-repo list torvalds --dry-run -> built the request after user-repo list torvalds --dry-run -> refused: restrict username matches [coily*] after user-repo list coilysiren --dry-run -> still builds the request ``` The control matters: a clause that refuses everything would also make the first line pass. ## The gate is now complete, not just one spelling closer Counted the owner-shaped parameters across the pruned spec rather than fixing the one I tripped over: ``` owner 34 paths org 5 username 1 ``` All three now carry a clause. Every other parameter in the spec (`repo`, `index`, `id`, `run_id`, `ref`, `job_id`, `workflowfilename`, `identifier`, `position`) is a sub-resource inside an already-gated owner, so none needs one. ## Why it was worth doing Low impact taken alone: a read-only repository list, bounded independently by what the coilyco-ops token can see. The reason it is in this milestone is the shape rather than the blast radius. The file described a gate, the gate did not exist for one leaf, and nothing said so. It also names the general rule, which is the part worth keeping: **a spec-resolved surface cannot rename its path parameters**, so it needs one clause per spelling the vendor chose. The MCP guardfile avoids this entirely by hand-writing `{owner}` everywhere, which is why the same gate binds there with a single clause. That asymmetry is recorded on `#1365`, and it is a trap for the vocabulary migration Kai chose there. ## Not established Whether the other wrapped entities have the same shape. `aws`, `kubectl`, `netlify`, `signoz`, `tailscale`, and `forgejo-admin` all declare restrict clauses and none has been checked against its resolved parameter names. That sweep is `#1378`'s own open question and is not in this change.
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
coilyco-ops deleted branch aos/claude/ee98 2026-08-29 08:10:23 +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!1387
No description provided.