chore(aosguard): repin umbra to v0.167.0, and write down how a boundary fails to bind #1234

Merged
coilysiren merged 4 commits from aos/claude/sb46 into main 2026-08-25 13:37:47 +00:00
Owner

Carries umbra#315's untyped-array encoding fix into aosguard's frozen dependency graph. The fix landed in umbra 2b1cf9c and released as v0.167.0; aosguard was still pinned at v0.161.0, so the defect was live in every guarded Forgejo call.

What was wrong

An array whose Swagger declares "items": {} was encoded as an array of strings. Nothing in the spec said string. Forgejo ignores a label it cannot resolve rather than rejecting the request, so the caller got HTTP 2xx for a write that did not happen:

  • add with a numeric ID was a silent no-op.
  • set with a numeric ID was a silent delete, because PUT replaces the label set and the quoted ID matched no name.

Verified after the repin

issue-label add  --labels 199          -> labels: [199]
issue-label add  --labels priority/P2  -> labels: [priority/P2]
issue-label set  --labels 199          -> labels: [199]

Both spellings now mean what they say on every verb, which is the only encoding consistent with a spec declaring the array carries both.

Closes coilyco-flight-deck/umbra#315
Refs coilysiren/inbox#426

🤖 Generated with Claude Code

Carries `umbra#315`'s untyped-array encoding fix into aosguard's frozen dependency graph. The fix landed in umbra `2b1cf9c` and released as `v0.167.0`; aosguard was still pinned at `v0.161.0`, so the defect was live in every guarded Forgejo call. ## What was wrong An array whose Swagger declares `"items": {}` was encoded as an array of strings. Nothing in the spec said string. Forgejo ignores a label it cannot resolve rather than rejecting the request, so the caller got HTTP 2xx for a write that did not happen: * `add` with a numeric ID was a silent no-op. * `set` with a numeric ID was a silent delete, because `PUT` replaces the label set and the quoted ID matched no name. ## Verified after the repin ``` issue-label add --labels 199 -> labels: [199] issue-label add --labels priority/P2 -> labels: [priority/P2] issue-label set --labels 199 -> labels: [199] ``` Both spellings now mean what they say on every verb, which is the only encoding consistent with a spec declaring the array carries both. Closes coilyco-flight-deck/umbra#315 Refs coilysiren/inbox#426 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chore(aosguard): repin the frozen umbra graph to v0.167.0
Some checks failed
ci / aos-eval-tests (pull_request) Has been cancelled
ci / aos-cli-tests (pull_request) Has been cancelled
ci / ward-doctor (pull_request) Successful in 18m50s
ci / gate (pull_request) Failing after 22m12s
2d7fa3ee00
Carries umbra#315's untyped-array encoding fix into aosguard. An array
whose spec declares `items: {}` now emits a bare all-digits token as a
JSON number and anything else as a string, so `--labels 199` applies the
label instead of silently matching no name.

Verified against the reproduction on the issue:

    issue-label add  --labels 199          -> labels: [199]
    issue-label add  --labels priority/P2  -> labels: [priority/P2]
    issue-label set  --labels 199          -> labels: [199]

Before the repin `set --labels 199` sent `["199"]`, which Forgejo
resolves to no label, making PUT replace the whole label set with an
empty one. Exit 0, every existing label removed.

Closes coilyco-flight-deck/umbra#315
Refs coilysiren/inbox#426

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): move the specgen pin with the lock it is owned by
Some checks failed
ci / aos-eval-tests (pull_request) Successful in 7s
ci / ward-doctor (pull_request) Successful in 8s
ci / aos-cli-tests (pull_request) Successful in 29s
ci / gate (pull_request) Successful in 59s
dev-base-pr / build (pull_request) Failing after 9m1s
1aafa5ef12
The repin bumped `specverb.lock` to umbra v0.167.0 and left
`ARG SPECGEN_VERSION` at 0.161.0, which
test_specgen_pin_is_owned_by_the_dependency_lock exists to catch. It caught it.

The invariant is that the lock owns the pin and the Dockerfile follows, so the
image is built against the umbra the guardfiles were locked against. Bumping one
and not the other would have shipped an image whose specgen predates the
untyped-array fix the lock claims.

Refs coilyco-flight-deck/umbra#315, coilysiren/inbox#426

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 changed title from chore(aosguard): repin the frozen umbra graph to v0.167.0 to chore(aosguard): repin umbra to v0.167.0, and write down how a boundary fails to bind 2026-08-25 10:22:32 +00:00
feat(skills): write down how a declared boundary fails to bind
Some checks failed
ci / aos-cli-tests (pull_request) Successful in 21s
ci / aos-eval-tests (pull_request) Successful in 6s
ci / ward-doctor (pull_request) Successful in 5s
ci / gate (pull_request) Successful in 50s
dev-base-pr / build (pull_request) Failing after 15m30s
d292a139e6
The reusable output of coilysiren/inbox#426, which is a sweep of fourteen places
across four products where a declared boundary neither binds nor refuses. It
passes quietly and reports success.

Derived from the ones already worked rather than designed up front, which was
the epic's own instruction: building the check first would encode a guess about
the failure taxonomy, and building it after encodes the observed one. The
observed one is richer than "it leaked".

Eight entries, each stated as an observation and the check that catches it. The
single highest-yield check is the negative control: supply a filter value that
cannot match and assert the result differs from the unfiltered one. That one
caught a dropped tool argument, an unresolvable label filter, and a partial view
reported as an absence, in three systems that share no code.

Two rules fall out of the whole set rather than any one entry. A surface is
stricter than the thing it guards, because a permissive default is what let most
of these through. And absence established through one search modality is not
absence.

A skill rather than a docs page, because it is a method an agent loads when
auditing a boundary rather than a page about this repository. docs/ is also at
its 40-page cap, which is its own problem and not this commit's to solve.

Refs coilysiren/inbox#426

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
coilysiren deleted branch aos/claude/sb46 2026-08-25 13:37:48 +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!1234
No description provided.