docs(okf-v0.2): supporting the latest OKF version becomes standing policy

Operator directive 2026-07-26: the library always supports the current
latest version of Google OKF. v0.2 shipped 2026-07-25, so v0.2 support is
committed work rather than something a consumer has to request. This
overrides the previous default answer to open question V3 ("no until a
named consumer asks"), which is kept in the plan marked superseded so the
override reads as deliberate.

Support is additive: a new profile, never a migration of the existing two.
That single design choice is what makes an always-latest policy sustainable,
and it resolves the tension the directive would otherwise create with three
constraints that do not yield to it:

- DEFAULT states commons' ingest-spec section 5 layer, so its `generated`
  shape is commons' call. Under the additive design this stops blocking us,
  which takes commons off the critical path.
- STRICT_V1 mirrors the proving consumer's ratified contract; changing
  another repo's contract from here would violate O2.
- v0.2 defers the attestation receipt and verdict wire formats upstream, so
  the format is supportable and the unspecified runtime is not. It re-enters
  scope when upstream specifies it.

This is also the first time the phase-3 profile abstraction is forced by
something outside this repo rather than by a second consumer, which is the
better test of whether the seam was cut in the right place.

Deliverables D1-D6 replace the earlier decision-round framing: a frontmatter
model that can carry block lists (`sources`, multi-verifier `verified`), an
OKF_V0_2 profile plus an OKF_LATEST alias whose moving-target tradeoff is
documented rather than hidden, Door C conformance against the consumer
tolerance rules, `Attested Computation` round-trip, v0.2 golden fixtures, and
a release-checklist re-check so the standing policy cannot decay silently.

Two new assumptions carry the weight. V-A7 forbids any profile from emitting
`timestamp` together with a malformed `generated`, since that combination
would have neither a valid `generated.at` nor an eligible section 13.1
fallback. V-A8 validates our own v0.2 fixture against upstream's reference
implementation, because every other test in the suite only asks whether we
agree with ourselves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A2aKJxLejT9S8jYwoZ9fut
This commit is contained in:
Kjell Tore Guttormsen 2026-07-26 13:41:30 +02:00
commit cb23de4700
3 changed files with 257 additions and 171 deletions

View file

@ -100,30 +100,37 @@ policy differs per consumer and becomes configurable in Phase 3." This is where
the contract becomes explicit and frozen — the precondition for a clean Node
port.
## OKF v0.2 alignment — decisions between 3 and 4, code possibly later
## OKF v0.2 support — between 3 and 4, and it is real code
Everything through Phase 3 targets OKF v0.1. Upstream published v0.2 on
2026-07-25. Detail and open questions: `docs/plan/okf-v0.2-alignment.md`.
2026-07-25, and the standing operator policy is that the library always supports
the current latest OKF version (see `CLAUDE.md`). So this is a committed
implementation track, not a decision round:
`docs/plan/okf-v0.2-alignment.md`.
**Why the decisions must land before Phase 4 code, even if the code does not.**
Phase 4 ports a *frozen, explicit* contract and uses the shared fixture suite as
the cross-runtime conformance oracle. Freezing that contract while its relation
to upstream v0.2 is undecided means freezing a v0.1 shape into two runtimes
instead of one, and the fixture suite would then certify the drift rather than
catch it. The expensive version of this mistake is discovered after the Node half
exists; the cheap version is a decision recorded now.
**Why it must land before Phase 4 code.** Phase 4 ports a *frozen, explicit*
contract and uses the shared fixture suite as the cross-runtime conformance
oracle. Freezing that contract before v0.2 is supported means freezing a v0.1
shape into two runtimes instead of one, and the fixture suite would then certify
the drift rather than catch it. Worse, the Node half would need the same v0.2
work done twice, in two languages, against a contract that had already been
declared final. The expensive version of this mistake is discovered after the
Node half exists.
**Why it is not a phase.** v0.2's breaking surface is two supersessions, both
with documented consumer fallbacks, and every new field is optional. The only
measured shape problem is `DEFAULT`'s `generated` marker, which lives in commons'
ingest-spec §5 layer and is therefore not this repo's to change. So the work is
mostly *deciding and routing*, expressed through the Phase 3 profile object —
not a new implementation stage.
**Why it is not a phase of its own.** It adds no new door and no new stage — it
adds a *profile*, which is precisely what Phase 3 built the seam for. Support is
additive: `DEFAULT` (commons') and `STRICT_V1` (the wiki's) keep their contracts
untouched, and v0.2 arrives as a third profile plus an `OKF_LATEST` alias. This
is the first time the Phase 3 abstraction is forced by something outside this
repo rather than by a second consumer, which is the better test of it.
**Order inside the track.** Characterization and audit first (they add tests and
change no behavior, so they are safe while the central question is still open),
then the one blocking dependency — commons' answer on `generated` — and only then
any migration, as its own release.
**Order inside the track.** Characterization and audit first — they add tests and
change no behavior. Then the frontmatter model that can carry block lists
(`sources`, multi-verifier `verified`), then the profile, then the golden
fixtures that make the support claim testable. The `okf_version: "0.2"`
declaration comes last, once the shape has earned it. Commons' answer on
`DEFAULT`'s `generated` runs in parallel and no longer blocks: the additive
design took it off the critical path.
## Phase 4 — Node half (two clocks)