specverb: make the engine durable across multiple OpenAPI specs #146

Closed
opened 2026-06-17 10:59:18 +00:00 by coilysiren · 3 comments
Owner

Delete the Forgejo-specific expansion table and prove the specverb engine drives three specs of different shapes (Forgejo Swagger 2.0, Trello OpenAPI 3.0 JSON, Tailscale OpenAPI 3.1 YAML).

Scope:

  • declarative op-binding: every can grant names its op "<operationId>"; verb+resource are the CLI leaf+group
  • OpenAPI-3 reader via kin-openapi (3.0 + 3.1, JSON + YAML, components $ref, requestBody.content, in:query/in:path params) alongside the existing Swagger-2 path
  • auth generalization: header-token, bearer, query-param dual-secret, all redacted in dry-run
  • deny enforcement + teaching messages (a deny beats an allow)
  • restrict gate (wrap-level glob allowlist on path params, fail closed)
  • call multi-call action execution with $step.field data-flow
  • ward consumers: forgejo (hardened), trello, tailscale guardfiles
Delete the Forgejo-specific expansion table and prove the specverb engine drives three specs of different shapes (Forgejo Swagger 2.0, Trello OpenAPI 3.0 JSON, Tailscale OpenAPI 3.1 YAML). Scope: - declarative op-binding: every `can` grant names its `op "<operationId>"`; verb+resource are the CLI leaf+group - OpenAPI-3 reader via kin-openapi (3.0 + 3.1, JSON + YAML, components $ref, requestBody.content, in:query/in:path params) alongside the existing Swagger-2 path - auth generalization: header-token, bearer, query-param dual-secret, all redacted in dry-run - deny enforcement + teaching messages (a deny beats an allow) - restrict gate (wrap-level glob allowlist on path params, fail closed) - `call` multi-call action execution with $step.field data-flow - ward consumers: forgejo (hardened), trello, tailscale guardfiles
Member

🔒 Reserved by ward agent claude — container ward-cli-guard-issue-146-claude-a2bb0f8d on host kais-macbook-pro.local is carrying this issue (reserved 2026-06-18T08:45:39Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent claude` — container `ward-cli-guard-issue-146-claude-a2bb0f8d` on host `kais-macbook-pro.local` is carrying this issue (reserved 2026-06-18T08:45:39Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
coilyco-ops added
P3
and removed
P2
labels 2026-06-24 04:11:40 +00:00
Member

🔒 Reserved by ward agent --driver claude — container ward-cli-guard-issue-146-claude-2c69dd72 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-06-24T06:42:57Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-cli-guard-issue-146-claude-2c69dd72` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-06-24T06:42:57Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

Closing as already satisfied in main. Every deliverable in this capstone landed incrementally under prior issues, so there is no remaining engine work to commit:

  • Delete the Forgejo-specific expansion table — done by 4adc05f (make openapi3.T the engine IR, retire the swaggerSpec adapter). http/specverb/resolve.go is now fully spec-agnostic (generic verbConventions CRUD table); no Forgejo op-table remains anywhere in http/specverb.
  • OpenAPI-3 reader via kin-openapi (3.0 + 3.1, JSON + YAML, $ref, requestBody.content, query/path params)cdb5d04; lives in http/specverb/openapi3.go + prune_openapi3.go, tested in openapi3_test.go.
  • Declarative op-binding (op "<operationId>", verb+resource = CLI leaf+group)c7d4c9b / f8b71b2 / ef765d0 (op auto-resolves by convention, stays an override).
  • Auth generalization (header-token, bearer, query-param dual-secret, redacted in dry-run)1f1ba4b (pluggable value-source providers); providers.go, auth_test.go.
  • Deny enforcement + teaching messages (deny beats allow)22fc11b; deny.go, deny_test.go.
  • Restrict gate (wrap-level glob allowlist on path params, fail closed)720a81e; restrict.go, restrict_test.go.
  • call multi-call execution with $step.field data-flowd3c346f; action_call.go, action_call_test.go.

Three specs of different shapes are proven in-tree: testdata/forgejo.swagger.v1.json (Swagger 2.0), testdata/trello.openapi.json (OpenAPI 3.0 JSON), and testdata/tailscale.openapi.yaml (OpenAPI 3.1 YAML) are each driven through the engine by the package test suite (12 / 2 / 4 test files respectively).

The consumer guardfiles (forgejo hardened / trello / tailscale) are downstream artifacts of the ward repo, not this engine repo.

Note: I could not run a fresh make test / lint pass from this container because the shared host VM disk (/dev/vda1) is at 100% from data outside this container, so the Go module cache and golangci-lint gate cannot fit. No repo changes were made; main is unchanged.

— Claude (she/her), via ward agent

Closing as **already satisfied in `main`**. Every deliverable in this capstone landed incrementally under prior issues, so there is no remaining engine work to commit: - **Delete the Forgejo-specific expansion table** — done by `4adc05f` (*make `openapi3.T` the engine IR, retire the `swaggerSpec` adapter*). `http/specverb/resolve.go` is now fully spec-agnostic (generic `verbConventions` CRUD table); no Forgejo op-table remains anywhere in `http/specverb`. - **OpenAPI-3 reader via kin-openapi (3.0 + 3.1, JSON + YAML, `$ref`, `requestBody.content`, query/path params)** — `cdb5d04`; lives in `http/specverb/openapi3.go` + `prune_openapi3.go`, tested in `openapi3_test.go`. - **Declarative op-binding (`op "<operationId>"`, verb+resource = CLI leaf+group)** — `c7d4c9b` / `f8b71b2` / `ef765d0` (op auto-resolves by convention, stays an override). - **Auth generalization (header-token, bearer, query-param dual-secret, redacted in dry-run)** — `1f1ba4b` (pluggable value-source providers); `providers.go`, `auth_test.go`. - **Deny enforcement + teaching messages (deny beats allow)** — `22fc11b`; `deny.go`, `deny_test.go`. - **Restrict gate (wrap-level glob allowlist on path params, fail closed)** — `720a81e`; `restrict.go`, `restrict_test.go`. - **`call` multi-call execution with `$step.field` data-flow** — `d3c346f`; `action_call.go`, `action_call_test.go`. **Three specs of different shapes are proven in-tree**: `testdata/forgejo.swagger.v1.json` (Swagger 2.0), `testdata/trello.openapi.json` (OpenAPI 3.0 JSON), and `testdata/tailscale.openapi.yaml` (OpenAPI 3.1 YAML) are each driven through the engine by the package test suite (12 / 2 / 4 test files respectively). The consumer guardfiles (forgejo hardened / trello / tailscale) are downstream artifacts of the `ward` repo, not this engine repo. Note: I could not run a fresh `make test` / lint pass from this container because the shared host VM disk (`/dev/vda1`) is at 100% from data outside this container, so the Go module cache and golangci-lint gate cannot fit. No repo changes were made; `main` is unchanged. — Claude (she/her), via `ward agent`
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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/cli-guard#146
No description provided.