Repository navigation
1.2.0
Schema set 1.2 (CDF spec contract-batch-two-implement-all, DR-183): the second review's fourteen
improvements, from a package that could not run its own test to a corpus that runs under six other
validators. Additive within 1.x by the contract's own rule, mechanically checked: against 1.1.0
the guard reports 115 allow-listed tightenings, each naming the exact value it admits and the
fixture or recorded check that proves no conformant writer ever produced what it now refuses, and
every real journal in the reference deployment validates with zero rejections (33,608 audit
records, 19,231 CDI signals, 995 provenance records, 2 assessments, the six-line lease journal, the
workspace config). No byte of any existing hash or signature changes. One new schema,
lease-record; one field at development stability, allow.tool_args; everything else stable.
Added
lease-record, the decision side of the lease (SPEC §6.1). One line of the lease journal:
nine events (granted,refused,narrowed,heartbeat,attached,revoked,stopped,
completed,expired) with what each must carry, enforced by conditional requirements; a
refusal'sreasonsare reserved codes (R<n>,runtime_error:<name>,vendor:<vendor>:<code>)
with the prose inreason;declared_hashandgranted_hashtie a record to the exact bytes
decided; arevokedrecord namesby(an ancestor lease orissuer) and rule L3 refuses any
other, given the journal. The schema carries the manifest and the lease inlined, held identical to
their sources (conformance/inlined-copies.mjs). Eleven valid fixtures, five invalid, one by rule.
The reference deployment's real journal validates unchanged; a 1.1grantedrecord carries no
granted_hashand a reader may compute it.
Changed
- Hosts, commands, tools and approvals have one identity rule each, enforced by the schemas
(SPEC §4.4). A host is a lower-case DNS name (IPv4 literals andlocalhostincluded), with at most
a single leading*.label, or*; a scheme, a port, a path, whitespace, upper case, a trailing
dot and an interior wildcard are refused. A command is the executable's basename: no path, no
arguments, no shell operator. A tool or approval is an identifier of at most 128 characters that
is never*and carries no whitespace. The same rules apply to the plugin schemas'capabilities,
which is the leaseallowshape. Eighteen invalid fixtures, one per refused form, and one valid
fixture carrying every admitted form.agent.nameis capped at 120 characters and described as
never a person's name;intent.purposeat 500.tooling/inline-granted-manifest.mjsrewrites the
inlined copy inagent-lease.schema.jsonfrom its source, so the identity check has a tool to
satisfy it. - Lease rules L1 and L2, and one timestamp form inside the signed bytes (SPEC §6). A schema
cannot say "expires_atis afterissued_at" or "not its own parent", soconformance/lease-rules.mjs
does, the runner applies it to every valid lease and tofixtures/invalid-by-rule/(Expired,
TooEarly,SelfParent, named after the UCAN 1.0 fixture errors where one exists), and an
adapter proves its own rules through aruleshook, reported unchecked when absent.
issued_atandexpires_atadmit only UTC with milliseconds andZ, because an offset form
hashes the same instant to different bytes; every real lease already uses it.attestation.signature
is 64 hex like the lease's own;budget.depth≤ 16 andbudget.fan_out≤ 256. - An allow-list entry admits one tightening, not every later one at the same path. Every guard
finding now carriesafter, the exact value it admits (pattern=…,maximum=16,enum=[…]),
and an entry must name it. Found while loweringdepth's ceiling: batch one's entry for the
2^53maximumwould have covered it silently. Every existing entry gained itsafter; three
guard scenarios prove the match is exact. - Inline plugin hooks and MCP servers are typed, and a manifest cannot carry a credential.
An inlinehooksobject validates as the event map (thirty-three events, five handler types
with their required fields, after the Claude Code settings schema of 2026-10-05) and an inline
mcpServersobject as a map of server configs (stdiorequirescommand;http,sse,ws
andstreamable-httprequireurl). A value in a hook header, an MCPenvor an MCPheaders
that matches one of seven credential shapes is refused; a marketplace entry'sheadersrefuses
anauthorizationkey in any case; a contributed provider'sbaseUrlishttps://or
http://to loopback only. Nine invalid fixtures, one valid fixture with every admitted inline
form; Anthropic's bundled-plugin manifest and the reference deployment's own manifests validate
unchanged. - The lock follows local
$refs (lock format 4). A property re-pointed from one definition to a
stricter one used to change only itsrefstring, which the guard never compared, so the typed
hook and MCP shapes above would have landed unseen; and a value that became a$reflost its
recorded type and read asTYPE_CHANGED. The referenced definition is now digested at the
referring path, withrefrecorded beside it; a cycle stops at its second visit. - Evidence hygiene (SPEC §6.2).
audit-event.event_typeis two or more lower-case dotted segments,
with the reference writer's first segments reserved and a vendor name for anyone else;summary
andreasoningrefuse any control character; adetailsstring value is at most 200 characters;
actor.runtime_agent(optional, the closed vocabulary) is added whileactor.runtimestays open,
because the real journal spells it eleven ways;schema_versionismajor.minoron every schema
(the lease schemas widen from the literal1.0);provenance.specis a slug; a CDI assessment has
exactly six dimensions, each id once, with integer scores; a sealed config path is dotted lower-case
and the runner checks it names a field the fixture carries. Ten invalid fixtures, one valid. Every
real audit record, signal, provenance record and assessment in the reference deployment validates. allow.tool_args(SPEC §4.4), a per-tool argument-schema declaration markedx-stability: development: an issuer MAY omit it from the grant and MUST NOT treat it as authority, because
the reference gate does not yet evaluate argument schemas and a rule without an enforcing gate is
a claim the corpus cannot test. The vectortool-args-droppedshows the reference dropping it.
The stability marker is a$comment(draft-07 defines it): Bowtie showed Ajv's strict mode in
another harness refusing a customx-stabilitykeyword, and a schema only this repository can
compile is not portable. Python'srelikewise rejected\p{Cc}, so the control-character
class is written as literal characters, which every engine reads the same way.- Every normative clause of the SPEC has a named test (
conformance/traceability.json,
checked bynpm test).conformance/spec-clauses.mjsextracts the 87 clauses with stable ids
and a drift key; each is mapped to the fixtures, vectors, checks or rules that test it, or
excluded with a reason (16 are: runtime behaviour, SHOULDs, definitions). Seven fixtures were
added where a clause had nothing to point at: a manifest with a bare-majorschema_version, a
runtime_agentoutside the vocabulary, a model withoutfamily, anallowordenymissing a
list, an attestation with an unknown issuer, and a valid home-relative deny path. - The corpus runs under six other validators.
conformance/suite/draft7/is the corpus in the official
JSON-Schema-Test-Suite format (one file per schema, every fixture a test, written by
npm run lockand checked current bynpm test), and CI runs it through Bowtie against
go-jsonschema,rust-jsonschema,python-jsonschema,java-json-schema,
dotnet-jsonschema-netandjs-ajv, failing on any disagreement. A case is kept under 60 KB as one line, chunking a schema's tests across cases where needed, because a harness that reads a case as a line (the Go one) errors above 64 KiB. A second job runs
Sourcemeta'sjsonschema metaschemaandlint(six style rules excluded by name, each with
its reason in the workflow). Two orphancomponentSourcedefinitions the typed hook and MCP
shapes had left behind are removed, and the marketplace's emptyrelevance.signalsschema
gained a description, both found by that lint. - Every property says what it promises. All 664 declared properties carry a
$commentof
stability: stableorstability: development(onlyallow.tool_argsis development), with
; deprecated: <replacement>for retiring a field.conformance/metaschema.jsonholds that and
the other conventions (dialect,$id, title, description, noformat) andnpm testvalidates
every schema against it. Lock format 5 recordsstability,deprecatedand the names an
allOfif/thenmakes required (the lease record's per-event requirements were invisible to
earlier formats); the guard reportsSTABILITY_LOWEREDandCONDITIONAL_REQUIRED_ADDEDas
breaking and treats deprecation as additive. Two new guard scenarios. - Governance written down.
GOVERNANCE.md: one maintainer (@datajace, the sole CODEOWNER,
stated rather than padded), a proposal underdocs/proposals/before any semantic change, how a
change lands and how a release is cut. A repository-ownedDCOcheck refuses a pull request with
an unsigned commit (the third-party app was not used because a suspended app's check disappears
silently). Issue templates for a defect and a proposal, a pull-request template with the checks
the automation cannot see, Dependabot for npm and Actions weekly, and the proposal template with
Backward compatibility and Security sections and a status lifecycle. - Every release frozen at its own URL, and an index.
pages.ymlnow lays out/<version>/
for everyv1.*tag beside the/1.x/alias, byte for byte as tagged and never rewritten, and
runs on the tag push so the frozen copy appears with the release;release.ymlchecks it serves
the tagged bytes (patiently, and reported rather than failed while the deploy is still landing).
schemas/index.json, written bynpm run lockand validated bynpm test, lists every schema
withfile,$id,title,dialectandfileMatch; it is served beside the schemas. A
SchemaStore catalogue entry is proposed for**/.cdf/config.yaml, pointing at the served
config-coreschema.
npm: https://www.npmjs.com/package/@cognitive-delivery/contract/v/1.2.0
Provenance: published from this workflow run with npm publish --provenance; verify with npm audit signatures after installing, or search Sigstore for pkg:npm/%40cognitive-delivery/contract@1.2.0.
Schemas: https://cognitive-delivery.github.io/contract/1.x/