Define CP2 authorization-result qualification and public reasons (Phase A) - #31
Define CP2 authorization-result qualification and public reasons (Phase A)#31samovers wants to merge 3 commits into
Conversation
samovers
left a comment
There was a problem hiding this comment.
Verdict: request changes before Phase A approval
Reviewed exact head 18e426a42923aef1c18701f4ada14f1594af62a6 against canonical main 71ca724a8b6ec23f1655b086a6f549496d10a47f and the pinned candidate dependencies. The head was rechecked before posting and remains unchanged.
Posted as COMMENT because GitHub does not permit the connected PR-author account to submit a formal REQUEST_CHANGES review on its own PR. The review recommendation remains request changes.
One P2 semantic finding. This is a one-file, documentation-only Phase A candidate, not a runtime-defect finding or authorization to change active law.
P2 — Historical refusal responses cannot qualify corrections to their own source evidence
File: package_meta/history/clean_baseline_migration/phase_reports/cp2_authorization_result_surface_and_public_reason_codes_rfc_candidate_v0_1.md
Locations: §5.1, line 111; §5.2–5.3; §9, lines 265–269.
Section 5.1 unconditionally excludes disputeStatus and related qualifications on the grounds that they concern domain material rather than this protocol reply. The closed replacement shape has no equivalent source-history qualification. Section 9 nevertheless permits returning historical committed authorization evidence.
The missing case is a governed correction to the authorization evidence itself—not merely a later authorization decision under changed permissions. Pinned PR #11 §17.2 explicitly permits corrections and later failures as new linked evidence records while preserving the original authorization evidence. The accepted CP2 qualification RFC §§2–3 and 9 and Platform AAI-P.6–P.6.1 require material correction, dispute and supersession limitations to remain visible where applicable. They do not restrict that obligation to domain payloads.
Counterexample: an immutable DENY bundle is followed by a governed, linked correction materially qualifying its recorded basis. An authorized caller subsequently retrieves the original bundle. Its bytes, digest, commit, original outcome and timestamp can all remain verifiable, so the historical-refusal admission conditions still pass. But the proposed response has no typed field or permitted display variation that communicates the correction. Recorded result; not current permission. identifies historical scope; it does not identify corrected or disputed evidence.
The §9 safeguard against missing or untrustworthy source evidence does not fully resolve this: a valid historical record can accurately establish that a refusal occurred while also having a material subsequent correction. Preserving that historical fact and disclosing its qualification are separate obligations.
Smallest controlled patch: narrow the blanket exclusion in §5.1. For committed source evidence, require the producer to consume the owner's governed source-history qualification and preserve any material correction/dispute/supersession limitation through a conditional machine-readable status and safe display rule. Keep the original outcome and asOf unchanged. Where the qualification cannot be established or disclosed, represent that limitation—or explicitly exclude the lookup from this narrow profile—rather than silently treating it as unqualified history.
Add a case for authorized retrieval of an original refusal after a linked correction, plus a variant where correction details are permission-limited. Neither case should rewrite the original refusal, reveal protected correction details or create retry authority.
Classification: RFC extension and future conformance implication. No active-baseline amendment is needed; this enforces existing Platform and CP2 requirements. Keep the patch in this candidate. Do not invent correction authority, a new history store or changes to the pinned owner contracts.
Other reviewed decisions
No additional blocking issue was found in the distinction between committed refusals, ingress rejection, unavailable results and unconfirmed commits. The draft prevents prepared evidence from becoming a public durable-decision claim and keeps unresolved commits from implying safe retry.
The sixth code, AUTHORIZATION_RESULT_UNAVAILABLE, has a defined purpose without becoming another authorization outcome. Its typed responseKind distinguishes failure from uncertainty, while retry eligibility remains with the operation owner. The versioned branch also avoids silently inserting authorization responses into legacy query/read envelopes.
Verification and limits
All four GitHub check runs were observed passing for the reviewed head, covering repository validation and generated currentness. These checks do not establish semantic correctness or runtime disclosure behavior. The full repository suite was not rerun locally for this review. The candidate's 30 cases remain specifications, not executed privacy, transaction or runtime-conformance evidence.
Recommendation: close the source-history qualification gap, then re-review the amended exact head for Phase A semantic approval. This review grants no steward approval, merge authority, schema/currentness promotion, extraction or OFARM2 implementation authorization.
|
The document-only fix for the P2 source-history qualification finding is pushed at
All four cheap canonical repository checks passed again. Direct document, currentness/hash/pin, reused registry-schema, status/display coverage, traceability and one-file/whitespace checks also passed. These are static/document checks, not executed privacy, transaction or runtime tests. Primary trust boundary: public authorization-result qualification and diagnostic disclosure. Scope stayed within the same one-file Phase A candidate (430 lines total). No active contract, correction authority, history store, transaction/retention owner, runtime, approval or merge changed. What is next: re-review this amended exact head. The finding is proposed as addressed, not reviewer-cleared; Phase A semantic approval is still pending. |
samovers
left a comment
There was a problem hiding this comment.
Re-review verdict: no blocking findings
Reviewed exact head 34b0f1901ccaab95d92249b6b43968a8ce301df7 against the previously reviewed head 18e426a42923aef1c18701f4ada14f1594af62a6. The live head was rechecked before posting and remains unchanged. The PR remains draft and limited to one non-authoritative Phase A candidate document.
The P2 source-history qualification finding in the previous review is resolved. No additional blocking issue was found in the amended candidate.
Reviewed file: cp2_authorization_result_surface_and_public_reason_codes_rfc_candidate_v0_1.md.
Previous finding: closed
The missing qualification now has an explicit carrier. Sections 5.1–5.4 require sourceHistoryQualification for every COMMITTED_REFUSAL, in both CURRENT_ATTEMPT and RECORDED_RESULT modes. It is forbidden for other response kinds, avoiding fabricated source-history claims for ingress rejection or an unconfirmed result. The object reuses the existing CP2 dispute-status values rather than creating new correction semantics.
Unknown history cannot silently become NONE. That value requires an affirmative, complete owner determination at the governed observation point. An intact original digest, filtered search, stale cache, incomplete lookup, or deliberately old checkpoint cannot establish it. UNAVAILABLE instead carries null status/time and an explicit uncertainty message. This addresses the failure case rather than merely adding an optional field.
Restricted history does not create a correction-existence oracle. WITHHELD takes precedence when the reader cannot receive the history qualification, regardless of whether the producer knows its status or availability. When only correction details are restricted, the safely disclosable status remains visible with DETAILS_REDACTED. Where even the limited statement is not permitted, the historical lookup is excluded from this narrow profile rather than exposing the original outcome through a fallback.
The historical refusal remains historical. The original outcome and root asOf stay unchanged; the nested history asOf identifies the history-observation point, while qualifiedAt identifies the outward projection time. Required display sentences communicate corrections, disputes, supersession, and uncertainty without replacing the primary category. Section 9 distinguishes a governed correction from a later authorization decision caused merely by changed permissions.
The new case specifications cover the requested closure. C31–C36 include the original intact-DENY-plus-linked-correction counterexample, restricted details, withheld classification, stale or incomplete history, other governed statuses, wrong-source bindings, invalid conditional fields, and omitted display warnings. They also explicitly apply the qualification requirement to fresh committed refusals, not only historical lookups.
Regression check
The amendment preserves the six proposed registry entries, the distinction between unavailable results and unconfirmed commits, and the rule that public messages do not confer retry authority. It keeps correction classification with the evidence owner; the public projector does not acquire a correction writer, history store, or authority to recompute the original decision.
Verification and limits
All four GitHub check runs were observed passing for the reviewed SHA, covering repository-validation and generated-currentness. Those results were inspected; the repository suite was not rerun locally during this re-review.
The 36 cases remain specifications, not executed privacy or runtime-conformance tests. Later contract and adapter checks must still prove that source-history completeness, observation-point validity, disclosure precedence, and display bindings are enforced—not merely that the envelope validates as JSON. Those obligations are explicitly retained in section 11.
Recommendation: proceed to exact-head Phase A steward semantic approval. No further patch is requested by this review.
This is reviewer clearance of the candidate, not steward semantic approval, merge authorization, schema/currentness promotion, extraction, or OFARM2 implementation authorization. Posted as a review comment; no approval or PR state change is requested.
samovers
left a comment
There was a problem hiding this comment.
Third review, second at head 34b0f1901ccaab95d92249b6b43968a8ce301df7
Disposition: one blocking finding, three should-fix, two minor. I do not concur with the previous review's clearance.
This is an independent pass at the same exact head the second review cleared. I re-extracted the file from refs/pull/31/head, re-derived every digest, enum and mapping from the pinned blobs, and diffed the amendment rather than reading only what it added. The live head was 34b0f19 when I started and when I finished; the PR is open, draft, one file, 430 lines, and the amending commit is 64 insertions(+), 16 deletions(-).
The blocking finding is a regression introduced by the fix for the first review's P2, and it is invisible if you only read what the amendment added. The previous review checked the new §5.4 object thoroughly and did not check what the amendment deleted from §5.1.
Blocker — the amendment removed the only rule governing root disputeStatus, and the branch no longer says whether it may appear
File: package_meta/history/clean_baseline_migration/phase_reports/cp2_authorization_result_surface_and_public_reason_codes_rfc_candidate_v0_1.md
Locations: §5.1 lines 96 and 113; §5.4 lines 142-156; §6 lines 178-187.
At the previously reviewed head 18e426a, §5.1 said:
The authorization branch does not carry
twinScope,authorityLevel,candidateStatus,disputeStatus,stalenessClass,evidenceSufficiency, source/domain result references, or domain promotion fields. […] Filling them with NONE, FRESH, SUFFICIENT or NOT_EVALUATED could invent facts.
At the current head that sentence reads:
The authorization branch does not carry the domain-material fields
twinScope,authorityLevel,candidateStatus,stalenessClass,evidenceSufficiency, source/domain result references, or domain promotion fields. Filling inapplicable fields with FRESH, SUFFICIENT or NOT_EVALUATED could invent facts. This exclusion does not apply to material qualifications of the authorization evidence itself: the conditionalsourceHistoryQualificationbelow reuses CP2's existingdisputeStatusmeanings for that evidence.
Two things were removed and not replaced: disputeStatus from the exclusion list, and NONE from the forbidden fill values. The carve-out that replaced them licenses the nested object only. Root disputeStatus now has no disposition anywhere in the document.
I checked this mechanically rather than by impression. The v0.1 carrier at pinned main 71ca724 declares 26 properties. At the current head every one of them has an explicit disposition in the authorization branch except one:
| Disposition in the branch | Properties | Where stated |
|---|---|---|
Required (13 of the 26, plus the new authorizationResponse) |
schemaVersion, qualificationId, qualifiedAt, asOf, surfaceClass, truthPosture, permissionClass, dataAbsentReason, highConsequenceUseAllowed, allowedUseClasses, blockedUseClasses, traceRefs, displayHints |
§5.1 line 96 |
| Explicitly excluded | twinScope, authorityLevel, candidateStatus, stalenessClass, evidenceSufficiency; derivedFromPromotionPoint, materializationResultRef, queryExecutionResultRef, outputAssemblyResultRef ("source/domain result references, or domain promotion fields"); notes (§5.1 line 96); sourceRefs, redactions (§7.1 line 210) |
§5.1, §7.1 |
| No rule at all | disputeStatus |
— |
$ git cat-file -p 71ca724:03_machine_contracts/schemas/runtime_surface/OFARM_ResultQualificationEnvelope_schema_v0_1.json
top required: [... 'candidateStatus', 'disputeStatus', 'stalenessClass', ...] # 19 required
disputeStatus => {"enum": ["NONE","OPEN_DISPUTE","DISPUTED_BASIS","CORRECTED","SUPERSEDED","MIXED"]}
additionalProperties: False
$ git cat-file -p pr31:<candidate> | grep -n disputeStatus
113: … reuses CP2's existing `disputeStatus` meanings for that evidence. # nested only
123: … conditional existing CP2 disputeStatus # nested only
142: `sourceHistoryQualification` has exactly three required fields: `availability`, `asOf`, and `disputeStatus`.
144: | availability | asOf | disputeStatus | Required source and meaning |
150: AVAILABLE reuses the exact enum at `ResultQualificationEnvelope v0.1`'s `properties.disputeStatus`
406: … reuse the exact existing disputeStatus enum
Why this is blocking rather than editorial. disputeStatus is required in v0.1 and remains required in the six legacy branches under §4 line 88 ("The six legacy surface branches retain their existing fields, enums and requiredness in v0.2"). It is also required in the resultQualification definition embedded in PublicReadModelEnvelope_schema_v0_1.json. So a v0.2 materializer has a live, non-hypothetical question — required, optional, or forbidden in the authorization branch? — and the candidate's answer at 18e426a was "forbidden, and specifically do not write NONE into it". That answer was deleted. If a producer now emits root disputeStatus, it does so with none of §5.4's discipline: no availability, no observation point, no WITHHELD precedence, and no required display sentence, because the §6 table at lines 178-187 keys entirely on sourceHistoryQualification. A root disputeStatus: CORRECTED would carry a correction claim with no sentence; a root disputeStatus: NONE — the exact value the deleted sentence forbade — would assert unqualified history to a reader whom §5.4 line 154 requires to be given WITHHELD. That is the correction-existence oracle the amendment was written to close, reachable through the field the amendment stopped governing. problems, traceStatus and every other slot got a rule; this one lost the one it had.
Counter-argument, stated because the call is close. §5.1 line 92 says "The authorization branch is closed" and line 96 says "Do not permit arbitrary extension objects", so a reader may argue an unlisted property is thereby forbidden. I do not think that survives contact with the document's own method: "closed" in JSON Schema terms means additionalProperties: false, which constrains undeclared properties and says nothing about a declared optional one; and if "closed" were sufficient, §5.1 line 113 and §7.1 line 210 would not need to enumerate exclusions for twinScope, notes, sourceRefs and redactions at all. The document enumerates because it does not rely on that inference. One property now falls outside the enumeration.
Smallest controlled patch. Restore the root-level rule in §5.1 in a form that survives the new carve-out — for example: the authorization branch does not carry root disputeStatus; the evidence's material history qualification is carried only by the conditional sourceHistoryQualification in §5.4, and root disputeStatus must not be emitted, including as NONE. Then add the hostile variant to §10 (root disputeStatus present on an authorization reply, alone or alongside a conflicting nested value → reject), and extend C36's "inconsistent null/status/time" clause to name the root field. No new authority, owner or carrier is needed; this restores a deleted sentence and tests it.
Should fix — the WITHHELD precedence rule is guarded, but the lookup-exclusion fallback beneath it is not
Locations: §5.4 line 156; §9 line 301; §10 case C33.
§5.4 line 154 closes the obvious oracle well, and I want to be explicit that it does so correctly: WITHHELD applies whenever the reader may not receive the observation, "regardless of whether the producer knows its status or availability". That phrasing is what makes the field uniform across readers, and it is the strongest sentence in the amendment.
Line 156 then opens a second path that carries no equivalent requirement:
A reply may retain the independently verified original refusal with this explicit limitation only if its governing disclosure policy permits both the original category and that limited statement. Otherwise exclude the historical lookup from this narrow profile and use the governing lookup's permitted qualified failure.
Whether the caller receives a RECORDED_RESULT at all now depends on a disclosure policy over "that limited statement". Nothing requires that policy to be independent of the record's actual history state. A deployment that permits the limited statement for records with no qualification and withholds it for corrected ones produces exactly the discrimination the field-level rule forbids, one level up: same reader, same original refusal, and the presence of the lookup becomes the oracle. C33 tests that a non-disclosable qualification yields WITHHELD rather than NONE, and that the lookup is excluded when even the limited statement is not permitted — but no case pairs two records to test that the exclusion decision does not vary with their history.
The document already applies this discipline elsewhere and that is why I think it belongs here: §7.1 line 208 forbids selecting TENANT_BOUNDARY_BLOCKED "merely because an internal check found a foreign tenant", and C11 tests that hidden, foreign and inaccessible targets produce the same permitted category. The amendment did not extend that pattern to its own new branch point.
Smallest patch. In §5.4, require the exclusion decision to be determined by reader and record-class policy that does not depend on the presence or value of the source-history qualification. Add one hostile case: two authorized historical lookups by the same reader, one record carrying a governed correction and one not, must produce indistinguishable replies wherever the qualification itself is not disclosable.
Should fix — no pinned or governing source creates the owner obligation §5.4 consumes
Locations: §2 line 37 (new responsibility row); §5.3 line 136; §5.4 lines 146-150; §11 line 406.
§5.4 requires the producer to consume "the owner's governed source-history qualification": exactly one of six CP2 values, valid at a "governed history observation point", with NONE requiring "the owner's affirmative, complete determination". §5.1 and §5.4 forbid the projector from deriving any of it. §2's new row assigns it to "Existing evidence governance and pinned PR #11 section 17.2".
I read §17.2 at the pinned head 03a21f6. It says, in full, on this point:
Governed authorization evidence is immutable and append-only. A correction or later failure is a new linked evidence record and never rewrites the earlier request, decision, approval, consumption, effect/read/outbox, or transport claim. These records support authorization-decision reconstruction and audit read models only […]
That establishes that corrections exist as linked records — which is what the first review's P2 correctly relied on. It does not establish a classifier, a vocabulary, an observation point, or any duty to answer "what is the applicable qualification for this evidence as of time T". PR #11 has no disputeStatus, no CORRECTED/SUPERSEDED/MIXED for authorization evidence, and no interface producing one.
Nor does anything else. disputeStatus appears nowhere in 00_active_baseline/ or 02_accepted_rfcs/ at 71ca724:
$ git grep -c disputeStatus 71ca724 -- 00_active_baseline 02_accepted_rfcs
(no matches)
$ git grep -l disputeStatus 71ca724 -- | head
03_machine_contracts/schemas/runtime_surface/OFARM_PublicReadModelEnvelope_schema_v0_1.json
03_machine_contracts/schemas/runtime_surface/OFARM_ResultQualificationEnvelope_schema_v0_1.json
… (fixtures and examples only)
The enum in the schema carries no description. The accepted CP2 RFC lists "dispute/correction/supersession status" among what a qualification "must expose, where applicable" (line 27) and requires that a result not be shown as complete truth when it reports "disputed, corrected, superseded" posture (line 42) — an obligation, which is why the first review's P2 was right — but no value semantics and no producer. So §5.1's "reuses CP2's existing disputeStatus meanings" reuses an enum whose meanings are not defined in governed text; only the six labels are.
The consequence is concrete rather than theoretical. Under §5.4, a producer built on exactly the four pinned candidates cannot obtain a trustworthy owner determination, and §5.4 forbids every substitute — "An intact original digest, empty visible search, filtered history, stale cache or incomplete lookup cannot establish NONE", and C34 rejects the forged NONE explicitly. The only honest value left is UNAVAILABLE. §5.4 line 156 then requires the §6 sentence, and §10 line 373 extends the requirement to fresh attempts: "All positive COMMITTED_REFUSAL cases, including CURRENT_ATTEMPT cases C01-C04, require the owner's source-history qualification […] a fresh commit does not waive that field." So the specified default public message on every authorization denial, including one whose evidence committed a second earlier, is:
This request was denied. Source-history qualification could not be established.
That is a worse public surface than the one the P2 fix was protecting, and it is what a conforming first implementation produces. The alternative outcomes are worse still: a producer under delivery pressure derives the classification itself (forbidden by §5.4) or reports NONE from an empty lookup (rejected by C34).
I do not think this is a reason to withdraw the amendment — the obligation in AAI-C.1.1 and the accepted CP2 RFC is real and the first review's P2 was correct. It is a reason not to approve §1 decision 7 as though the owner side already exists.
Smallest patch. In §11's cross-binding list, name the owner-side obligation this candidate creates as an explicit prerequisite rather than an assumption: PR #11 (or its successor) must define, for authorization evidence, the qualification vocabulary, who classifies, and what a governed observation point is. And settle one sentence in §5.4 that decides most real traffic: whether the owner's determination at the moment of the refusal commit — where no linked record can yet exist — is an affirmative complete determination establishing NONE, or is UNAVAILABLE. As written, CURRENT_ATTEMPT refusals are the common case and the document does not say.
Should fix — C01-C04 contradict §5.2 and §10 line 373, and §11 turns them into fixtures
Locations: §10 cases C01-C04 and line 373; §11 line 398.
§5.2 makes sourceHistoryQualification required for COMMITTED_REFUSAL in either reply mode. C01-C04 are the four positive committed-refusal cases and their "Required observation" columns do not mention it:
| CP2A-C01 | Verified current DENY bundle | COMMITTED_REFUSAL / DENY / AUTHORIZATION_DENIED; no positive-use permission | I02, I03, I05 |
Line 373 patches this in prose after the table. That is enough for a human reader and not enough for §11, which requires "One named CP2A-Cnn.json fixture per applicable positive case": a fixture built from C01's stated required observation is invalid under §5.2, and C36 exists precisely to reject it. The case table is the test specification; it should not need a footnote to be correct. Also add I06 to C01-C04's invariant column, since the field is now part of what those cases prove.
Preference — the sixth code's fixed remediation asserts a pending confirmation that the RESULT_UNAVAILABLE row does not have
Locations: §6 lines 166-167; §8 AUTHORIZATION_RESULT_UNAVAILABLE.
One code serves two rows. Its requiredRemediation is fixed: "Use an authorized status or support workflow where available. Do not resubmit while confirmation is pending; later retry eligibility belongs to the operation owner." C07's entry condition is "Conclusive persistence failure, relevant commit facts settled" — nothing is pending there, and the same sentence is already carried separately for the row that does have something pending (§6 line 176's fixed COMMIT_UNCONFIRMED sentence). By the candidate's own standard — "If the producer cannot truthfully choose a row, it cannot manufacture a durable result" — the remediation should not describe a state the row excludes. Either drop the clause from the registry entry and let §6's fixed sentence carry it, or make the remediation conditional on responseKind and say so in §8.
I am not asking for a seventh code; the one-code-plus-responseKind choice in §8 line 293 is well argued and I concur with it.
Follow-up — sourceHistoryQualification.disputeStatus cannot literally reuse the v0.1 enum
Locations: §5.4 lines 142-150; §11 line 406.
The nested object has "exactly three required fields" and disputeStatus is JSON null under UNAVAILABLE and WITHHELD. §5.4 line 150 and §11 line 406 both instruct the materializer to "reuse the exact existing disputeStatus enum", which contains no null. A materializer following that literally produces a schema that cannot validate two of its own three availability rows. One clause in §11 — reuse the enum as the non-null branch of a nullable type — removes the ambiguity before it reaches a draft schema.
What I verified and found correct
Reproduced from the pinned blobs, not from the prose. Recording it so the next pass does not re-spend it.
-
The four dependency pins are clean, including against their own review history. This is the check that produced a Blocker on issue #25, so I ran it fully. Every pinned SHA equals the live head and equals the commit of the newest review on that PR, and each of those reviews reads "ready for exact-head steward semantic approval" (#29: "No blocking findings for Phase A at head
8e0994c"). No pin is ahead of its last review.Dependency Pinned in §3 Live head Newest review commit Last review disposition PR #11 03a21f603a21f603a21f6(5087264297)ready for exact-head approval PR #20 98f8c4f98f8c4f98f8c4f(5099749737)ready for exact-head approval PR #26 e042efae042efae042efa(5125732836)ready for exact-head approval PR #29 8e0994c8e0994c8e0994c(5134001116)no blocking findings All four are open,
draft: true,merged: false, as §3 claims. PR #11's last review warns that "Any dependent artifact still pinned to the superseded5974bb9authorization semantics must refresh its exact-head dependency" — this candidate pins the post-5974bb9head, correctly. §9 line 318's carve-out of PR #29's open schedule-resolution clarification matches that review's actual non-blocking remainder; the candidate is not quietly absorbing another PR's open item. -
The three SHA-256 anchors in §4 are exact.
a6fa2ac6029b01aa5536d563dab099e8adc224e696bfd468e9bd0ab90b5eeb52 ResultQualificationEnvelope v0.1 62191e9a983b5cb60468404c4c26b0e4ad7ec6298902f2c497caeea6850b57c3 RuntimeProblemReasonCodeRegistry v0.1 873dbeda2932d48a54e5d08d22f4031c6a86b44712a3cec85f1c1008f4d6e95b RuntimeProblem v0.1 -
Every enum the candidate constrains exists with the values it names.
surfaceClasshas exactly the six legacy values;truthPosturecontainsCANONICAL_HISTORY_DIRECTandUNKNOWN_OR_MIXED;permissionClassanddataAbsentReasoncontain all five and five values used in §7.1; the seven use-classes make §5.1's "exact complement" well-defined;disputeStatusis exactlyNONE, OPEN_DISPUTE, DISPUTED_BASIS, CORRECTED, SUPERSEDED, MIXED, matching §5.4 line 146 in order and spelling;displayHintsrequires exactlysafeLabel,userMessage,forbiddenLabelswith optionalnextActionLabel, matching §5.1 line 109.TraceRetrievalResult.statusis exactly the five values §4 line 71 names, so §7.2's claim that it "has no general storage-unavailable or integrity-failure status" is true and the two added values are genuinely new. -
§5.2 line 132's RuntimeProblem claim is exactly right, and it is the sort of claim usually asserted without checking. The
runtimeProblemdefinition embedded inPublicReadModelEnvelope_schema_v0_1.jsondiffers from coreRuntimeProblem_schema_v0_1.jsonin precisely one respect:problemIdis^[A-Za-z0-9._:/#-]+$there versus^[A-Za-z0-9._:-]+$in core. The embedded variant admits/and#in an opaque public identifier — path and fragment shapes — so importing the core definition is materially safer, not merely tidier. §4 line 86's companion claim also holds: the embeddedresultQualificationpinsschemaVersionto the v0.1 const withadditionalProperties: false, so a legacyPublicReadModelEnvelopestructurally cannot embed the new branch. -
The six registry entries are complete against the registry schema. All ten required entry fields are supplied (four in the §8 table, three shared above it, four per code below it). All six codes match
^[A-Z0-9_:-]+$.AUTHORITY,OTHERandPERMISSION_REDACTIONare real family values;INFO/WARNING/ERRORare the real severities;AUTHORIZATIONis a realrelatedTraceTypesvalue. -
§4's inventory claims are true at
71ca724. All seven named families reportdraftNonDefaultCount: 0with a v0.1currentDefaultSchemainCONTRACT_FAMILY_CURRENTNESS.json. The CP2 core registry example contains exactlyEVIDENCE_INSUFFICIENT,MATERIALIZATION_STALE,PERMISSION_REDACTEDwithstatus: ACTIVE, and the accepted registry RFC's Authority row listsAUTHORITY_DENIEDandHUMAN_APPROVAL_REQUIRED— so §4 line 84's near-synonym warning, and C16, are grounded in real spellings that a producer could plausibly substitute. -
PR #11 §18.7's five mappings are reproduced verbatim, in the same order, including the
HUMAN_ACTION_REQUIREDspelling that differs from the accepted RFC'sHUMAN_APPROVAL_REQUIRED. -
The markdown is mechanically sound. Sixteen tables; none ragged (uniform pipe counts per table); no blank line inside any table. The one blank line my scanner flagged, at line 333, separates the invariant table from the case table and is correct — GitHub renders both. This matters because a blank line inside a table silently drops every row after it, which is how thirteen rows went missing on issue #25.
-
Traceability closes. 36 cases defined
CP2A-C01-C36with no gaps; all 36 are cited across the nine criterion rows; seven invariants defined and all seven cited. The document's own count of "36 cases" and "seven invariants" is accurate, as are "430 lines" and the one-file boundary. -
All four check runs pass at the reviewed head (
repository-validation×2,generated-currentness×2, allsuccess, completed 2026-09-07T18:17Z). As §12 concedes, several checks exclude the historical candidate lane, so this establishes package hygiene only.
Checked and decided were not findings
-
traceStatus: NOT_APPLICABLErestricted toINGRESS_REJECTION(§7.2 line 216). ARESULT_UNAVAILABLEcaused by a failure before any authorization decision has no applicable decision trace either, so the honest value is unavailable to it and it must useNOT_REQUESTED. I decided this is a feature:NOT_REQUESTEDis still literally true ("this projection did not perform or receive an authorized trace observation"), and forcing one value across both pre- and post-decision failures denies a caller the ability to infer how far the request got. Distinguishing them would leak; collapsing them does not lie. -
One code for two response kinds.
AUTHORIZATION_RESULT_UNAVAILABLEserves bothRESULT_UNAVAILABLEandCOMMIT_UNCONFIRMED, so a registry-driven consumer reading onlyreasonCodecollapses the distinction. §8'ssafeUiBehaviorrequires readingresponseKind, §6 gives the two rows different fixed titles, and §8 line 293's argument against inventing two decision types is sound. Not a finding; the remediation-text wobble above is the only residue. -
Challenge display has no slot in the closed member. PR #11 §18.7 pairs
HUMAN_ACTION_REQUIREDwith "only the safe challenge display/ref allowed by its display policy", and §5.2's closed member has no field that could carry or link one (traceRefsis trace-only;recordedResultRefisRECORDED_RESULT-only). §8 line 295 assigns it to "their existing human-action display carrier" and PR #11 says "return or link", so this is a scoping choice rather than a contradiction, and §11 line 406 already routes PR #20's display rules into cross-binding review. Worth naming that carrier during materialization; not a Phase A finding. -
humanReviewRequired: falseonHUMAN_ACTION_REQUIREDreads wrong at a glance and is defended correctly at §8 line 249; C02 and C03 pin both sides. -
allowedUseClassestightening. §5.1 requires a non-empty unique subset; v0.1 declares neitherminItemsnoruniqueItems. Tightening in a branch profile is legitimate and stated, and §11's profile unit is where it materializes. -
Root
asOfversus nestedasOfversusqualifiedAt(§5.4 line 152). Three times, three meanings, each assigned. I tried to construct a case where the nested observation point could be passed off as the original decision time and could not; the sentence is tight.
What my method made easier than production
- Nothing was executed. No envelope was built, no fixture validated, no adapter exercised. My finding that "the only honest value is
UNAVAILABLE" is derived from reading the pinned owner contracts, not from an implementation attempt; if an owner interface I could not see already supplies the qualification, that finding weakens to a documentation gap. I would rather be told that than have it assumed. - I read prose, not a schema. The v0.2 branch does not exist. My Blocker is about what a materializer would be entitled to write; a draft schema could resolve it in either direction, and the point is that the document no longer says which.
- I checked pins against review bodies, not against a governance record. "Ready for exact-head steward semantic approval" is a sentence in a review comment, not an approval object. GitHub refuses
APPROVEfrom the PR author, so state isCOMMENTEDthroughout and I read dispositions from prose. - The oracle findings are analytical. I did not run two lookups against a real disclosure policy; I read §5.4 line 156 and asked what an implementer is permitted to condition on. A deployment with a uniform record-class policy is unaffected — the point is that the candidate does not require one.
- Digests prove bytes, not meaning. Every hash in §4 matched, which tells you the anchors are honest and nothing about whether the branch is safe.
Standing and independence
Both prior reviews on this PR, and every review on the four pinned dependencies, were submitted by samovers — the author of all of them. GitHub refuses APPROVE and REQUEST_CHANGES from a PR author, which is why they are all COMMENTED. This pass is also delivered through that account. If §11 gate 1 or issue #30 contemplates independent review, none of these reviews satisfies it, and the sequence "first review found P2 → author fixed → second review cleared" should not be read as two parties agreeing. The Blocker above is a case in point: it exists because the fix was reviewed by reading its additions.
Recommendation: restore the root disputeStatus rule and re-review that head before Phase A semantic approval. The three should-fix items are cheap and belong in the same patch. This review grants no steward approval, merge authority, admission or currentness promotion, extraction, or OFARM2 implementation authorization.
|
Published the document-only response to the third review at
All four cheap canonical repository checks passed again. Direct checks verified all 26 legacy root properties' disposition, 16 tables, 39 unique cases cited across nine criteria, seven invariants, source/currentness/hash pins, nullable/display rules and six registry entries against the existing schema. The only registry-entry change is the intended remediation string. Whitespace and one-file scope checks passed. These are static/document checks, not executed privacy, transaction or runtime conformance. Primary trust boundary: public authorization-result qualification and diagnostic disclosure. Scope stayed within the one-file Phase A candidate, now 466 lines. No owner contract, correction authority, history store, new issue, active contract, runtime, approval, merge or extraction changed. What is next: re-review this exact head. The fixes are proposed for clearance, not already cleared or approved. CP2A-DEP01 remains an explicit owner dependency before complete binding or runtime claims. |
samovers
left a comment
There was a problem hiding this comment.
Re-review verdict: no further blocking findings for Phase A
Reviewed exact head 092be94f3a67497ba619295932cd0b2b1e9443f3, including the amendment from 34b0f1901ccaab95d92249b6b43968a8ce301df7 and the third review's objections. The live head was rechecked before posting and remains unchanged. The PR is still draft and changes one non-authoritative candidate document only.
Reviewed file: cp2_authorization_result_surface_and_public_reason_codes_rfc_candidate_v0_1.md.
The public-response corrections are sufficient for exact-head Phase A semantic approval. CP2A-DEP01 remains an open prerequisite—not a resolved contract—and must block complete binding, acceptance/admission, and runtime capability claims. The revised candidate now makes that distinction explicit.
My earlier clearance of 34b0f190 was too broad: it missed the root-field ambiguity and did not identify the missing source-history producer contract clearly enough.
Findings disposition
Root disputeStatus ambiguity — resolved
Section 5.1 now specifies the complete allowed root-property set, rather than merely listing required fields. It explicitly forbids root /disputeStatus for every value, including NONE, whether it agrees or conflicts with the nested qualification. History status has exactly one permitted location under authorizationResponse/sourceHistoryQualification. The six legacy surface branches retain their existing rules.
The property partition was cross-checked against the pinned v0.1 schema: 26 existing properties, 13 reused and 13 forbidden, with no overlap or unclassified property. authorizationResponse is the sole new root property. C36–C37 explicitly require rejection of the previously ambiguous root-field variants.
Hidden-history leakage through lookup exclusion — resolved at the design level
The new rule covers both returning a limited historical result and excluding the lookup. Neither decision may depend on hidden correction history, including indirectly through a history-derived record class or policy branch. For equivalent readable records, changing only undisclosable history must not change the outward category, withholding posture, display, hints, or reference exposure.
C38 pairs corrected and uncorrected records under both policy paths. That tests the missing distinction: protecting the nested field alone is insufficient when the decision to return a result can reveal the same information.
Assumed source-history producer — explicitly deferred, not implemented
Section 11.1 separates what the existing sources establish—immutable evidence, linked corrections, and CP2 qualification requirements—from what they do not establish: the classifier, its authority, its input/output contract, and its completeness and observation-point rules. Those missing obligations now belong to CP2A-DEP01.
The current-attempt behavior is also bounded: a fresh refusal commit alone cannot establish NONE. A valid owner determination is required. Otherwise, an appropriately qualified UNAVAILABLE or WITHHELD reply may be permissible, but neither a synthetic fixture nor an implementation that always returns UNAVAILABLE can satisfy the missing producer dependency. Whether a commit-time determination can establish complete history remains with the separately governed owner contract.
This is an acceptable boundary for Phase A public-design approval, not closure of the executable contract.
Fixture, nullability, and remediation corrections — resolved
C01–C04 explicitly require the owner determination, nested qualification, and I06 coverage. C39 distinguishes a temporarily unavailable determination from an absent or unadmitted producer contract. The conditional shape is unambiguous: AVAILABLE requires a non-null existing status and date-time; UNAVAILABLE and WITHHELD require null status and time.
The revised shared remediation no longer implies a pending commit for every AUTHORIZATION_RESULT_UNAVAILABLE response. The explicit do-not-resubmit warning remains mandatory for COMMIT_UNCONFIRMED, and the public codes still confer no retry authority. No regression was found in that change.
Validation and limits
The latest repository-validation and generated-currentness checks were observed passing for the reviewed SHA. Those results were inspected, and the root-property consistency check was performed. The repository suite and the author's registry-validation checks were not rerun locally during this re-review.
The 39 cases are specifications, not executed runtime or privacy tests. In particular, C38 still requires a real producer/adapter test proving that hidden history does not affect either outward response path.
Recommendation: proceed to exact-head Phase A steward semantic approval, explicitly retaining CP2A-DEP01 as open. No additional patch is requested within this PR's public-response boundary.
This is reviewer clearance of the bounded public design, not steward semantic approval, merge authorization, contract/currentness promotion, extraction, or OFARM2 implementation authorization. Posted as a review comment; no approval or PR state change is requested.
Phase A semantic approval recorded — 2026-09-10The user replied “approved” in the implementation task immediately after the exact-head review summary requested Phase A approval of this version while keeping CP2A-DEP01 open. This comment records that user decision; it is not an approval independently granted by the AI or a formal GitHub APPROVE review.
The approval covers the public-design choices in section 1 of those exact candidate bytes: the closed authorization-result branch, public code and qualification meanings, truthful commit/source distinctions, safe disclosure and retry limits, and the conditional source-history qualification. The primary trust boundary is public authorization-result qualification and diagnostic information disclosure. Scope stays within that boundary. CP2A-DEP01 remains OPEN. The authorization-evidence owner's classifier, producer authority, observation/completeness rules and exact producer bindings are not supplied or approved by this decision. That separate dependency continues to block complete binding, acceptance/admission and runtime capability claims. Neither a fresh commit alone nor synthetic fixtures or permanently UNAVAILABLE replies can close it. This is Phase A semantic approval only. It does not authorize a merge, active-law or current/default promotion, contract materialization, extraction, implementation, a new prerequisite issue, or changes to another owner's authority or transaction protocol. Issue #30 and the existing #21 and OFARM2 implementation gates are not closed by this record. The 39 cases remain specifications, not executed runtime/privacy evidence. The live PR head was verified before recording this decision. The reviewed candidate bytes are left unchanged; its in-file “approval pending” text describes the draft at that commit, while this later record supplies the user approval. The PR remains open, draft and unmerged. What is next: obtain direction for the separate CP2A-DEP01 producer-contract work before complete contract binding, acceptance/admission or runtime claims. Later public-contract materialization also requires its own authorization. |
Purpose
Refs #30; child of #10 and adjacent-contract prerequisite of #21.
This is one non-authoritative Phase A candidate, not active law or an implementation. Following exact-head review, the user approved the bounded Phase A design on 2026-09-10; the approval is recorded at
092be94f3a67497ba619295932cd0b2b1e9443f3. CP2A-DEP01 remains open. Merge, materialization, admission/currentness, extraction and implementation are not authorized by that approval.Trust boundary and scope
Primary trust boundary: public authorization-result qualification and diagnostic information disclosure.
The PR changes only
package_meta/history/clean_baseline_migration/phase_reports/cp2_authorization_result_surface_and_public_reason_codes_rfc_candidate_v0_1.md(466 lines). Scope stayed within that boundary. No active contract, other candidate, authorization rule, transaction protocol, retention/custody mechanism, public endpoint or OFARM2 runtime changed.Phase A-approved design choices (not admitted contracts)
The 10 September re-review found no further blocking Phase A findings at the exact current head and requested no additional patch within the public-response boundary. The separate producer dependency remains open.
Exact source pins
Canonical main:
71ca724a8b6ec23f1655b086a6f549496d10a47f.03a21f669ee04f96d444e14f00ae7212cab0480398f8c4fafbae42c8f7fd931f43f53adcb4733713e042efa2911b2ef0a61603b8e0adaa6911c03ac08e0994cae5610ac9c0d2652e02c8a8a2dd7b45c5At the last dependency check for the amendment, live heads matched and all four were draft and unmerged. That dependency status was not re-audited when recording this approval. Their Phase A status does not make them accepted law. No dependency files are copied into this PR.
Verification
Passed locally:
validate_repo_hygiene.pycheck_generated_currentness.pycheck_repository_cross_references.py(read-only; no --write)check_repository_steward_guardrails.pySeveral package checks exclude the historical candidate lane. These results establish document/package consistency, not semantic correctness, real privacy enforcement, atomic persistence or runtime conformance. The 39 cases are specifications, not executed runtime evidence.
Approval and delivery limits
Phase A-approved decision:
OFARM-ISSUE30-CP2-AUTHORIZATION-RESULT-PUBLIC-REASONS-001, version1.Initial reviewed head:
18e426a42923aef1c18701f4ada14f1594af62a6. Reviewed and approved head:092be94f3a67497ba619295932cd0b2b1e9443f3. The user replied “approved” after the exact-head review summary requested Phase A approval with CP2A-DEP01 retained as open. The dated approval record applies only to the section 1 public-design choices in those exact bytes; it does not authorize merge, materialization, acceptance/admission/currentness, extraction, implementation or a new owner issue/contract.CP2A-DEP01 remains an open prerequisite for complete binding, acceptance/admission and runtime capability claims. The reviewed document is deliberately unchanged, including its in-file pre-approval status; this later approval record supplies the decision without moving the reviewed head. The PR remains open, draft and unmerged.
The remaining #21, domain-effect and OFARM2 #353/#359 and #178 gates are unchanged. This PR does not close #30 merely by publishing a design.
Earlier review fix at 34b0f19
The first review identified one P2 source-history qualification gap. The document-only patch adds a closed conditional sourceHistoryQualification object, reuses the six existing CP2 disputeStatus values, and distinguishes unavailable qualification from withheld qualification. Required safe messages preserve the original refusal while disclosing material limits without correction IDs, contents or counts.
C31-C36 cover a linked correction, restricted correction details, withheld classification, unavailable/partial/stale history, other governed statuses versus a new permission decision, and invalid source/shape/display combinations. The six registry entries and next-action rules are unchanged. All four local repository checks passed again, along with document structure, source/hash/pin, exact status/display coverage, registry-schema, traceability and one-file/whitespace checks.
At 34b0f19 this was a proposed resolution for re-review, not reviewer clearance or semantic approval. Later review and approval status is recorded above. No correction authority, history store, owner contract or runtime behavior changed.
Response to the third review at 092be94
The third review disagreed with clearance of 34b0f19. The new document-only patch addresses its public-surface findings and records the owner-boundary limitation:
The current candidate is 466 lines. This revision is 65 additions and 29 deletions relative to 34b0f19; the complete PR still changes one candidate file. All four cheap local repository checks passed again. Direct checks verified 16 Markdown tables, 39 unique cases cited across all nine criteria, seven invariants, the complete root-field partition, nullable/display rules, source pins/hashes, registry schema compatibility and one-file/whitespace scope. Only the intended requiredRemediation string changed among the six registry entries.
CP2A-DEP01 remains open. The amendment created no new issue, owner PR, classifier, active contract, runtime implementation or approval. Its public-design fixes subsequently received exact-head review clearance and user Phase A approval; neither closes the producer dependency. No synthetic fixture or permanently UNAVAILABLE implementation can substitute for the missing producer binding.
What is next: obtain direction for the separate CP2A-DEP01 producer-contract work before complete binding, acceptance/admission or runtime claims. Later public-contract materialization also requires its own authorization; do not merge or implement from this Phase A approval.