A signature is an envelope of one or more signatures over one or more subjects; a level chooses its form, changes it only forward, and never below its floor
Accepted
Context
Every ratified SOW and every signed receipt in this level is today one detached minisign signature over one file: `<file>.ncl.minisig` beside `<file>.ncl`, verified with `minisign -V` (.ontoref/reflection/modules/forms.nu:538, mandate.nu:137, authority.nu:107). The SOW schema forbids a signature field inside the SOW, because a file cannot carry a signature computed over its own bytes (code/ontology/schemas/sow.ncl:5-7). Measured on 2026-10-07: all 32 signed SOWs of this level, 31 in .governance/archive/ and one in force, verify with `form verify-sow` (stage Archived, and Landed).
Three pressures meet on that single form.
ALGORITHM. minisign is Ed25519 over a BLAKE2b-512 prehash. It is not post-quantum, and forgeability is retroactive: a signature that can be forged later is a signature that could have been forged all along (qa.ncl:6010). The schemes are already declared as a seam rather than fixed: a SOW's ratification policy lists `accepted_schemes` (code/ontology/schemas/ratification.ncl:87-89, default ["minisign"]), the presentable set is `["minisign", "ml-signify"]` (ratification.ncl:41), ratify.nu:251 refuses a signer whose scheme the policy does not accept, the daemon dispatches `--verify-payload` by scheme with ml-dsa-65 recognised and not built (crates/ontoref-daemon/src/main.rs:815-828), and signatio recognises ml-signify, ml-dsa-65 and sshsig-ed25519 without building them (signatio-attest/src/scheme.rs:11-24, signatio-verify/src/scheme.rs:59). `accepted_schemes` is a disjunction: ANY one listed scheme answers. Nothing can say «these schemes, ALL of them», which is what a hybrid classical + post-quantum signature needs during a transition, and what makes changing the signing tool possible without a flag day.
VOLUME. One human act per file is the cost the principal reported as the reason this question was opened («cansados de firmar cada SOW»). A form that can name several subjects by digest lets one act cover several files, the way a signed release manifest covers every package it lists by hash.
PROPORTION. A hybrid, multi-subject envelope is excessive for a project with one signer, one key and a few SOWs, which is this level today. Imposing it would be the mandatory-gate failure voluntary-adoption and formalization-vs-adoption exist to refuse.
The in-toto attestation framework was measured as a model on 2026-10-07. Its layout/link pair does not fit the SOW and the receipt: the layout embeds keys (adr-122 leaves who-is-who to the authority), its steps require links signed by the functionary who did the work (adr-121 `agents-never-sign`, `a-trace-authorizes-nothing`), and it has no place for validity (adr-127), relation, refutation or pay_at. Its envelope does fit: a payload carried as bytes with any number of signatures beside it, and a statement naming its subjects by digest. Measured in the same pass: no receipt line records the digest of the tree its checks ran on (keys of all 248 lines in .governance/receipts/: wo, contract, phase, exit, verdict, detail, ts, and sometimes refutation, cause). That gap is real and is not decided here.
Out of scope, explicitly: who may produce a signature (adr-121 stands unchanged), where a key is kept and by what act it is used (adr-120 `ratification-needs-a-human-act` stands unchanged), building any post-quantum scheme, and any notary or presence provider. This decision fixes the FORM a signature takes and how a level moves between forms; it does not move the authority to sign.
Decision
ONE MODEL, TWO ENCODINGS. A signature over governed files is an ENVELOPE: one or more subjects, each named by its digest, and one or more signatures, each tagged with its scheme and key id. Verification has one question: do the signatures present, over the subjects present, satisfy what the policy asks? Two encodings answer it, and both are first-class:
- SINGLE — today's detached `<file>.minisig`. It IS the envelope with one subject (that file) and one signature (minisign). It needs no new file, tool or field, and it is the default. - ENVELOPE — one file carrying the payload as bytes, its subjects by digest, and N signatures. A file is covered only if its exact digest is listed. The envelope signs the bytes it carries, never a re-serialisation of a structure, so no canonicalisation step stands between what was signed and what is verified. The concrete format (DSSE is the candidate it was measured against) is the delivering SOW's.
COMPOSITION IS DECLARED. The ratification policy keeps `accepted_schemes` and gains `compose`: 'Any (default — one accepted scheme suffices, exactly today's behaviour) or 'All (every accepted scheme must be present and verify over the same subjects). A hybrid signature is `compose = 'All` over a classical and a post-quantum scheme. A scheme the verifier cannot evaluate is never a pass: under 'All it fails closed, as the authority profile already does for an unbuilt scheme (authority.ncl:123).
RULE 1 — THE FORM IS INSIDE THE SIGNED TERMS. What a SOW requires of its own signature (`compose`, the schemes) lives in its ratification policy, which is inside the SOW and frozen with it (sow.ncl:171-174). A file never means a different thing tomorrow because a configuration file changed. A SOW without a ratification policy keeps the single witness.pub path of adr-066.
RULE 2 — THE LEVEL CHOOSES, AND CHANGES ONLY FORWARD. A governance level declares its default form beside its authority declaration; a new SOW drafted in that level starts from it. Changing the default never rewrites, re-signs or invalidates a file already signed: every encoding the level ever accepted stays verifiable by `form verify-sow` and `verify-receipt` for as long as any file in the level or its archive uses it. A signature cannot be amended (sow.ncl:9-10), and re-signing the corpus would repeat, N times, the human act this decision exists to make cheaper.
RULE 3 — NEVER BELOW THE FLOOR. The level declares a floor: the minimum composition it accepts for a NEW ratification. A SOW whose ratification is recorded in the level's ledger was judged under the floor in force when it was recorded and keeps that judgement. A SOW with no recorded ratification is held to the floor in force now, whatever its own terms ask for: its terms may raise the bar above the floor, never lower it. Without this rule, the weakest accepted form is the one an attacker chooses, and a hybrid policy protects nothing. Lowering the floor is itself a governed act: admitted only through a SOW ratified under the floor it lowers.
An offline level keeps verifying minisign (ratification.ncl:133): a hybrid with minisign as one of its schemes satisfies that rule unchanged, so this decision does not touch it.
Constraints
- Hard The ratification policy's default accepts a single minisign signature, so a project that declares nothing keeps today's flow
- Hard Every SOW signed in this level or its archive verifies with `form verify-sow`, whatever form the level uses for new work
- Hard The composition a SOW requires of its own signature is declared in its ratification policy (`compose`), never only in configuration
- Hard A SOW with no recorded ratification is refused by `collect-signatures` and `verify-sow` when its signatures do not meet the level's floor in force, whatever its own policy asks
- Hard A change that lowers a level's floor is admitted only through a SOW ratified under the floor it lowers
Alternatives considered
- The envelope for every project, replacing the detached signature — rejected: Imposes a multi-signature format on levels with one signer and one key, which is this level today. That is the mandatory-gate failure formalization-vs-adoption refuses; the single form is kept as a first-class encoding, not tolerated as legacy.
- Keep the single form only, and reach post-quantum by swapping minisign for another single-signature tool — rejected: A swap is a flag day for every signer and verifier, offers no hybrid during the move, and leaves the level with whichever primitive it switched to as its only protection.
- Declare the form only in the project's configuration — rejected: Configuration is edited after the fact: one edit would change what every signed file is required to carry and would make downgrade a one-line change. The policy is inside the signed terms for exactly this reason.
- Re-sign the existing corpus when the level changes form — rejected: A signature cannot be amended and the archive would be rewritten; it costs one human act per file, which is the burden this decision was opened to reduce.
- Adopt in-toto layout and link as the SOW and receipt formats — rejected: Measured 2026-10-07: the layout embeds keys (contra adr-122), requires signed links from whoever executes a step (contra adr-121), and has no place for validity, relation, refutation or pay_at. Only its envelope fits, and that is what this decision keeps.
- Leave composition as 'Any only — rejected: Under 'Any, a hybrid policy is satisfied by its weakest scheme alone; adding a post-quantum scheme would protect nothing against an adversary who presents only the classical one.
Related ADRs
ADR-047 · ADR-063 · ADR-066 · ADR-120 · ADR-121 · ADR-122 · ADR-123 · ADR-127
· reads
Perspectives