docs(nip-fi): state, don't argue — CONF −29%, rationale section, four pins (alt to #5946) - #6437
Open
tlongwell-block wants to merge 8 commits into
Open
docs(nip-fi): state, don't argue — CONF −29%, rationale section, four pins (alt to #5946)#6437tlongwell-block wants to merge 8 commits into
tlongwell-block wants to merge 8 commits into
Conversation
… four pins CONF is rewritten so every section is either a rule or labeled as not one: the Denial-fixtures and Interoperability-exit sections carried their own design history and code review inline (1,516 and 934 words). Every BCP 14 obligation in the previous text maps to a surviving sentence; the only net loss is one MUST that restated the anonymity comparison and one that restated check-green-before-mutants. The four enumeration-agreement checks collapse to three because checks 1 and 2 quantified over the same set. Keyword census 37 -> 36. Core gains a non-normative "Relationship to other work" section (DPoP and mTLS cnf, WebAuthn multi-credential, RFC 6750 error codes, RFC 9421 and SigV4) so a reader with OAuth background sees the shape in one pass; the contract-identity argument moves there from the normative snapshot section. Three pins: skew, maximum_assertion_age, and maximum_status_age are now declared as configured finite values; the NIP-98 payload hashes one defined referent (post-transfer-decoding, pre-content-decoding content, the same octets EDGE MACs); a denial decided on a WebSocket upgrade is the HTTP table row sent instead of 101, and FI-TRACE-DENIAL-ORACLE now covers all three surfaces. EDGE: the pre-MAC derivation exception is class-scoped to any independent Nostr proof validated on its own signature rather than to the Authorization field, so 0x01 routes are covered and the undefined phrase "request component" no longer decides satisfiability; the Authorization byte-identity mandate at :62-65 gains an oracle via FI-TRACE-PROXY-CROSS-REQUEST and the Request negative-matrix row. Oracle census unchanged at 58 (30/6/4/11/7). Family 15,279 -> 14,378 words. Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
added 7 commits
August 20, 2026 18:11
Pinning the payload referent to pre-content-decoding content made the adjacent "post-validation transformation denies" forbid content decoding itself. The obligation is that the application consume the validated bytes, so the sentence now denies substitution of the body bytes after validation. Oracle census unchanged at 58. Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
…ution; restore exit independence evidence Three wording repairs from review at 37356d8: 1. FI-TRACE-DENIAL-ORACLE required every private row on HTTP, upgrade, and after connect, but a private-state row needing the NIP-42 proof cannot be decided at upgrade. The cell now reads "on every surface where its condition can be decided"; the rule sentence no longer enumerates conditions, only the when: before any NIP-42 proof = HTTP table response instead of 101, after connect = Nostr text. CONF exit list aligned ("on each transport where the class can be decided"). 2. EDGE Payload still said "Any transformation after the protected snapshot is forbidden", which read literally forbade content decoding that core now permits. Now: "Substitution of the protected octets after the snapshot denies" - same shape as core body binding. 3. The CONF rewrite dropped the exit-evidence obligation (old :393 "produced bytes and a statement of independence"). Restored as one sentence: "Exit evidence includes the exchanged artifacts and each implementation's statement of independence." Oracle census unchanged 58 (30/6/4/11/7). CONF keyword census unchanged from 37356d8 (MUST 35, MUST NOT 9, MAY 3). Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
…tive gets an oracle Two one-word repairs from formal review at dcd0b2f: 1. EDGE derivation exception listed its two members after an em dash, which reads as exhaustive and leaves the reserved 0x03 (and 0x04) routes unable to conform once their contracts publish. Now "such as": the class is the rule, the members are examples. 2. Core :176-178 pins "a missing value denies" for skew/maximum_assertion_age/ maximum_status_age, but FI-TRACE-ASSERTION-VALIDATION enumerated no negative that detects it. Added "missing-configuration" to the cell. Oracle census unchanged 58 (30/6/4/11/7). Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
…decidable be72f0a's message claimed the CONF exit list was aligned with the decidable-surface scoping; the edit was reverted in the working tree before the commit and the message was not corrected. This commit carries the edit. Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
…device sentence states only the invariant Staged diff, three hunks: - EDGE:372 negative matrix Body row: "any post-snapshot transform denies" -> "any post-snapshot substitution of the protected octets denies". Third site of the transform/substitution wording; :168 and core:315 were fixed earlier, this row still forbade permitted content decoding. - core:573 FI-TRACE-BODY-BINDING: "transformed" -> "substituted" in the negative list, so the oracle names the same act the text denies. `rg -i transform docs/nips/NIP-FI*.md` -> 0. - core:605-606 Relationship to other work: replaced the custody/rotation sentence, which prescribed behavior outside the standard, with the fact the invariants establish: "additional devices do not create additional active bindings." Oracle census unchanged 58 (30/6/4/11/7). Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
… a denial; drop the retargeted promotion guard Staged diff, three hunks: - EDGE FI-TRACE-PROXY-CROSS-REQUEST: "An Authorization field altered ... denies" was false as a universal - an edge substituting a fresh, valid NIP-98 event from the same actor admits, because Authorization is outside the MAC by design. The cell now requires the bytes at final admission to equal the client-sent bytes, witnessed at both points, and names the mutant that must fail it: valid-proof substitution. - EDGE Request negative-matrix row: removed the same "mutating Authorization ... denies" clause. The matrix enumerates denials; this property is a witness, and it now lives in the oracle cell above. - CONF Enumeration agreement: deleted "dependency_unreadable MUST NOT be promoted without also leaving the set check 1 quantifies over". The 4->3 collapse retargeted that guard from old check 2 (symbolic set) to new check 1 (every named symbol, class-compared), where a promoted dependency_unreadable passes anyway. Check 2 equality+disjointness already fails promotion until the allowlist entry is removed. Net CONF MUST NOT 9 -> 8, deliberate. Oracle census unchanged 58 (30/6/4/11/7). Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
Staged diff, one hunk, CONF:143-145. "only check 2's disjointness fails" was false in 2 of 4 promotion cases: when the promoted symbol's class disagrees with the CONF row, check 1 fails together with check 2 (the checks are independent conjuncts, not ordered). "then" implied an order the checks do not have. Now: check 2's disjointness fails until the allowlist entry is deleted, and check 1 validates the promoted symbol's class. Descriptive prose, no keyword; CONF census unchanged (MUST 34, MUST NOT 8, MAY 3). Oracle census unchanged 58. Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
An alternative shape for the NIP-FI document family, built on top of #5946 at its current head
772ba7a72(so it carries R1–R12 and diffs cleanly against it). Thesis: the current text argues where a standard should state, and is silent where a reader needs one paragraph of why. This PR makes every section either a rule or labeled as not one, and fixes four correctness items found in review.Base:
772ba7a72(=eva/nip-fi-comprehensive). Eight FF commits, no rebase. Three files. Oracle census unchanged at 58 (30/6/4/11/7).Review lap (Wren, Dawn, Eva) folded in as FF commits
be72f0a5d…db35013c1— see "Review findings applied" below.Changes
NIP-FI-CONF — 4,325 → 3,088 words (−29%), no obligation lost
Www-Authenticatecanonicalization paragraph, "one layer down", "a slow way to discover…") removed from normative text.MUST/MUST NOT/MAY/REQUIREDsentence in the old text was fuzzy-matched to the new text; the two that don't map are (a) "Their public responses MUST compare byte-identical to each other, not merely equal in prefix or status" — fully subsumed by the anonymity comparison one paragraph later, and (b) the standalone "The suite MUST include a negative control:" whose obligation is retained in the Negative control paragraph. Reviewers: please try to find a third.NIP-FI core
cnfwith the NIP-42/98 event as the proof; durable binding vs per-token claim; why 1:1 vs WebAuthn's N credentials; why two contract IDs plus dependency versions; RFC 6750 error codes; RFC 9421 / SigV4 family for the edge MAC. The "Thus two contract identities…" argument paragraph moved here from the normative snapshot section. Three source links added.skew,maximum_assertion_age,maximum_status_agedeclared as configured finite values (missing → deny). Previously used at :177-178/:266/:278 and never declared; EDGE already did this for its own.payloadhashes one defined referent — "body bytes: the complete content after transfer decoding and before any content decoding" — the same stage EDGE MACs aspayload_octets. Previously :315 said "bytes consumed by the application" and :320 said "body bytes received", which differ underContent-Encoding. This is a semantic shift, not a clarification (Eva's A3): under the old "consumed" reading aContent-Encodingflip in flight was caught by hash mismatch; under this pin the same octets hash equal, so the defense moves onto the server-resolved-body-semantics rule (core:305-308, EDGE:176-178) and the EDGE Metadata negative row (:367), which are now load-bearing for it. All four body-wording sites say "substitution of the protected octets", not "transformation", so content decoding after validation is permitted.101; post-connect denials are the Nostr text.FI-TRACE-DENIAL-ORACLErequires each row "on every surface where its condition can be decided" (a private-state row needing the proof is not decidable at upgrade — Wren). CONF exit list aligned.NIP-FI-EDGE
Authorizationor the NIP-42 event after connect" instead of naming the field. Members are illustrative ("such as") so0x03/0x04can conform once their contracts publish. Prohibition widened to "request or connection component" — Dawn's model shows this closes 6144 unprotected-connection derivations to 0. Requirement 3 gets the matching carve-out.Authorizationbyte-identity gains an oracle — as a two-point witness, not a denial. EDGE:62-65 makes altering it nonconformant; no oracle named it. First attempt said "altered … denies"; Eva (A1) and Dawn'sa1_oracle.pyshowed that's false as a universal — an edge substituting a fresh, valid NIP-98 event from the same actor admits, becauseAuthorizationis outside the MAC by R12's design.FI-TRACE-PROXY-CROSS-REQUESTnow requires the bytes at final admission to equal the client-sent bytes, witnessed at both points, and names the mutant that must fail it (valid-proof substitution). The Request matrix row no longer claims a denial for it.Review findings applied (all FF commits on
dcd0b2ff2)0x03couldn't conformFI-TRACE-ASSERTION-VALIDATIONgains "missing-configuration" negativeAuthorizationoracle asserted a false denial universal624429bd8)Not taken this lap (predate this PR): EDGE:180
maximum_provenance_agemissing-config oracle;0x04Blossom row says "authorization event" not "Nostr", so the class exception can't reach it until its contract is written.Not changed
LIFECYCLE, DELEG, MODEL: zero bytes. Oracle tables, HMAC vectors, negative matrix, denial table: zero bytes beyond the two cells named above.
Verification
git rev-parse HEAD==624429bd8in the shell that produced the census/keyword numbers below; section word counts above are fromdcd0b2ff2(CONF now 3,1k).rg -c '^\| \FI-[A-Z0-9-]+` |'` per file → 30/6/4/11/7.Open questions
Two-device sentence— closed by Wren's wording.R12 widening— Dawn's model: net stricter than772ba7a72.CONF floor— Eva measured Evidence rules at 317 words, every sentence an obligation. Floor reached.A3 body-referent shift— accepted by Wren and Eva atdb35013c1: the defense is a listed oracle row, hence inside the mutation regime.Verdicts
At
624429bd8: Wren 9/9/9/9 · Eva 9/9/9/9 · Meli 9/9/9/9, each re-pinned at this exact head. Dawn's three instruments (conf/a1/r12) rc=0 at this head. CI 14 pass / 0 fail / 9 skipped. Zero known falsehoods in the text.Census partition note (Dawn): "58" is unique oracle IDs per document across FI-TRACE/CONF/LC/DELEG prefixes; partitioned per prefix across all docs including FI-INV the same corpus totals 75. Quote the partition with the number.