Innsigle Reference Contract

Generated reference: edit sources under docs/helix/, then npm run site:build.

Generated from HELIX docs. Source: docs/helix/02-design/contracts/CONTRACT-001-claim-and-cli.md. Edit the source, not this file or site/ HTML.
Source frontmatter
ddx:
  id: aibadge.contract.001
  type: contract
  links:
    - target: aibadge.adr.001
      kind: informed_by
    - target: aibadge.design.claim-system
      kind: informed_by
    - target: aibadge.prd
      kind: informed_by
status: draft
activity: 02-design
created: 2026-07-22

Contract

Contract ID: CONTRACT-001 Type: schema + CLI Version: v1 Status: draft (normative for implementers; bump version on breaking field changes) Related: ADR-001; ADR-003; claim-system.md; PRD FR-1–4a, FR-8–12, FR-18–19

Purpose

Define the colophon claim document, attestation envelope, public key document, content hashing rules for v1, and CLI commands that produce and verify them.

Scope and Boundaries

  • In scope: JSON claim payload; attestation envelope; keys.json; SHA-256

content digests; Ed25519 sign/verify; CLI verbs listed below.

  • Out of scope: C2PA embed; DSSE/in-toto wire format (MAY export later);

multi-tenant accounts; social platform APIs; HTML DOM normalization beyond "hash the file bytes given."

  • Owning system: Innsigle CLI / library (TypeScript + Bun assumed).

Normative Surface

Use MUST / MUST NOT / SHOULD / MAY as written.

Claim payload

A claim payload MUST be a JSON object with:

ElementTypeRequiredRules
innsiglestringyesMUST be "1" for this version
typestring (URI)yesMUST be https://innsigle.dev/claim/colophon/v1 until domain freeze changes it via version bump
issued_atstringyesMUST be RFC 3339 UTC timestamp
issuerobjectyesSee issuer object
subjectsarrayyesMUST contain ≥1 subject
colophonobjectyesSee colophon object

issuer object

ElementTypeRequiredRules
idstringyesDisplay slug (e.g. azgaard); not globally unique; not a crypto identifier (ADR-003)
namestringyesDisplay name
key_idstringyesMUST match a key in the issuer document; format ed25519:<fingerprint>
key_urlstringyesAbsolute URL of the issuer document (ADR-003). Production MUST use https:. Relative URLs are invalid. http: only for loopback/tests. file: only for offline tests. Covered by the claim signature via ADR-001 JCS of the full payload.

subject object

ElementTypeRequiredRules
uristringnoContent locator when known
digestobjectyesalg MUST be "sha256"; value MUST be lowercase hex of SHA-256

colophon object

ElementTypeRequiredRules
schema_versionstringyesMUST be "1"
compositionstringyesMUST be one of human-authored, mixed, model-primary
ingredientsarrayyesMAY be empty only if composition is human-authored and notes explain; SHOULD list tools/models when used
notesstring or nullnoFree text; MUST NOT replace required composition honesty

ingredient object

ElementTypeRequiredRules
kindstringyesMUST be one of model, tool, human, other
namestringyesNon-empty
rolestringnoe.g. draft, edit, rewrite
versionstring or nullnoModel/tool version when known
uristringnoLink to tool/model docs

Composition integrity: Implementations MUST NOT offer a mode that sets composition to human-authored solely because an editorial tool (including sloptimizer) rewrote model-primary text. Tools MUST be listable as kind: "tool".

Attestation envelope

ElementTypeRequiredRules
payloadobjectyesMUST be a claim payload as above
payload_encodingstringyesMUST be "json"
signaturesarrayyesMUST contain ≥1 signature object for signed attestations

signature object

ElementTypeRequiredRules
key_idstringyesMUST match payload.issuer.key_id for the primary signature
algstringyesMUST be "ed25519"
sigstringyesbase64url (no padding) raw Ed25519 signature
signed_atstringyesRFC 3339 UTC

