feat(access): an offline gate for the access policy #639

Merged
coilyco-ops merged 1 commit from feat/an-offline-access-policy-gate-claude into main 2026-08-13 17:41:31 +00:00
Member

closes #628

sirens-echo-access-check path/to/access-policy.yaml [...]

<path>: ok per file, exit 1 with the reason on stderr for any failure, exit 2 with usage on no arguments. Reads files and does nothing else.

The design is one line

check calls community.LoadAccessPolicy — the same function the agent calls at startup.

A second implementation would be a worse gate than none. It would pass policies the pod rejects and reject policies the pod accepts, and the divergence would surface as a rollout failure that CI had already called green. That is the failure this issue exists to prevent, reintroduced one layer up.

This is also why deploy could not build it: their standing rule is not to reimplement a parser for a format another repository owns, and there was no tool here to call.

What it catches

The bound the issue names:

guild "…" opens to every member: set rate_limit.per_user to a real bound such as 1/60s

And the quieter one — strict decoding. A misspelled ratelimit fails rather than being ignored, which is precisely what a plain YAML parse elsewhere cannot see: the file is valid YAML and the bound it was meant to set is simply absent.

The tests caught me twice

Two fixtures were wrong on the first run and said so:

  • I guessed the schema string; it is coilyco-harness.access.v1
  • I wrote an open allowlist as users: ["all"]; it is the scalar users: all, and the list form fails as a non-snowflake

Both would have shipped a test that passed against a fixture the runtime rejects — a gate proving nothing. Worth stating because I had just claimed the command was thin, and thin is exactly where that mistake hides.

ward exec gate green.

closes #628 ```sh sirens-echo-access-check path/to/access-policy.yaml [...] ``` `<path>: ok` per file, exit 1 with the reason on stderr for any failure, exit 2 with usage on no arguments. Reads files and does nothing else. ## The design is one line `check` calls **`community.LoadAccessPolicy`** — the same function the agent calls at startup. **A second implementation would be a worse gate than none.** It would pass policies the pod rejects and reject policies the pod accepts, and the divergence would surface as a rollout failure that CI had already called green. That is the failure this issue exists to prevent, reintroduced one layer up. This is also why deploy could not build it: their standing rule is not to reimplement a parser for a format another repository owns, and there was no tool here to call. ## What it catches The bound the issue names: ``` guild "…" opens to every member: set rate_limit.per_user to a real bound such as 1/60s ``` And the quieter one — **strict decoding**. A misspelled `ratelimit` fails rather than being ignored, which is precisely what a plain YAML parse elsewhere cannot see: the file is valid YAML and the bound it was meant to set is simply absent. ## The tests caught me twice Two fixtures were wrong on the first run and said so: - I guessed the schema string; it is `coilyco-harness.access.v1` - I wrote an open allowlist as `users: ["all"]`; it is the scalar `users: all`, and the list form fails as a non-snowflake Both would have shipped a test that passed against a fixture the runtime rejects — a gate proving nothing. Worth stating because I had just claimed the command was thin, and thin is exactly where that mistake hides. `ward exec gate` green.
feat(access): an offline gate for the access policy
All checks were successful
ci / image-build (pull_request) Successful in 19s
ci / test (pull_request) Successful in 34s
ci / publish-echo-image (pull_request) Has been skipped
ci / publish-observed (pull_request) Has been skipped
c49953f85e
Deploy applies access-policy.yml as a ConfigMap and its pre-commit parses the
file as YAML, which catches a syntax error and nothing else. Every check that
matters is semantic and lives here, so the first thing to evaluate a policy was
pod boot, after the ConfigMap was already applied.

Deploy's rule is that it never reimplements a parser for a format another
repository owns. There was no tool here to call, so the hole was ours.

The command calls community.LoadAccessPolicy, the same function the agent calls
at startup. A second implementation would be a worse gate than none: it would
pass policies the pod rejects and reject ones it accepts, and the divergence
would surface as a rollout failure that CI called green.

Tests cover the bound the issue names, an open guild with no per-user limit,
plus a misspelled key, an unsupported schema, and a missing file. Two of the
fixtures were wrong on the first run and the tests said so, which is the only
reason the schema string and the scalar form of an open allowlist are right.

Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
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!639
No description provided.