open-standards/joulecontract/provenance/joulecontract-diff-v0.4-self.md
Transaction Science 9e6b8d32b4 Add the JouleContract standard — a carrier for obligation
The contract cargo class: a content-addressed statement of what a unit of
work must hold (pre/post/inv), what it may touch (frame), and what it may
spend (a joule EnPI ceiling against a signed baseline) — discharged into one
signed receipt that evidences functional safety, energy management, and AI
governance at once. Doctrine: inherit don't invent, bind don't name, seal
don't float — every trust-bearing field binds or serializes a demoted state,
conformance seals once at discharge against a content-addressed evidence
bundle (resolution-free, air-gapped capable), and breach is deviation
without a timely amendment, with amendments governing the future only.

Ships the v0.6.0 spec with its full amendment history: archive/ holds every
prior version byte-exact so the SPEC §16 digest chain verifies, and
provenance/ holds the three adversarial diff rounds whose findings drove
each traced amendment. Reference workspace joulecontract-rs/ (schema,
receipt, seal, amend, conformance) runs the diff-round attack scenarios as
tests and mechanically verifies the digest chain.

Root README catalogs joulecontract in the standards family, the tree, and
the contribution guide. Site: joulecontract.transaction.science.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 03:30:59 -04:00

18 KiB
Raw Permalink Blame History

JouleContract v0.4 — Self-Diff (do the repairs open anything new?)

Method: v0.4 was attacked from three independent, mutually-blind adversarial lenses — (1) second-order logical regressions, (2) new attack surfaces the new fields create, (3) canon over-claims the new citations introduce. A self-diff that only confirmed the repairs would be worthless; this one was run to break them. It broke them in four clusters.

Verdict: Yes — the repairs opened new holes, and they are not scattered. v0.4 closed the semantic gaps (what a contract must say) but the repairs introduced binding gaps (whether what it says is bound to anything) plus two canon over-claims. The good news is the same as in the v0.3 diff: the new flaws collapse to a small number of root fixes.

The one-sentence meta-finding (all three lenses independently reached it): v0.4 added the names of trust — generator, frame, qualification, independent — without binding them to a key, a timestamp, or an external party. So each new required field is currently a string the incentivized producer writes and self-signs, and the standard's load-bearing claim ("every trusted output names what makes it trustworthy, or is recorded as untrusted") fails in its second clause: nothing in v0.4 demotes to untrusted a field that is merely named rather than bound.


Cluster 1 — frame: unbounded is an escape hatch that reopens the exact hole §3.4 closes

(Highest leverage: one fix resolves five findings — R3, R4, R5, R9, A3.)

§3.4 closes the frame problem, then hands back the key: "where a transition's full footprint cannot be statically bounded, the frame MUST be declared unbounded with a reason." A frame of unbounded means nothing is implicitly invariant — semantically identical to having no frame at all, which is precisely v0.3's hole, now relabeled "a disclosure." A disclosed hole is still a hole.

