docs(okf-v0.2): the F1 disposition, and A-E6's rationale after catalog 1ca27f6
Three corrections to the alignment plan, two of them because a fact a peer repo gave us stopped being true. **P1 dispositions.** F1 is fixed before the tag; the other five are not. The line is whether a finding bites in code the pilots will pin. F1 did. F2/F3 do not: measured, all three `TypePolicy.rejection` call sites hard-code `DEFAULT.types`, and both `DEFAULT` and `OKF_V0_2` set `allowed=None`, so the closed-set branch is unreachable in shipped code and fires only for a caller constructing `STRICT_V1` directly — which is what the sweep did. Dequoting in `TypePolicy` would repair a write path that never sees a quote, and would fix the meaning of a quote without a value model able to express one. F2/F3/F4 are one root cause and go to D1b; F5/F6 stay P4's. **A-E6's reason did not survive, though the expectation did.** It justified "unquoted" as a property of catalog's gate — their shape regex read quotes as part of the value and so rejected upstream's own §12:773 example. Catalog resolved that in `1ca27f6`: from spec 0.3 the value is unquoted before the form check and both forms pass. The expectation stands on a different ground now, supplied by commons the same day: `method-spec.md:90` parses frontmatter line-oriented, so a quote is a character in the value rather than syntax a parser removes, and upstream emits the same way. Recorded as a supersession rather than swapped silently — reading a stale rationale as current is this expectation's own defect class. **TEST B must name the reader revision.** `okf-check.mjs` changed in the same commit, and the reader's placement-blindness is now a deliberate choice rather than an unanchored regex. A report that does not say which revision it ran is not reproducible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JqCmfJ2ukpFXeFjfab8wvy
This commit is contained in:
parent
2c01e58259
commit
128109bef0
1 changed files with 67 additions and 15 deletions
|
|
@ -469,8 +469,24 @@ enumerates nothing.
|
||||||
|
|
||||||
Every finding below is on the **judge** path. None of them touches what the
|
Every finding below is on the **judge** path. None of them touches what the
|
||||||
library emits, so none of them blocks `v0.5.0a1`, P2 or P3: both remaining pilot
|
library emits, so none of them blocks `v0.5.0a1`, P2 or P3: both remaining pilot
|
||||||
tests are emit-side. They are recorded here against GA exit criterion 1 and are
|
tests are emit-side. They are recorded here against GA exit criterion 1.
|
||||||
P4's work, not this session's.
|
|
||||||
|
**Disposition, decided by the operator 2026-07-31: F1 is fixed before the tag,
|
||||||
|
the other five are not.** The line between them is whether the finding bites in
|
||||||
|
code the pilots will actually pin. F1 does — `IndexPolicy.violations` is public,
|
||||||
|
`OKF_V0_2` names the key, and the profile contradicted its own emitter. The
|
||||||
|
others do not: F2 and F3 need a value model the parser does not have (which is
|
||||||
|
D1b, already scheduled), and the surface where they would bite — a read path
|
||||||
|
built on `TypePolicy.allowed` — is not wired to any profile. Measured: all three
|
||||||
|
call sites (`manifest.py:202`, `inbox.py:105`, `inbox.py:245`) hard-code
|
||||||
|
`DEFAULT.types`, and both `DEFAULT` and `OKF_V0_2` set `allowed=None`, so the
|
||||||
|
closed-set branch is unreachable in shipped code and fires only for a caller
|
||||||
|
that constructs `STRICT_V1` and calls `rejection` directly — which is what this
|
||||||
|
sweep did. Patching `TypePolicy` to dequote would therefore add a repair to a
|
||||||
|
write path that never sees a quote, and would fix the meaning of a quote without
|
||||||
|
a value model able to express one — precisely what commons warns against for a
|
||||||
|
line-oriented format (`method-spec.md:90`). F2, F3 and F4 are one root cause and
|
||||||
|
go to D1b together; F5 and F6 stay P4's.
|
||||||
|
|
||||||
**P1-F1 — `root_frontmatter` conflates "permitted and ordered" with "required",
|
**P1-F1 — `root_frontmatter` conflates "permitted and ordered" with "required",
|
||||||
and the emitter and the judge disagree about the same key.** `IndexPolicy`
|
and the emitter and the judge disagree about the same key.** `IndexPolicy`
|
||||||
|
|
@ -485,6 +501,16 @@ correctly and grade it as a MUST. `STRICT_V1` is unaffected in substance — the
|
||||||
wiki emits all three of its pinned keys (measured) — but it is the same field
|
wiki emits all three of its pinned keys (measured) — but it is the same field
|
||||||
carrying two meanings, so the fix has to separate them rather than relax them.
|
carrying two meanings, so the fix has to separate them rather than relax them.
|
||||||
|
|
||||||
|
**FIXED before the tag.** `IndexPolicy` gained `root_frontmatter_required`:
|
||||||
|
`root_frontmatter` permits a key and fixes its position, the new field demands
|
||||||
|
it, and a required key outside the ordered set now fails at construction.
|
||||||
|
`OKF_V0_2` leaves it empty (upstream's MAY), `STRICT_V1` names all three
|
||||||
|
(unchanged behavior for the proving consumer), `DEFAULT` is untouched.
|
||||||
|
Re-measured over the eight bundle-root indexes reachable locally — our four
|
||||||
|
goldens and upstream's four: **7 of 8 failing under the old semantics, 0 of 8
|
||||||
|
after**, matching this finding's own numbers. The emit path is byte-identical;
|
||||||
|
the golden suite would have caught it otherwise.
|
||||||
|
|
||||||
**P1-F2 — `TypePolicy.allowed` cannot be used against a consumer that quotes its
|
**P1-F2 — `TypePolicy.allowed` cannot be used against a consumer that quotes its
|
||||||
scalars.** All **526/526** wiki documents are rejected as `okf_type_not_allowed`
|
scalars.** All **526/526** wiki documents are rejected as `okf_type_not_allowed`
|
||||||
under `STRICT_V1`; **526/526** are clean when values are dequoted before judging.
|
under `STRICT_V1`; **526/526** are clean when values are dequoted before judging.
|
||||||
|
|
@ -878,13 +904,29 @@ output is the baseline. Materialize it twice with the *same* explicit
|
||||||
must not conflate them** — doing so would be this expectation's own defect
|
must not conflate them** — doing so would be this expectation's own defect
|
||||||
class:
|
class:
|
||||||
|
|
||||||
- **Unquoted** is a property of **catalog's gate**, NOT of OKF v0.2. Their
|
- **Unquoted** is not a property of OKF v0.2 either way. The expectation
|
||||||
shape regex `/^\d+(\.\d+)*$/` reads the quotes as part of the value and
|
stands; its ORIGINAL REASON DID NOT SURVIVE 2026-07-31, and the reason is
|
||||||
exits 1. Upstream's §12:773 is the only line in the whole spec showing the
|
recorded here rather than quietly swapped because reading a stale rationale
|
||||||
key *with* a value, and it shows it **quoted** — so their gate rejects
|
as current is this expectation's own defect class.
|
||||||
upstream's own canonical example. That is catalog's defect to resolve, not
|
|
||||||
ours to work around, but while it stands, an unquoted value is what passes.
|
*What it said, and why that is now wrong.* It said unquoted was a property
|
||||||
We emit unquoted, and A-E6 expects unquoted **of catalog's gate**.
|
of **catalog's gate**: their shape regex `/^\d+(\.\d+)*$/` read the quotes
|
||||||
|
as part of the value and exited 1, which meant the gate rejected upstream's
|
||||||
|
§12:773 — the only line in the whole spec showing the key *with* a value,
|
||||||
|
and it shows it **quoted**. We called that catalog's defect to resolve, and
|
||||||
|
they resolved it: **from spec 0.3 (`1ca27f6`) the value is unquoted before
|
||||||
|
the form check, so `okf_version: 0.2` and `okf_version: "0.2"` both pass.**
|
||||||
|
"An unquoted value is what passes" is no longer a discriminating statement
|
||||||
|
about their gate.
|
||||||
|
|
||||||
|
*Why the expectation survives anyway.* Commons settled the same question
|
||||||
|
from the other side on 2026-07-31: `method-spec.md:90` (frozen since
|
||||||
|
`7d2b46c`) parses frontmatter line-oriented as `key: value` strings, so a
|
||||||
|
quote would be **a character in the value, not syntax a parser removes** —
|
||||||
|
there is no transparent quoting in the format at all. Upstream emits the
|
||||||
|
same way (`by: human:jsmith@acme`, colon in the value and no quotes). So we
|
||||||
|
emit unquoted because that is the format's own convention, not because a
|
||||||
|
consumer's gate would otherwise reject it.
|
||||||
- **BOM-free** is a property of the file we emit, full stop. A BOM makes the
|
- **BOM-free** is a property of the file we emit, full stop. A BOM makes the
|
||||||
marker invisible to their gate *while still exiting 0* — a failure that
|
marker invisible to their gate *while still exiting 0* — a failure that
|
||||||
reports success.
|
reports success.
|
||||||
|
|
@ -894,12 +936,22 @@ output is the baseline. Materialize it twice with the *same* explicit
|
||||||
sees it, so a parsed assertion masks precisely these two defects.
|
sees it, so a parsed assertion masks precisely these two defects.
|
||||||
|
|
||||||
**A green TEST B does not confirm the placement, and a red one does not
|
**A green TEST B does not confirm the placement, and a red one does not
|
||||||
identify it.** The shape regex is unanchored, so it matches in the frontmatter
|
identify it.** The reader is placement-blind: green measures the value, never
|
||||||
block and in a body line alike — green measures the value, never the position.
|
the position. What changed on 2026-07-31 is only the REASON — it was an
|
||||||
Catalog sharpened the other direction on 2026-07-31: moving the marker into
|
unanchored regex matching a frontmatter line and a body line alike; from 0.3
|
||||||
frontmatter *with* quoting, as §12 literally shows it, also yields FAIL. So a
|
it is a deliberate choice, reading frontmatter first and falling back to the
|
||||||
red run cannot distinguish "wrong quoting" from "wrong placement". Read TEST B
|
body, reporting which form it found. Catalog's stated ground for not enforcing
|
||||||
as a statement about the value's shape only, in both directions.
|
placement: `check-okf-parity` runs okr's LIVE checker, and enforcing before the
|
||||||
|
emitters have migrated would redden that gate without making a single bundle
|
||||||
|
more conformant. Read TEST B as a statement about the value's shape only, in
|
||||||
|
both directions. A red run still cannot separate "wrong quoting" from "wrong
|
||||||
|
placement" — but quoting is now the *less* likely of the two, since both forms
|
||||||
|
pass.
|
||||||
|
|
||||||
|
**TEST B must record the reader revision.** `okf-check.mjs` changed in
|
||||||
|
`1ca27f6`, and catalog invoked their standing promise to notify on any change
|
||||||
|
to it. A TEST B report that does not name the revision it ran is not
|
||||||
|
reproducible, whatever it says about the result.
|
||||||
|
|
||||||
**What would surprise us — report immediately:** any diff outside the frontmatter
|
**What would surprise us — report immediately:** any diff outside the frontmatter
|
||||||
block (the profile seam leaks); `at` differing from the `ingested_at` they passed
|
block (the profile seam leaks); `at` differing from the `ingested_at` they passed
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue