docs(okf-v0.2): the stamp's byte form is the ownership contract, decided

Two records, both from decisions that had already fallen but were living
only in a mailbox thread.

1. The ownership contract (operator, 2026-08-02). The byte form of
   `generated: { by: process:okf-ingest, ... }` is the intended contract;
   `OwnershipPolicy.owns` is its canonical implementation for Python
   consumers, not the contract itself. The deciding argument is phase 4:
   the Node half shares the contract and the fixtures but never the code,
   so a Python API cannot be load-bearing there. The guarantee is
   formalised at GA rather than now, because the profile is provisional on
   a pre-release precisely so pilot feedback can still move the surface.
   Recorded as GA exit criterion 9, including the notice still owed to
   po-claude.

2. V6, measured end-to-end against the real guard (v0.3.4) instead of the
   stub gate the D4 tests use. Both canonical §10 pointer forms are
   rejected by the guard's grammar before `unverified_references` can see
   them; the only shape that reaches `merged` today is the non-conformant
   one-key block sequence the guard recorded as its own defect. So the
   report is empty against everything conformant, and pre-empts no grammar
   decision of theirs. Sent to them the same day.

586 tests green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JxRjDS9U2szUGYDeuZB2M3
This commit is contained in:
Kjell Tore Guttormsen 2026-08-02 21:30:28 +02:00
commit e654190a4f

View file

@ -1157,6 +1157,50 @@ plainly is more useful than an invitation to review.
other, and consumer trees move — the wiki's document count moved by two between our
reading and their reply.
### The ingest stamp's byte form is the ownership contract — decided 2026-08-02
Door A's `generated` value is `{ by: process:okf-ingest, at: <ingested_at> }`, and
`OwnershipPolicy.owns` recognises it with a string-prefix test. A consumer wanting
to answer "did this library write this file?" for itself has two things it could
bind to: those bytes, or that function. po-claude raised the first as a de facto
interface (2026-07-31); we recorded it as a decision that must fall before GA
rather than as something we were considering.
**Decided (operator, 2026-08-02): the byte form is the intended contract, and the
guarantee is formalised at GA, not now.** Three facts settle it, and the third is
what makes the choice narrower than it looks:
- The actor value deliberately carries no version (V1(d)), so the prefix is stable
across releases by construction. That is what makes it promisable at all.
- Recognition is a string convention, not structure parsing. Measured on the
consumer side: a line-oriented parser returns the whole flow mapping as one
opaque string and the prefix test passes on it. Neither side needs a nesting
model to participate.
- **Phase 4's Node half shares the contract and the fixtures, never the code.** A
Node consumer can never call `OwnershipPolicy.owns`. Making the API the
load-bearing contract would leave the whole Node side with no ownership contract
at all, or drive it to reimplement the byte test unofficially — the same binding
without the promise.
`OwnershipPolicy.owns` is therefore the canonical *implementation* of that test for
Python consumers, not the contract itself.
**The guarantee waits for GA, on the reason we gave po-claude on 2026-07-31:** the
profile is provisional on a pre-release precisely so pilot feedback can move the
surface without a deprecation cycle, and the pilot's one outstanding signal (Test
A) blocks GA regardless. Deciding the policy now and shipping the guarantee at GA
honours "the decision falls before GA" without binding the emitter mid-pilot.
**What is already true, and what is not.** The byte form is asserted today in
`test_okf_v0_2_profile.py:51` and `test_profile_threading.py:91`, so it is locked
against unintended drift. That is an observation of our own emission, not a
promise — a test carrying no stated promise is one we may change together with the
test. A test asserting that the prefix *is* a public interface belongs at GA.
**Owed and unsent.** We told po-claude they would hear when the decision fell,
before GA rather than with it. It has now fallen and the notice has not been sent
(operator's call, 2026-08-02). That is an outstanding obligation, not a closed one.
### GA exit criteria
1. Every P1P3 finding is either fixed or explicitly accepted with the reason
@ -1175,6 +1219,10 @@ reading and their reply.
8. The `llm-ingestion-pipeline-security` §10 boundary questions are answered, or
their being open is recorded as an accepted, stated limit — never left silent,
since Door C is the path an external bundle's executable attester would take.
9. The stamp's byte-form guarantee is stated where a consumer actually reads it
(CHANGELOG and the v0.2 profile docstring) and pinned by a test that asserts it
as a public interface rather than as an observation — and po-claude has been
sent the notice owed since 2026-08-02.
**One honest limit on what GA can mean.** A three-repo pilot exercises only what
those three repos use. `sources` with `usage_window`, multi-verifier `verified`,
@ -1341,6 +1389,26 @@ the block mapping flattens and collides, the flow mapping stays one opaque strin
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.
**Measured end-to-end against the real guard, 2026-08-02 (v0.3.4, resolved version
confirmed).** The D4 tests run through a stub gate, which cannot answer whether the
report ever fires in production. One concept per row, through Door C:
flat baseline, no pointer -> merged report: []
executor: { resource: … } (flow) -> rejected report: []
fail_secure: value begins with a disallowed YAML indicator '{'
attester:\n resource: … (block) -> rejected report: []
fail_secure: nested mappings are not supported in OKF frontmatter
attester:\n - resource: … (one-key seq) -> merged report: [attester]
Both *canonical* forms are stopped by the guard's grammar before the report can see
them. The only shape that carries a §10 pointer through Door C today is the
non-conformant one-key block sequence — precisely the hole the guard recorded as
theirs (their item 3, 2026-07-26). Two consequences: the ordering they recommended
holds, since our report pre-empts no grammar decision of theirs while it stays
empty against everything conformant; and if they fix their item 3, today's only
pointer path closes too. Neither is an argument for leaving it unfixed — an
advisory with nothing to report is the better outcome. Sent to them 2026-08-02.
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