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
|
||||
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
|
||||
P4's work, not this session's.
|
||||
tests are emit-side. They are recorded here against GA exit criterion 1.
|
||||
|
||||
**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",
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
|
@ -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
|
||||
class:
|
||||
|
||||
- **Unquoted** is a property of **catalog's gate**, NOT of OKF v0.2. Their
|
||||
shape regex `/^\d+(\.\d+)*$/` reads the quotes as part of the value and
|
||||
exits 1. Upstream's §12:773 is the only line in the whole spec showing the
|
||||
key *with* a value, and it shows it **quoted** — so their gate rejects
|
||||
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.
|
||||
We emit unquoted, and A-E6 expects unquoted **of catalog's gate**.
|
||||
- **Unquoted** is not a property of OKF v0.2 either way. The expectation
|
||||
stands; its ORIGINAL REASON DID NOT SURVIVE 2026-07-31, and the reason is
|
||||
recorded here rather than quietly swapped because reading a stale rationale
|
||||
as current is this expectation's own defect class.
|
||||
|
||||
*What it said, and why that is now wrong.* It said unquoted was a property
|
||||
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
|
||||
marker invisible to their gate *while still exiting 0* — a failure that
|
||||
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.
|
||||
|
||||
**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
|
||||
block and in a body line alike — green measures the value, never the position.
|
||||
Catalog sharpened the other direction on 2026-07-31: moving the marker into
|
||||
frontmatter *with* quoting, as §12 literally shows it, also yields FAIL. So a
|
||||
red run cannot distinguish "wrong quoting" from "wrong placement". Read TEST B
|
||||
as a statement about the value's shape only, in both directions.
|
||||
identify it.** The reader is placement-blind: green measures the value, never
|
||||
the position. What changed on 2026-07-31 is only the REASON — it was an
|
||||
unanchored regex matching a frontmatter line and a body line alike; from 0.3
|
||||
it is a deliberate choice, reading frontmatter first and falling back to the
|
||||
body, reporting which form it found. Catalog's stated ground for not enforcing
|
||||
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
|
||||
block (the profile seam leaks); `at` differing from the `ingested_at` they passed
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue