Accept describe on inline can-grants #275

Merged
coilysiren merged 1 commit from aos/claude/gm46-can-describe into main 2026-08-10 03:48:59 +00:00
Member

Closes #274.

ward-mcp mints one MCP tool per grant and reads Descriptor.Describe for that tool's description. The inline grammar could not set it on a can grant, so every such tool shipped the generated fallback and a guardfile's only way to say anything about a grant was a // comment no model can read.

The change

describe "..." becomes a can-grant child setting Descriptor.Describe. Duplicate and empty both fail closed, matching fail-when. Proxy describe is untouched.

The grammar widens by exactly one node and gains no authority: a string flowing into a description field consumers already read.

Test changes worth noting

describe inside a can grant was the exemplar for the "unknown grant child" rejection case, so this is a deliberate boundary being moved rather than a bug being fixed. That case now uses annotate, and two new negative cases cover duplicate and empty. A positive test asserts the string lands on the right descriptor and that an omitted describe stays empty.

Verification

make vet, make lint (0 issues), go test ./http/..., and scripts/check-godoc-current.sh all pass. No exported API changed, so the godoc pin is unmoved.

Pre-existing failure, not from this change: make test fails 5 tests in pkg/broker (TestServerAllWriteOpsReachExecutor, TestServerLabelIssueFoldsModeAndLabels, TestServerAuthorizerVetoSkipsExecutor, TestServerExecutorErrorFoldsToResponse, TestServerRejectsProtocolMismatch). I confirmed the identical 5 failures on a clean checkout of main with my change stashed. main is red there independently of this PR, and worth its own issue.

Also worth flagging for whoever runs lint locally: a stale golangci-lint cache produced a phantom gosec hit against a pkg/credseed path that does not exist in a fresh clone. golangci-lint cache clean clears it.

Downstream

This is the first step of a chain. ward-mcp needs a pin bump to pick it up, after which coilyco-bridge/deploy migrates its guardfile comments into describe strings so the text reaches the calling model instead of only the next editor.

Closes #274. `ward-mcp` mints one MCP tool per grant and reads `Descriptor.Describe` for that tool's description. The inline grammar could not set it on a `can` grant, so every such tool shipped the generated fallback and a guardfile's only way to say anything about a grant was a `//` comment no model can read. ## The change `describe "..."` becomes a `can`-grant child setting `Descriptor.Describe`. Duplicate and empty both fail closed, matching `fail-when`. Proxy `describe` is untouched. The grammar widens by exactly one node and gains no authority: a string flowing into a description field consumers already read. ## Test changes worth noting `describe` inside a `can` grant was the **exemplar** for the `"unknown grant child"` rejection case, so this is a deliberate boundary being moved rather than a bug being fixed. That case now uses `annotate`, and two new negative cases cover duplicate and empty. A positive test asserts the string lands on the right descriptor and that an omitted `describe` stays empty. ## Verification `make vet`, `make lint` (0 issues), `go test ./http/...`, and `scripts/check-godoc-current.sh` all pass. No exported API changed, so the godoc pin is unmoved. **Pre-existing failure, not from this change:** `make test` fails 5 tests in `pkg/broker` (`TestServerAllWriteOpsReachExecutor`, `TestServerLabelIssueFoldsModeAndLabels`, `TestServerAuthorizerVetoSkipsExecutor`, `TestServerExecutorErrorFoldsToResponse`, `TestServerRejectsProtocolMismatch`). I confirmed the identical 5 failures on a clean checkout of `main` with my change stashed. `main` is red there independently of this PR, and worth its own issue. Also worth flagging for whoever runs lint locally: a stale `golangci-lint` cache produced a phantom `gosec` hit against a `pkg/credseed` path that does not exist in a fresh clone. `golangci-lint cache clean` clears it. ## Downstream This is the first step of a chain. `ward-mcp` needs a pin bump to pick it up, after which `coilyco-bridge/deploy` migrates its guardfile comments into `describe` strings so the text reaches the calling model instead of only the next editor.
feat(opcore): accept describe on inline can-grants
All checks were successful
ci / secrets (pull_request) Successful in 8s
ci / lint (pull_request) Successful in 37s
ci / test (pull_request) Successful in 48s
7be1ae6c16
ward-mcp mints one MCP tool per grant and reads Descriptor.Describe for that
tool's description, falling back to a generated sentence. The inline grammar
could not set it: applyInlineGrantChild fail-closes outside
path | query | body | set | fail-when, and the only describe handler wrote
Proxy.Describe, a different field on a different struct.

So every can-grant tool shipped the fallback, and a guardfile's only way to say
anything about a grant was a // comment no model can read. A channel-scoped
Discord read surface in coilyco-bridge/deploy describes itself to the calling
model as "Use this when the user wants to list eco-chat-message through the
configured upstream service", while 40 lines of // explain the eco scope, the
page cap, and that the messages are untrusted community input. The audience that
most needs that text is the one audience a comment cannot reach.

Accept describe as a can-grant child, setting Descriptor.Describe. Duplicate and
empty both fail closed, matching fail-when. Proxy describe is untouched.

The grammar widens by one node and gains no authority: a string flowing to a
description field consumers already read.

`describe` inside a can-grant was the exemplar for the "unknown grant child"
rejection test, so that case now uses `annotate` and two new negative cases
cover duplicate and empty.

Closes #274

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-flight-deck/umbra!275
No description provided.