Skip to content

11.4 step 3 requires vendoring spec.md and engine.md; no manifest or lock field covers them, so no engine can re-verify them #98

Description

@euskadi31

Found while synchronizing entid-go onto v2026.08.38, then demonstrated by
accident an hour later.

The gap

Section 11.4 step 3 requires a synchronization to write the prose contracts:

  1. écrit spec/, rules.lock et spec/PROVENANCE.mdles contrats en prose
    compris
    , spec.md, engine.md et son engine-<langage>.md, que la release
    publie et atteste au même titre que les schémas.

The manifest carries a digest field for every other vendored file — rulesProtoSha256,
conformanceProtoSha256, testeeProtoSha256, irDocSha256, featuresDocSha256,
and the two artifacts. It carries none for spec.md, engine.md or
engine-<langage>.md.

Section 16 then closes the lock:

rules.lock porte exactement ces champs, dans cet ordre :

Twelve fields, plus attestation_identity. So an engine that vendors the three
prose contracts, as step 3 requires, has nowhere to record what they hashed to,
and its verification entry point (section 12.6, "empreintes du lock") cannot
re-check them. They are verified once, at download, and never again.

The demonstration

While entid-go was being synchronized, tools/sync_engines.sh was run from
this repository by accident and copied a newer, unreleased spec/engine.md into
the engine's tree. The engine's own guard caught nothing, because there is
nothing to catch it with:

  • make verify checks eight digests. engine.md is not one of them, and cannot
    be, because no manifest field and no lock field exists for it;
  • the file was read afterwards, as a normative source, for section numbering and
    for the list in section 16;
  • the tree was restored by hand, and the engine only established that its
    committed copy is the released one by re-downloading SHA256SUMS out of band:
99bc6e72095841d40c6ee3bbb2df00b16e1d4572311ab9deb630a81f448a756d  engine.md
58335ea2aeedf444f49a1133dfe179ad26ac8bfcc5473b9fa34eed00cac64f30  spec.md
85e07d332830db928c46dfd2a5d210865ee1dd9e13277fcaf9405768720bb47b  engine-go.md

Nothing was lost this time. What the incident measures is that the engine had no
way of knowing that from inside its own verification, and that the answer had to
come from the release rather than from the repository.

This matters more now than it did before v2026.08.38, because engine.md stopped
being documentation an engine merely reads: section 16's ```lock-fields block
is normative, and entid-go asserts its rules.lock against it by parsing the
vendored copy — deliberately, so that two engines compare against one source
rather than two hand-copied lists. A vendored normative source that nothing
re-verifies is a worse position than a vendored document nobody parses.

What would settle it

Three digest fields in the manifest — specDocSha256, engineDocSha256,
engineLangDocSha256 — and the matching lock fields in the section 16 list, so
that the files step 3 requires are covered by the same mechanism as the files it
requires beside them. That is a normative change to a closed list, which is why
it is an issue here rather than a decision taken in an engine: a fourteenth field
invented by one engine is the failure section 16 already documents, where
conformance_jsonl_sha256 existed on one side only and the first release shipped
seven digests where four engines checked eight.

If the answer is instead that the prose contracts are deliberately outside the
verified set, section 11.4 step 3 should say so, so that no engine parses one as
a normative source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    next-releaseHandled together at the next legitimate release

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions