Skip to content

The kernel's operations are a file, and each field says which it is - #30

Merged
jithinAB merged 3 commits into
masterfrom
pact-kernel/kernel-ops-in-the-spec
Nov 14, 2026
Merged

jithinAB merged 3 commits into
masterfrom
pact-kernel/kernel-ops-in-the-spec

Conversation

@jithinAB

Copy link
Copy Markdown
Contributor

A runtime that runs PACT one operation at a time has to know which fields reach each of the 76 operations of the seven primitives (97 §2, §5.4). That list lived in one place, the OPS table inside scripts/pattern-coverage.py, and said it in keyword prose (limits, at-most, fuel, checks-at-most), which a runtime can only turn into fields by matching words. Bud Meta Harness did exactly that for its per-operation registry and got it wrong in both directions: shape.stream picked up bundle.from and provenance.harness, and shape.one-of picked up nothing. This puts the operations in a file and puts on each field the operations it is, so the mapping is data both sides read, held to each other by a test.

Nothing changes in what an author writes or what pact check accepts.

What changes

  • spec/kernel.yaml: the 76 operations, each with its primitive, what it does and the keyword that is it today, copied from OPS unchanged. An operation an author writes as syntax inside a value rather than as a field of its own says where with written-in: (six of them: one of a, b, list of, stream of, an agent-shaped answer, a binding, a list of conditions).
  • kernel-op: on a field of spec/schema.yaml: one operation or a list. 291 field lines, 295 fields once the anchored interface:/chosen-by: are counted on skill and tool, 347 field-operation pairs. Descriptions, names and because: carry none. Placed after each field's tier: line, so no run of type:/names:/key-names:/surface: lines that a test anchors on is split. The header's attribute list describes it.
  • Field::kernel_ops in pact-schema, read by from_doc with the same helper as names:.
  • crates/pact-schema/tests/every_kernel_operation_is_written_somewhere.rs (4 tests): every operation names one of the seven primitives, is named <prefix>.<what>, and says what it does and its keyword; every kernel-op: names an operation the kernel lists; every operation is named by a field or placed by written-in:; the attribute travels through an anchor. The last test runs the same check on the real files with one line changed each way (store.fork renamed on stage.forks, and shape.one-of's written-in: removed) and requires both to fail with the sentence that names them.
  • scripts/pattern-coverage.py reads OPS from spec/kernel.yaml; its output is byte-identical to master's. --ops gains a column with each operation's fields.
  • scripts/primitive-coverage.py adds the primitive of each operation a keyword's kernel-op: names after the primitives its table gives it. The main ingredient never changes. 48 keywords gain a secondary primitive where the table had given them fewer than their operations have; agent.accepts is actor.signature by OPS's own keyword list, so it is an Actor as well as a Shape. docs/97 §6's "any part" column, Appendix A (48 rows, each only appended to) and Appendix C (the new column) are regenerated; the §5.4 sentence points at the file.
  • CHANGELOG entry; headline test counts synced.

Evidence

  • cargo test --workspace --locked: 1652 passed, 0 failed (the headline count is synced to it).
  • cargo clippy --workspace --all-targets --locked -- -D warnings: clean.
  • python3 scripts/pattern-coverage.py: same output as master; --ops lists fields for 75 operations and none for shape.one-of, which is placed by written-in:.
  • python3 scripts/primitive-coverage.py: 569 keywords, 0 unmapped, main-ingredient counts unchanged.
  • The full adapter suite: 3169 passed, 151 skipped, 1 failed: test_the_second_port_reports_a_spend_cap_it_cannot_price, which fails on master too on a machine without the TypeScript adapter's dependencies installed.

Choices a reviewer may want to change

  • The mapping is mine, curated field by field against OPS's keyword column and the help text. Where a field is several operations it says so (stage.does is six; when-this.in-share is shape.digest and check.digest, as OPS lists it under both). Every placement is a line of YAML to move.
  • written-in: is a sentence, not a list of types, because the six places are syntax a reader recognises, not fields a checker can resolve.
  • The floor in the anchor test (more than 340 pairs) is there so the list cannot shrink silently, the way spec/comparisons.yaml's row floor works.

Downstream: Bud Meta Harness reads kernel-op: at its next re-pin instead of matching keyword text (its PK-1 kernel registry and coverage dashboard).

🤖 Generated with Claude Code

spec/kernel.yaml lists the 76 operations of the seven primitives; kernel-op: on a field of spec/schema.yaml names the operations the field is, read into Field::kernel_ops. every_kernel_operation_is_written_somewhere.rs holds the two files to each other in both directions. pattern-coverage.py reads the operations from the file; primitive-coverage.py adds a keyword's operations' primitives to its own.
…ops-in-the-spec

# Conflicts:
#	CHANGELOG.md
#	README.md
#	docs/90-REVIEW.md
#	site-docs/index.md
#	site-docs/status/verified.md
#	spec/schema.yaml
…ops-in-the-spec

# Conflicts:
#	CHANGELOG.md
#	README.md
#	docs/90-REVIEW.md
#	site-docs/index.md
#	site-docs/status/verified.md
@jithinAB

Copy link
Copy Markdown
Contributor Author

Merged master (0299680, after #29) into this branch. CI on the merged head: gate / everything passes. gate / newest-pydantic-ai fails only the 5 tests/test_parity.py cases master itself fails (pydantic-ai's newest release adds capabilities the registry does not list yet), as on master's run 43389520212. Marking ready and merging, per the owner's standing rule for pact-kernel's upstream PRs.

@jithinAB
jithinAB marked this pull request as ready for review November 14, 2026 20:17
@jithinAB
jithinAB merged commit c325e46 into master Nov 14, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant