docs(okf-v0.2): D4 shipped, and the leaning §14 overruled

Three plan statements the session's work overtook:

- D4 records what shipped, including the part deliberately left undone
  (reading §10's block form) and the invariant that falls out of it.
- V6's "our leaning, for them to accept or overrule" is superseded:
  refuse became import-and-report. The leaning had a problem the prose
  could not see — §14 forbids rejecting a bundle over a broken
  cross-link and does not settle whether `executor.resource` is one,
  while §10.5 asks a consumer to surface. Reporting honours the
  unambiguous rule without testing the ambiguous one.
- What stays with the guard is restated rather than assumed closed:
  whether a non-`.md` code file is within `okf.import_bundle`'s mandate
  is untouched by this, and the execution boundary still has no owner.

Also recorded: the report is key-level because the resource-level value
is the one the parser cannot recover in either canonical form. A
measured limit, not a preference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KKKMwi7e7PVHoFW6dJK5XP
This commit is contained in:
Kjell Tore Guttormsen 2026-07-31 21:45:51 +02:00
commit 6e0a7c015a

View file

@ -390,6 +390,28 @@ value the sanctioned way" sits against the guard's boundary rather than this
library's plumbing. When upstream specifies the protocol, the standing policy
brings it back into scope — and the boundary question goes to the operator first.
**Done 2026-07-31** (`deeb248`, `c6d64c3`), in three parts and with one part
deliberately left undone:
- The five contract fields join `OKF_V0_2`'s emission order as one block, in
§10.2's own listing order. Without it they still emitted — in `emit`'s sorted
tail, where `attester` precedes `runtime`: alphabetical order standing in for
the contract's own.
- `FrontmatterSchema.required_by_type` carries §10.2's one requirement
(`runtime`, for this type and no other). It is the first rule here keyed off a
frontmatter *value* rather than a key, and it cannot be `required`, which would
demand `runtime` of every document. A type the mapping does not name carries no
extra requirement — which is what keeps the field inside §14, since a consumer
must not reject on an unknown `type`.
- Door C reports the §10 pointers it imports (V6, below).
- **Not done, and not a gap: reading the canonical block form.** §10.2 presents
`executor` and `attester` as nested block mappings, both carrying a `resource`.
Measured: the line-oriented parser has no indentation model, flattens them into
one namespace, and the second `resource` overwrites the first — `executor.resource`
is lost with no error raised. Pinned as a characterization test. The invariant
that falls out and now sits in `CLAUDE.md`: **we emit flow form, never block**,
or we write bundles we cannot read back. Reading block is D1b's.
**D5 — v0.2 golden fixtures.** A byte-exact v0.2 bundle in `examples/`. This is
what converts "we support v0.2" from a claim into a test, and in phase 4 it
becomes the cross-runtime conformance oracle for the Node half too.
@ -1298,10 +1320,31 @@ we declared runtime out of scope on that same deferral. Recorded because "the gu
covers it" is a conclusion someone could reasonably draw and it would be wrong in a
way that is hard to detect later.
Our leaning, for them to accept or overrule: Door C should **refuse** a concept
whose frontmatter references an executor or attester resource that did not come
with it — failing closed, and half an Attested Computation is not something a
consumer can use anyway.
Our leaning was that Door C should **refuse** such a concept, failing closed.
**Superseded by the operator 2026-07-31: import and report.** The leaning had a
problem measurement surfaced and the prose did not. §14 forbids a consumer to
reject a bundle over a broken cross-link, and the spec does not settle whether
`executor.resource` counts as one; §10.5, by contrast, explicitly asks a consumer
to *surface* rather than silently drop. Reporting honours the rule that is
unambiguous without testing the rule that is not, and it leaves this door's one
invariant — the sender's bytes, verbatim — untouched.
`ImportResult.unverified_references` is an advisory over the merged set rather
than a fifth bucket: every concept it names has already merged, and a refused
concept is never named, because nothing was written for an operator to inspect.
**The report names the pointer key, not the resource** — and that is a measured
limit, not a preference. Resolving the resource means reading `executor.resource`,
the one value the line-oriented parser cannot recover in *either* canonical form:
the block mapping flattens and collides, the flow mapping stays one opaque string.
A resource-level report would therefore be empty or wrong on exactly the forms
upstream writes, while key presence survives both. Precision arrives with D1b.
Still theirs, and still open: whether a non-`.md` code file inside a bundle is
within `okf.import_bundle`'s mandate. Nothing above answers it — this decision
covers what *we* do with a pointer, not what the guard owes for the thing pointed
at, and the execution boundary named two paragraphs up still has no owner.
## TDD order
@ -1371,6 +1414,9 @@ everything after. **Done 2026-07-26** (`1215f98`, `7bc366b`).
so it deliberately follows the feedback rather than preceding it.
11. **D4**`Attested Computation` round-trip. Nothing in the pilot set uses it,
so building it earlier would add surface the feedback cannot reach.
**Done 2026-07-31** — format only, and taken ahead of steps 910 because the
pilot's two closed tests left D4 the one piece with no dependency on
feedback still outstanding. Details under D4 above.
12. **GA** — flip `OKF_LATEST`, its own release. **V1 to commons** in parallel
throughout; **D6** lands with the GA release.