feat(openapi-mcp): expose complete catalog release admission - #27
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
| ### Complete release admission | ||
|
|
||
| `admitCatalogRelease(options, catalogId, releaseId)` from | ||
| `@knitli/openapi-mcp/runtime` verifies every signed inventory operation and | ||
| schema before admitting the generation through the configured `GenerationStore`. | ||
| It revalidates the manifest and inventory around generation CAS retries. Use | ||
| this supported portable API when activating an executable catalog; `admitManifest` | ||
| retains its signed-envelope-only contract. Storage must preserve immutable release | ||
| identities. Admission does not guarantee future availability, so runtime reads | ||
| continue verifying records at use time. |
There was a problem hiding this comment.
Nit: this new "Complete release admission" section is nested under ## Release gates, which is entirely about npm package publication (protected npmrelease environment, OIDC, registry verification, etc.) — a different "release" concept from the OpenAPI catalog release/generation this section documents. Nesting it here reads as if admitCatalogRelease is part of the publish-gating process, which it isn't.
Consider moving this under ## Recover from a bad release (which already documents admitManifest, generations, and rollback for catalog releases) or its own top-level ## section, so it sits next to the concept it actually belongs to.
🧶 Knitli Agent · PR ReviewerClean, well-tested addition.
|
|
🎉 This PR is included in version 1.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
## What does this change? Adds Knitli's OpenAPI host binding foundation. An authenticated configurator can issue a draft for its intended workspace; the host resolves the stored canonical resource URL, reserves and activates the matching facet, and captures a restricted dispatch capability. Account disconnection, facet removal, and workspace deletion fence further use and retain durable cleanup state until acknowledgement. The implementation includes transactional approval-queue insertion guards, account-incarnation and generation checks, cleanup-only revocation capabilities, and an opt-in connector fixture exercised through real authenticated `/api` Cap'n Web sessions. Kernel/shared changes and UI wiring are separated into commits for review. Custom implementation and test files carry precise fork-audit exemptions. Upstream integration files remain audited; no broad exemption hides their changes. Account disconnect delivers recipient workspace fences and completes connector cleanup before invoking provider revocation. A failed recipient remains durably pending and prevents the provider operation; the final account mutation still checks the exact lifecycle epoch. Remote fencing takes effect on recipient arrival, not atomically with the User-side fence. OpenAPI alarm recovery runs only when its own deadline is due and retries pending bindings, leaving healthy published connections untouched. Constructor-driven recovery still replays all bindings after restart. Legacy and OpenAPI resource resolution share one private User policy-enforcement helper, documented in `AGENTS.md`, so deployment-policy corrections apply to both paths. The private host facet, draft authority, dispatch-use authority, and acknowledgement-only revoker now use named `@validateRpc()` targets with private captured state. Malformed arguments fail generated validation before lifecycle reads or writes. Fixture protocol targets are also decorated, and the new protocol methods no longer bypass validation. The draft handoff uses a scoped native stub; recipients duplicate capabilities they retain. A pinned `capnweb-validate@0.3.0` patch preserves native Workers capability transport: its original transform wrapped returned native stubs in JavaScript proxies, breaking subsequent RPC calls. Both ESM and CJS transforms now distinguish Workers brand declarations from Cap'n Web declarations. Native capabilities retain stub validation and transport identity; their owning decorated endpoint enforces method arguments. Ordinary Cap'n Web capabilities retain service wrapping. The patch and its regression test have exact fork-audit exemptions. Agent keepalive scheduling now retains the deadline established when the first agent starts. OpenAPI recovery and response updates continue choosing the earliest shared alarm without restarting that minute. Last-agent completion clears the agent deadline and retains any response/OpenAPI deadline. The alarm handler itself is unchanged. Restart recovery preserves previously published bindings across transient lookup, activation, and description/publication failures. The constructor marks all persisted published bindings `recoveryPending` before its first recovery await. These bindings retain their identity and remain unavailable to public entry points and dispatch use until the full replay succeeds. Private dispatch-key registration can proceed during replay. Pending rows participate in the existing alarm retries, and a late failed lookup cannot revoke a binding another replay already recovered. Locally established semantic invalidation still fences; failed new creation still cleans up. Both recovery warning paths now include the caught error through the typed logger, retaining diagnostic message and stack. Recovery now starts independent account drafts and binding replays concurrently, with the durable retry alarm armed before external work. A real 10-second timer bounds each recovery wait. The entire attempt, including lookup, retains its per-key slot until the underlying operation settles, so repeated alarms cannot accumulate duplicate hanging RPCs. Expired attempts cannot activate, publish, or provide usable dispatch authority; late lookup results release their finalizer. Timeout preserves pending state rather than treating a published grant as invalid. Safe revocation acknowledgements may finish late. The removal warning now also includes its caught exception through the typed logger. ## Review and validation This feature is for `knitli/knitli-os`; custom files have precise fork exemptions and upstream integration files remain audited. Independent review covered lifecycle behavior, capability scope, native stub ownership, and the dependency compatibility patch. - Full build: 70 tasks passed, including production validator generation. - Full tests: 169 script tests and 2,406 Vitest tests passed, with seven existing skips and one expected failure. This includes 736 backend tests and 63 integration tests. - All 22 authenticated OpenAPI acceptance cases passed, with no skips or unhandled errors. - Lint, script type checking, and the fork merge audit passed. - Actual RPC regressions reject malformed dispatch-key requests, activation digests, draft registration/cancellation, proof-revocation reasons, selection inputs, and session writes before lifecycle effects. - The transform regression exercises distinct public ESM and CJS plugins, checks native `stub` versus Cap'n Web `stubOf` output, and checks the production zero-argument dispatch authority's generated validator structurally. Sensitivity checks ran in isolated scratch copies. Removing the facet decorator caused seven intended assertion failures; removing the draft-authority decorator caused two, and removing the proof-revoker decorator caused one. Removing fixture selection or session validation failed their respective authenticated assertions. Using the original unpatched ESM/CJS transforms caused two native-capability shape failures; removing the zero-argument authority decorator caused two structural failures. Restoring each change returned the relevant full files to green. Agent-deadline regressions exercise real agent registration/unregistration, OpenAPI recovery, response scheduling, and an alarm handler waiting for completion. The final full facet file passed all 64 tests. In an isolated scratch copy, restoring the original implementation caused three deadline assertion failures: OpenAPI and response updates each postponed the deadline by 10 seconds, and an update during the waiting alarm postponed it by 60 seconds. Restoring the fix returned all 64 tests to green. Tests use explicit timestamps to check stored scheduling decisions, not elapsed workerd wall-clock time. Restart regressions cover constructor marking of multiple bindings, lookup/activation/description failures and successful retry, repeated Add, late overlapping lookup failure, and dispatch availability during recovery. The facet/dispatch files pass 89 tests. Restoring the original source in an isolated scratch copy causes seven regression failures; restoring the fix returns all 89 to green. A separate narrow mutation removes the dispatch-use guard and fails specifically because pending `use.assertActive()` incorrectly resolves; restoring it returns all 89 to green. Earlier sensitivity checks also cover captured generation, account readiness, final transactional insertion, public workspace deletion, recipient fencing before provider revocation, alarm deadline/pending-only recovery, and shared deployment-policy enforcement. Full final suites passed after all fixes. Blueprint regression coverage includes eight backend setup tests, two additional authenticated acceptance cases, and 15 focused UI tests. Eight narrow helper mutations fail their intended assertions. Removing the preallocation guard produces the wrong error and an extra workspace; restoring it returns all 22 acceptance cases to green. UI mutations cover suggested-URL bypass, explicit deferral, original binding names, dependent retries, workspace/gadget scoping, account preference, and both sides of owner-only panel visibility. All mutations ran in isolated scratch copies and were restored to green. Recovery isolation regressions run through the production timer mechanism and actual Overseer alarm path. They cover hung lookup, activation and publication, healthy bindings and historical drafts alongside a stuck account draft, no overlapping retries after expiry, and retained dispatch authority remaining expired after a later successful replay. The prior overlap-oriented lookup regression now requires one shared in-flight attempt, matching the new contract. Tests capture and invoke the actual timer callback and assert its configured delay; they do not infer elapsed time from workerd's frozen request clock. Six isolated scratch mutations triggered the intended assertions: restoring sequential recovery blocked a healthy binding; serializing account drafts left healthy historical cleanup pending; removing early scheduling left the retry alarm unarmed; releasing an expired attempt's slot started a duplicate operation; removing the attempt guard permitted late continuation; removing the dispatch-use guard let an expired capability succeed after recovery. Restoring source returned the full facet file to 77 passing tests. Harness and compilation failures were excluded from this evidence. An additional test-file-inclusive type check found the same two pre-existing fixture errors (partial DurableObjectNamespace cast and ObservationDescription.text) as the preceding commit, with no new errors; repository build and script type checks pass. ## Scope and follow-up A permanently unresolved connector operation requires settlement or a Durable Object restart before that same key can retry. This bounds waiting and isolates healthy siblings without claiming remote RPC cancellation. A separately running user Add that recovery joins remains independently authorized. Blueprint retry guarantees apply to durably saved resource IDs and binding progress. The existing resource creation APIs can leave an unused workpiece if execution stops after creation but before its ID is saved; this change does not promise duplicate-free creation across arbitrary process termination. The authenticated reload scenario changes Worker configuration while retaining storage and then logs in again; it is not a process-restart or explicit eviction test. Separate workerd tests exercise Durable Object eviction and persistence. Fixture leases establish protocol admission/drain ordering, not physical provider I/O; expiry checks use explicit injected or persisted timestamps rather than elapsed workerd wall-clock assertions. This PR does not add native provider action execution, the wrapper's native connector/search implementation, publication, deployment, or a wrapper gitlink update. Those remain follow-on integration work. The private connector contract requires an immutable `resourceUrl` and an exact-reference cleanup-only revoker that remains usable after account revocation. Related implementation PRs: [portable admission helper](knitli/toolshed#27) and [wrapper catalog/search](knitli/knitli-site#322). Wrapper pin adoption and the real native connector remain separate steps. The published runtime is adopted separately in [knitli/knitli-site cloudflare#323](knitli/knitli-site#323).
What
Add public
admitCatalogRelease(options, catalogId, releaseId)to@knitli/openapi-mcp/runtime. Admission now has a supported entry point that verifies the complete executable release inventory before performing CAS-backed generation admission. A missing unreferenced operation or corrupt schema rejects the release without accepting its generation.The helper composes the existing executable verification/admission primitives, exports through the public runtime entry point, and is exercised through packed Node/Bun and Worker consumers. The README documents the immutable-storage and use-time verification boundary. This PR does not change package versions or release configuration; publication remains a separate release step.
Plugin(s) affected
packages/openapi-mcppackage.Validation
git diff --checkpassed.mise exec -- bun run validatepassed; generated files are in sync.expected 0,received 1). The unmodified admission file and full runtime suite passed afterward.Checklist
Related implementation PRs: wrapper catalog/search and host binding. Publication and consumer adoption remain separate steps.