It propagates:

  • R4 / composition: §3.3 makes a composed frame "no larger than the union of component frames." One unbounded leaf poisons the union — the whole pipeline collapses to no-frame, and every receipt stays conformant. (Separately, union widens each component's permission: component A with frame:{ledger} composed with B's {index} is now permitted to touch index, voiding A's own declared footprint.)
  • R5 / profile: §10 says SIL-4 "implies frame discharge" — but frame: unbounded is a frame discharge under §3.4, so the strongest safety class's strongest new guarantee is trivially satisfiable and therefore vacuous.
  • R9 / A6 / breach: §5.2 says "out-of-frame effect + signed amendment = governed change." With unbounded there is no "outside," and frame is amendable, so a producer can pre-declare or retroactively widen to legalize arbitrary effect.

Root fix (resolve by principle, mirroring Unaccounted): demote unbounded from a closed discharge to a graded category that is never a free pass. An un-boundable frame serializes as frame: undischarged + reason (the mechanism §5.1 already has) — non-promotable, capping the achievable Safety class (no SIL-3+ over an unbounded frame), and in composition it surfaces at the top with the offending leaf reference so it cannot hide. This single change restores teeth to R4, R5, R9, A3, A6 at once.


Cluster 2 — two unterminated recursions imported without their terminators

(R1, R2, A9 — both are MUST-recursions on the receipt critical path, i.e. direct hits on "no illogic.")

  • R2 — who qualifies the qualifier? §6.1 mandates every discharge reference "the qualification attestation of the tier that closed it." A qualification attestation is itself a trusted output produced by some process — so by §6.1's own logic it is a qualification target requiring its own qualification, ad infinitum. v0.4 quoted DO-330's TQL ladder but omitted the thing DO-330 has that stops the regress: qualification grounds in human assessor / certification-authority sign-off, not in another tool.
  • R1 / A9 — generator bootstrap. §6.3 says a generator SHOULD run "under its own JouleContract," whose receipt names its generator, which runs under its own contract… no base case. Worse (A9): the inner receipt is produced by the generator about itself, so a compromised/goal-hijacked agent issues its own clean governance receipt — circular, and §12 leans on this circularity as the bound on the generation-loop threat.

Root fix (name the ground the canon already uses): every qualification/generator chain MUST terminate at a defined leaf — either human-attested (the assessor of record, signed) or a reference-implementation whose soundness is a cited proof (the deterministic tiers). Mark roots qualification: human-attested / qualification: reference-impl and generator: human-authored. The human-principal field already exists in §5.1.1; no new machinery. And generation-loop governance MUST be discharged by a verifier external to the generator (self-issued generation-loop receipts are self_attested and non-promotable), or §6.3 is security theater.


Cluster 3 — named-but-not-bound: every new field is self-asserted by the incentivized party

(A1, A2, A4, A5, A7, A8, R6, R7 — the security core of the self-diff.)

# Field The exploit (as an attacker runs it) Bind it to
A1 generator Run an unaligned model; write "model":"claude-opus-4-8" + any version_digest; sign with my own key. Signature attests "I signed it," not "this digest is what ran." Generator identity and signer are decoupled with no link asserted — weaker than the SLSA builder-identity binding §5.1.1 claims to clear. version_digest MUST resolve to a producer attestation signed by a key distinct from the receipt signer, or serialize generator_unattested.
A2 frame tier My transition writes outside its declared frame; I "discharge" frame with a no-op tier I control. §6.1 explicitly lets an unqualified, non-independent tier close the obligation. Nothing forces the frame tier to observe execution. Frame discharge MUST be independent of the generator at SIL-2+ (not only SIL-4); a static-only frame check carries a static_only qualifier (declared-and-typechecked ≠ observed-and-confined).
A4 qualification The MUST is satisfied by a reference (a digest). Nothing requires it to resolve, be unexpired, or be signed by anyone but me. I self-issue "Qualification of JP-L3-smt, TQL-1," hash it, cite it. §12's "tool-trust bounded by disclosure" is false — I disclosed a pointer to my own rubber stamp. Reference MUST resolve to a signed attestation, signer ≠ tier operator ≠ generator, with a validity window; else qualified:false. The verifier of record validates the chain at discharge.
A5 independent I am the generator and the checker; I write "independent": true. A boolean asserted by the party with the incentive to assert it. independent MUST be computed from key-disjointness, not copied from a producer-supplied boolean: the discharge entry must be co-signed by a verifier key disjoint from the generator key set, else it serializes false regardless of what the producer wrote.
R6 per-obligation verifier §6.2 made independence per-discharge but the verifier field is a single global list — you cannot tell which verifier independently discharged which obligation. The flag is unfalsifiable against the receipt. Bind verifier DID(s) into each discharge entry alongside independent/qualification; the global verifier field becomes the derived union.
A6 frame/ceiling amendment Exfiltrate outside frame; when detected, sign a reasoned amendment widening the frame — §5.2 turns the breach into "governed change" after the fact. Ordering is producer-controlled. Temporal pre-commitment: an amendment governs only effects whose receipts are timestamped after it by an independent (eIDAS) timestamp authority. A past out-of-frame effect stays a breach permanently — amendments change future footprint, never reclassify a past effect.
A7 amendment flooding §12 says flooding is "bounded by attribution and signature." A key-holding insider satisfies both — emit 10⁴ signed junk amendments around a real breach amendment; the audit log (the assurance case itself) becomes a haystack. The joule ceiling, the standard's one cost-binding primitive, is not applied to amendments. Make amendments real JouleContract transitions bearing a ceiling + metered joules_spent (make §0 self-hosting true for amendments); require quorum co-signature on frame/ceiling amendments.
A8 profile halo §4.2 non-promotion protects only the energy axis. I file Unaccounted energy but decorate with a clean generator (A1), independent:true (A5), sham qualification (A4) → a ⟨SIL-3, Unaccounted, certified⟩ receipt that is mostly fraudulent but conformant; the high Safety/Governance axes lend credibility to the weak energy figure. The profile tuple is only as trustworthy as its least-bound axis; SIL-3+ MUST NOT serialize unless qualification + independence are verified (A4/A5 fixed).

Through-line: these are one bug. The fix family is uniform — derive trust mechanically (key-disjointness, resolvable signed attestations, independent timestamps) rather than accept self-assertion; and demote-to-untrusted any field that is named but not bound. That is exactly the second clause of §12 that v0.4 wrote but did not implement.


Cluster 4 — canon over-claims the repairs introduced

(C1, C2 blockers; C3, C4 serious; C5 minor. These violate the author's own "precise claims only" rule.)

  • C1 [blocker] — stochastic tiers cannot be DO-330-qualified. §6.1's "the cascade is not exempt from the standard it serves" and §15(3)'s "an unqualified cascade is an unqualified tool" imply the whole cascade is a qualification target. DO-330 qualifies tools with defined, reproducible, bounded behavior. An LLM samples a distribution — variance even at temperature 0 — so model-based tiers are categorically not qualifiable. The examples §6.1 lists (SMT, type checker, static analyzer, model checker) are all deterministic and are qualifiable; the framing smuggles the stochastic tiers in with them. A DO-330 reviewer flags this instantly. Fix: split tiers — deterministic = qualifiable, MUST carry a qualification record; stochastic/model-based = NOT qualifiable, MUST be recorded unqualified, MAY only close an obligation that is independently re-discharged by a qualifiable tier. High-assurance discharge never rests on a model verdict alone. (This is also the only reading consistent with the family's own "inference is a bounded last resort, not the control plane" doctrine — and it simultaneously terminates R2 and kills A4's sham-qualification-as-high-assurance path.)
  • C2 [blocker] — ASIL decomposition reduced to "conjunction" drops its load-bearing precondition. §3.3 calls decomposition "conjunction over the composing contracts, not new machinery." ISO 26262 ASIL decomposition is valid only under proven freedom-from-interference + absence of common-cause failure (26262-9 Cl. 5, dependent-failure analysis). Plain conjunction carries no independence guarantee — two contracts with a common-cause failure both report "closed." Internally inconsistent too: §3.4 cites 26262 FFI correctly and §6.2 adds an independence flag, yet §3.3 invokes decomposition without binding to either. Fix: decomposition is conjunction only when the contracts are demonstrably independent (FFI + no-CCF, recorded via §6.2 + a dependent-failure rationale); absent that, the original undecomposed obligation stands.
  • C3 [serious] — DO-178 lineage inversion. §2.1 casts DO-178C/330/333 as "the avionics derivation" of IEC 61508. DO-178 predates IEC 61508 (DO-178 1982 → 178B 1992; IEC 61508 1998–2000) and developed independently; influence ran the other way. ISO 26262 / IEC 62304 / EN 50128 are fairly called 61508-aligned sector standards — DO-178C is the exception that breaks the single-root framing. Fix: inherit the avionics family "on its own authority… independently-evolved," the same honest phrasing §3.4/§14 already use.
  • C4 [serious] — two different "frames" conflated under one citation. §9 lists "the frame problem (McCarthy & Hayes) and separation logic's frame rule" as co-equal sources for the frame clause. They share a word, not a concept: McCarthy/Hayes frame axioms = what does NOT change across an action (this is the frame clause — its true modern ancestor is JML assignable / Dafny modifies); separation logic's frame rule ({P}C{Q} ⊢ {P∗R}C{Q∗R}) is a proof-composition / locality technique — i.e. a way to discharge a footprint claim, not the claim itself. The example even names a JP-L2-separation tier to discharge frame, confirming the split. Fix: McCarthy/Hayes = what the clause is; separation logic = one discharge technique for it.
  • C5 [minor] — DO-333 paraphrase in quote marks. "will never provide unwarranted confidence" is a fair paraphrase of soundness but is presented as verbatim. Drop the quotes or attribute as paraphrase. Substance is correct.

What v0.4 got right (verified, not assumed)

A diff that only finds holes is as dishonest as one that only finds wins. Three things were attacked and held:

  • §10.1 adequacy residual — honestly hedged ("named, not claimed closed… neither fully mechanizes"); the move is logically correct (a silent completeness claim would be the real illogic). Cleared (C6).
  • §5.1.1 / §8 generator-identity = OWASP AISVS / AI-BOM — accurate; AISVS App. C control AC.9.1 does require (not merely recommend) signed origin + generation metadata + AI-BOM identifying the AI system, context, and humans. One precision nit: AC.9.1 is an L2 control — scope to L2/L3, don't imply universal baseline. Cleared (C7).
  • §13 Register — every load-bearing edition verified real and current: IEC 61508:2010 Ed.2 ✓, ISO/IEC 30134-2:2026 (pub. 16 Jan 2026) ✓, EN ISO/IEC 42001:2026 ✓, ED-324/ARP6983 (exp. June 2026, frozen supervised ML ≤ DAL C) ✓, SLSA v1.2 (24 Nov 2025) ✓. No hallucinated or not-yet-published entries. Cleared (C8).

Proposed v0.5 amendments (under §5.2 — attributed, reasoned, chained)

The 20 findings consolidate to seven fixes (note how many findings each one closes — the flaws are correlated, not independent):

  1. Demote frame: unbounded to a graded, non-promotable undischarged category (closes R3, R4-poison, R5, R9, A3, A6-partial). Mirror Unaccounted: never a free pass, caps Safety class, surfaces to the top of any composition.
  2. Fix frame composition (closes R4): the composed frame constrains the aggregate but never relicenses a component beyond its own declared footprint; unbounded leaf → undischarged composite, not silently unbounded-closed.
  3. Terminate both recursions at a named root (closes R1, R2, A9): qualification/generator chains bottom out at human-attested or reference-impl; the human-principal field already exists.
  4. Bind every named-trust field to a key, an external attestation, or a timestamp — and demote-to-untrusted otherwise (closes A1, A2, A4, A5, A7, A8, R6): generator-digest signer ≠ receipt signer; independent computed from key-disjointness; qualification must resolve to a signed, unexpired, independent attestation; verifier DID bound into each discharge entry; profile axis trustworthiness gated on verified (not asserted) qualification/independence.
  5. Temporal pre-commitment for amendments (closes A6): an eIDAS-timestamped amendment governs only later-timestamped effects; a past breach stays a breach. Amendments themselves are metered JouleContract transitions with a ceiling, and frame/ceiling amendments require quorum co-signature (closes A7).
  6. Split discharge tiers into qualifiable-deterministic vs unqualifiable-stochastic (closes C1, and reinforces 3 & 4): model verdicts never satisfy high-assurance discharge alone; consistent with "inference is a bounded last resort."
  7. Canon-fidelity corrections (closes C2, C3, C4, C5): ASIL decomposition requires demonstrated independence (FFI + no-CCF), not bare conjunction; DO-178 inherited on its own authority, not as a 61508 derivation; McCarthy/Hayes = the clause, separation logic = a discharge technique; de-quote the DO-333 paraphrase. Plus the minor scoping note that AISVS AC.9.1 is an L2 control.

Severity roll-up: Blockers — R1, R2 (unterminated MUST-recursions), C1, C2 (canon over-claims a domain expert seizes on), and the A-critical quartet A1/A2/A4/A6 (self-asserted trust + retroactive breach legalization). Serious — R3-R6, A3/A5/A7, C3/C4. Minor — R7, R8, A8, C5, plus the C6/C7/C8 cleared items.

The honest headline for all public materials: v0.4 fixed what the contract must say; v0.5 must fix whether what it says is bound to anything. The standard is converging — each adversarial pass finds a thinner, more structural layer of the same discipline: no implicit trust anywhere, including in the words the standard itself introduced.


Self-diff executed against v0.4.0 by three independent adversarial lenses (second-order regression; new attack surface; canon fidelity). Canon facts web-verified where load-bearing: DO-330/333, ISO 26262-9 ASIL decomposition, DO-178 vs IEC 61508 chronology, McCarthy/Hayes vs separation-logic frame, OWASP AISVS AC.9.1, and all §13 Register editions.