Bytes to sign (ADR-001): Let canonical = JCS(payload) per RFC 8785. Let h = SHA-256(canonical) (raw 32 bytes). sig MUST be Ed25519 signature of h using the issuer private key.

Unsigned claims MAY be distributed as payload-only JSON for display; they MUST NOT be labeled as signed in UI or CLI success paths.

Issuer document (at key_url)

Canonical document for key discovery and optional web-of-trust edges (ADR-003).

Preferred form (innsigle_issuer)

ElementTypeRequiredRules
innsigle_issuerstringyesMUST be "1"
issuer_idstringyesDisplay slug; SHOULD match claim issuer.id
issuer_namestringyesDisplay
keysarrayyes≥0 keys (empty means no active keys)
endorsementsarraynoDefault []. Index of key-endorsement attestations published by this issuer

Legacy form (innsigle_keys)

ElementTypeRequiredRules
innsigle_keysstringyesMUST be "1" (pre-ADR-003)
issuer_idstringyesDisplay slug
issuer_namestringyesDisplay
keysarrayyesSame as preferred form

Verifiers MUST accept either form. Legacy form implies endorsements: [].

key object

ElementTypeRequiredRules
key_idstringyesed25519: + fingerprint
algstringyes"ed25519"
public_keystringyesbase64url 32-byte public key
created_atstringyesRFC 3339
revoked_atstring or nullyesnull if active

Fingerprint: lowercase hex of SHA-256 over the 32-byte public key, truncated to first 16 bytes (32 hex chars), prefixed as ed25519:<hex>.

endorsements[] index entry

ElementTypeRequiredRules
attestation_urlstringyesAbsolute URL of a key-endorsement attestation JSON
subject_key_idstringyesEndorsee key_id
subject_key_urlstringyesAbsolute URL of endorsee issuer document
issued_atstringnoHint only; attestation payload is authoritative

Key-endorsement claim (ADR-003)

Optional claim type for web-of-trust edges. Type MUST be https://innsigle.dev/claim/key-endorsement/v1.

ElementTypeRequiredRules
innsiglestringyes"1"
typestringyesKey-endorsement type URI above
issued_atstringyesRFC 3339 UTC
issuerobjectyesEndorser — same rules as colophon claims, including absolute key_url
endorsementobjectyesSee below

endorsement object

ElementTypeRequiredRules
subject_key_idstringyesEndorsee key fingerprint id
subject_key_urlstringyesAbsolute URL of endorsee issuer document
subject_issuer_idstringnoDisplay slug of endorsee (non-unique)
levelstringnoOne of full, marginal, unknown (PGP-inspired; default full if omitted)
purposestringnoMUST NOT claim content truth; default identity — trust for recognizing seals

Key-endorsement attestations use the same envelope and ADR-001 crypto as colophon claims. They do not authenticate content honesty.

Signed key_url rules (normative)

  1. Producers of signed claims MUST set issuer.key_url to an absolute URL.
  2. The signature (ADR-001) covers the full payload including issuer.key_url.
  3. Verifiers MUST discover keys using the signed issuer.key_url unless applying an explicit local pin/override.
  4. issuer.id MUST NOT be treated as a globally unique or cryptographic identifier.
  5. key_url MAY be any durable HTTPS origin that serves the issuer document (self-hosted, git forge raw/Pages, static free host, etc.). Self-operated webserver is not required (ADR-003 D7).
  6. Social profile text and “link in bio” fields MAY embed an issuer card (fingerprint + keys URL) for human discovery. Profile embeds are not signatures and MUST NOT be treated as cryptographic proof by themselves.

Content hashing (v1)

  • For a subject that is a file, digest MUST be SHA-256 of the exact file

bytes the operator supplies (no silent transcoding).

  • CLI MUST record the path or URI used when building the claim.
  • HTML "live page" fetch MAY be supported later; v1 CLI MUST support local file

subjects.

CLI

Binary name: innsigle (package may ship as such).

