feat(capabilities): add the typed capability catalog of sixteen fleet capabilities (CFVC-09) - #1919
Closed
sbracewell64 wants to merge 2 commits into
Closed
sbracewell64 wants to merge 2 commits into
sbracewell64 wants to merge 2 commits into
Conversation
…-09)
Add capabilities/catalog.json: a harness-neutral catalog of sixteen typed
capabilities, each naming the file that already implements it. Definitions
only - nothing is bound, nothing executes, and no runtime reads the file, so
this changes nothing for any agent and rolls back by deleting it.
Every row is {name, input_schema, output_schema, owner, authority_class,
verifier}. authority_class reuses loopspecs/schema.json's existing validated
enum rather than growing a second vocabulary. network.request is defined and
deliberately left unowned and captain-required, because nothing here mediates
general outbound network access and naming an owner would invent one.
The catalog certifies in its own text that it is a capability boundary and
not a security boundary: crewmates launch with permission enforcement
disabled and the harnesses do not share a sandbox, so it constrains a
mistaken agent, never a hostile one. Enforcement would need an issue-time
binding record, which is separate work blocked on an open ownership
decision.
This is not the platform's CapabilityRegistry and states so: that answers a
Kernel-side service-dispatch question, not an agent-side authority question.
tests/fm-capability-catalog.test.sh pins the contract - every owner and
verifier resolves, network.request is the only unowned row and is
captain-required, every authority_class is in the existing enum, and the
security-boundary certification is present. Each check runs against a mutated
copy first and must fail there, so a pass is evidence the check fires.
sbracewell64
force-pushed
the
fm/cfvc-09-capability-catalog
branch
from
August 7, 2026 22:34
04f99d0 to
829eb36
Compare
sbracewell64
added a commit
to sbracewell64/firstmate
that referenced
this pull request
Aug 11, 2026
… of upstream kunchenguid#1919) (#78) Land CFVC-09 on the fork trunk, which is the code this fleet actually runs. The same change was contributed upstream as kunchenguid#1919 and merged there, but a merged upstream PR is a contribution rather than a landing, so capabilities/catalog.json was still absent from the running trunk. The catalog is harness-neutral and definitions ONLY: nothing is bound, nothing executes, and no runtime reads the file. Each of the sixteen rows names an existing owner in this repo plus the existing check that pins that owner's behavior. network.request is deliberately unowned and captain-required, because nothing here mediates general outbound network access and naming an owner would invent one. authority_class reuses loopspecs/schema.json's already-validated enum verbatim rather than growing a second vocabulary, and the file certifies in its own text that it is a capability boundary and NOT a security boundary: it constrains a mistaken agent, never a hostile one. Binding and enforcement are CFVC-10's work, deliberately not built here. Rollback is deleting the file.
Owner
|
Speaking as Kun's firstmate: closing this as stale. It has been waiting on a contributor update for 14+ days with no author push or comment. Reopen if you want to pick it back up. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
CFVC-09: build the capability catalog - typed definitions ONLY - per data/cfvc-synthesis-and-plan/report.md section 4's CFVC-09 table, which is the authoritative spec.
Goal: a harness-neutral catalog of typed capabilities, each naming an existing owner. Definitions only: nothing is bound, nothing executes, no runtime reads the file.
Context that explains the shape: every crewmate on every harness currently launches with all permission enforcement disabled (bin/fm-launch-lib.sh - four explicit bypass flags plus one harness with no permission system at all), so 'child_authority is a subset of parent_authority' is doctrinal only today. This increment NAMES capabilities. Enforcement arrives later via CFVC-10 (the capability binding record and issue-time authority law), which is deliberately split off and blocked on an open captain ownership decision (work-identity-owner). Building any binding record, broker, or enforcement point HERE was explicitly out of scope and was deliberately not done.
Accepted requirements, all from the spec:
Decisions made while doing the work, which a reviewer reading only the diff would not know:
Decisions already accepted on an earlier run of this same branch, which a fresh run should honour rather than re-litigate:
(a) network.request's purpose says it covers requests 'not already mediated by a named forge, quota, or vendor owner above', but there are no quota or vendor rows. That is stale drafting by the author, confirmed. Fix by dropping the words 'quota, or vendor'. Do NOT add quota or vendor rows: the catalog is fixed at sixteen.
(b) field_contract claims every schema type comes from loopspecs/schema.json's type vocabulary, but 'bool' is a catalog-local extension used by six rows. The provenance claim is factually wrong in a fact-stating artifact. Fix the wording to say the catalog uses the LoopSpec type vocabulary plus 'bool', which extends it, and that the only thing this catalog must reuse from loopspecs/schema.json is the authority_class enum. Do NOT remove bool from the rows and do NOT add bool to loopspecs/schema.json.
(c) tests/fm-capability-catalog.test.sh's mutate() ignores python3's exit status, so a mutation that failed to apply would leave the control passing on a 'catalog unreadable' violation - a broken negative control reading as proof the check fires, the exact vacuity the controls exist to prevent. Fix mutate() to fail loudly when the mutation does not apply, keeping every existing mutation body and all six cases green.
What Changed
capabilities/catalog.json, a harness-neutral, data-only catalog of sixteen typed capabilities, each defined as{name, input_schema, output_schema, owner, authority_class, verifier}. Every owner is an existing script underbin/and every verifier an existing check undertests/;authority_classreuses the validated enum fromloopspecs/schema.jsonrather than inventing a new vocabulary.network.requestis the single deliberate exception — defined, unowned, and captain-required, with the reason recorded in anunowned_becausefield. The artifact states in its own text that it is a capability boundary, not a security boundary, names CFVC-10 as the future enforcement point, and explicitly disclaims merging into the platform's CapabilityRegistry. No runtime reads the file; definitions only.tests/fm-capability-catalog.test.sh, which runs every check against a mutated catalog copy first and requires it to fail there before accepting the real catalog. The pipeline's review round landed three authorized fixes on this branch: dropped the stale "quota, or vendor" wording fromnetwork.request's purpose, corrected the field-contract text to state thatboolis a catalog-local extension of the LoopSpec type vocabulary, and hardened the test'smutate()to fail loudly when a mutation does not apply so a broken negative control can't read as proof the check fires. The new test is wired intobin/fm-test-run.sh's family classifier and the artifact is listed in AGENTS.md's tracked-material list and layout tree.Risk Assessment
✅ Low: The only delta since the last reviewed head is one commit that applies the three author-authorized fixes exactly as specified (two wording corrections in the data-only catalog and a hardened negative-control mutate() whose failure path was verified to propagate via stderr and a non-zero exit through the command substitution), with every round-1 acceptance-criterion verification still holding.
Testing
Ran the spec-required capability-catalog test (all six checks green), independently audited the catalog against every intent constraint (sixteen typed rows, resolving owners and verifiers, enum reuse, the unowned captain-required network.request exception, both written-in disclaimers), visibly demonstrated the negative controls firing on mutated copies and the hardened mutate() failing loudly, confirmed no runtime reads the file, verified the three previously-authorized review fixes landed in 04f99d0, and covered the peripheral classifier and AGENTS.md edits with their own focused tests — everything passed. No screenshot artifact because the change is a JSON data artifact plus a shell test with no rendered UI surface; CLI transcripts and the audit table are the end-user-facing evidence.
Evidence: Capability catalog test transcript (six checks green)
ok - capability catalog: every capability names an owner file that exists ok - capability catalog: every verifier names a check that exists ok - capability catalog: network.request is the only unowned row and is captain-required ok - capability catalog: every authority_class is in the existing LoopSpec enum ok - capability catalog: states it is a capability boundary, not a security boundary ok - capability catalog: sixteen capabilities with unique namesEvidence: Catalog audit vs CFVC-09 spec (rows, owners, enum, exception, certifications)
Evidence: Negative controls firing on mutated copies + mutate() hardening demo
Evidence: Changed-file selector picks up the new test with nothing unmapped
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
⏭️ **Rebase** - skipped
.agents/skills/afk/SKILL.md- branch carries 46 commit(s) that exist on your local main branch but were never pushed to origin/main; rebasing would bundle this unrelated work (202 file(s)) into the PR:Push main to origin, or rebase your branch onto origin/main, before gating.
🔧 **Review** - 3 issues found → auto-fixed ✅
capabilities/catalog.json:166- network.request's purpose text says the capability covers requests "not already mediated by a named forge, quota, or vendor owner above", but the catalog contains no quota or vendor rows — stale drafting in a fact-stating artifact. Author-confirmed with an authorized resolution: drop the words "quota, or vendor" from the purpose text. Do NOT add quota or vendor rows; the catalog is fixed at sixteen.capabilities/catalog.json:22- field_contract's input_schema entry claims the types "(slug, string, string[], bool, object, pos_int)" are "the loopspecs/schema.json type vocabulary", but 'bool' appears zero times in loopspecs/schema.json — it is a catalog-local extension used by six rows, so the provenance claim is factually wrong in a fact-stating artifact. Author-confirmed with an authorized resolution: reword to say the catalog uses the LoopSpec type vocabulary plus 'bool', which extends it, and that the only thing this catalog must reuse from loopspecs/schema.json is the authority_class enum. Do NOT remove bool from the rows and do NOT add bool to loopspecs/schema.json.tests/fm-capability-catalog.test.sh:124- mutate() ignores python3's exit status: if exec(body) raises (mutation fails to apply), the destination file is never written, but printf still echoes its path; check() then reports "catalog unreadable" on the missing file and assert_control_fires treats that as the control firing — a broken negative control reading as proof the check works, the exact vacuity the controls exist to prevent. Latent today (all six current mutation bodies apply cleanly), but it silently degrades the verification discipline. Author-confirmed with an authorized resolution: make mutate() fail loudly when the mutation does not apply, keeping every existing mutation body and all six test cases green.🔧 Fix: fix stale catalog wording and harden mutate negative controls
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-capability-catalog.test.sh— all six cases green (owners resolve, verifiers resolve, network.request unowned+captain-required, enum reuse, security-boundary disclaimer, sixteen unique rows)Manual audit script overcapabilities/catalog.jsonvs the CFVC-09 spec: 16 rows, six required fields per row, all 15 owners and verifiers exist on disk, all authority_class values in loopspecs/schema.json's enum, unowned_because present, certification names CFVC-10, CapabilityRegistry separation statedManual negative-control demo: ran the test's embedded validator against four mutated catalog copies (bad owner, owned network.request, invented authority class, deleted certification) — each emitted a violation while the real catalog ran cleanManual fix-(c) demo: a mutation body that raises exits python3 with status 1, triggering mutate()'s newfail "mutation did not apply"guardgrep -rn "capabilities/catalog"across the repo — only the test references the file, confirming the data-only/no-runtime-reader claimbash bin/fm-test-run.sh --changed --base 571c60c^ --list— exits 0 with nothing unmapped and selects tests/fm-capability-catalog.test.shbash tests/fm-test-run.test.sh— green, covering the one-line family-classifier edit in bin/fm-test-run.shbash tests/fm-documentation-audiences.test.sh— green, covering the two one-line AGENTS.md updates✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.