CommandArgs (normative intent)Behavior
innsigle init--onepassword [--dir] [--site-url] [--issuer-*] [--vault] [--force]MUST create house key custody outside the repo (1Password when --onepassword); MUST write all repo-local state under .innsigle/ only (no framework web-root detection); MUST stage public issuer document at .innsigle/public/keys.json for publish to site /.well-known/innsigle/keys.json; MUST write commit-safe .innsigle/config.json with key_id fingerprint and custody reference; MUST write agent-oriented publish instructions under .innsigle/; MUST NOT write private key material into the repo
innsigle keygen--out-dir <dir>MUST write private key (permissions 0600 when FS supports) and public material; MUST NOT print private key
innsigle keys template--issuer-id --issuer-name --public-key --key-idMUST emit issuer document skeleton (innsigle_issuer preferred; includes endorsements: [])
innsigle claim build--content <file> --uri <uri?> --colo <colo.json> --issuer-* --key-urlMUST emit claim payload JSON; MUST reject non-absolute key_url (exit 5); MAY accept --bill as alias for --colo; MAY default issuer fields from .innsigle/config.json
innsigle sign--claim <file> --key <private?>MUST emit attestation envelope; SHOULD refuse unsigned path if claim lacks absolute key_url; MAY load private key from --key, --op-ref, or .innsigle/config.json → 1Password (op read)
innsigle verify--attestation <file> --content <file> `--keys <file\url>`MUST exit 0 iff signature valid, key not revoked, and content digest matches; MUST exit non-zero otherwise. Identity/WoT recognition is separate (ADR-003)
innsigle colo example`--kind model-primary\human-authored\mixed`MUST print example colophon JSON; MAY accept bill example as alias

verify exit codes

CodeMeaning
0Valid signature, active key, content match
1Usage / IO error
2Bad signature
3Content digest mismatch
4Unknown or revoked key
5Invalid schema invalid

verify stdout (human)

MUST include lines sufficient to see: result keyword (VALID / INVALID), issuer id, composition, and failure reason when invalid. MUST NOT print AI detection scores.

Precedence and Compatibility

  • Versioning: innsigle field and schema_version / innsigle_keys /

innsigle_issuer govern payload and issuer-document compatibility. Breaking changes MUST bump these and the contract version.

  • Related decision records: ADR-001 (crypto), ADR-003 (issuer URL + WoT).
  • Unknown JSON fields in payload: verifiers MUST ignore unknown fields when

verifying signatures (signature covers canonical form of known payload as signed; producers SHOULD avoid unknown fields in v1).

  • Deprecation: announce in release notes; keep verify for prior innsigle: "1"

for at least one minor series after a bump.

Error Semantics

ConditionOutcomeRetry
Missing fileexit 1no
Invalid JSON schemaexit 5no
Signature failexit 2no
Digest mismatchexit 3no
Revoked keyexit 4no

Examples

See:

  • docs/helix/02-design/examples/claim-model-primary-docs.json
  • docs/helix/02-design/examples/keys.json (legacy keys-only)
  • docs/helix/02-design/examples/issuer-document.json (ADR-003 issuer + endorsements index)
  • docs/helix/02-design/examples/key-endorsement-claim.json
innsigle keygen --out-dir ~/.config/innsigle/azgaard
innsigle claim build --content ./site/index.html --uri https://example.com/ \
  --colo ./colo.json --out claim.json
innsigle sign --claim claim.json --key ~/.config/innsigle/azgaard/ed25519.priv \
  --out claim.attestation.json
innsigle verify --attestation claim.attestation.json --content ./site/index.html \
  --keys ./keys.json

Non-Normative Notes

  • Type URI host innsigle.dev is provisional until domain purchase.
  • JCS libraries: implement or depend on a reviewed RFC 8785 implementation;

golden vectors will live under tests/vectors/ when code lands.

  • Social UC often uses mark assets without per-post sign.

Validation Checklist

  • [x] Normative fields and rules explicit
  • [x] Compatibility rules explicit
  • [x] Error / exit codes explicit
  • [x] Tests can be derived (golden vectors + CLI exits)
  • [x] Non-normative section separated