Innsigle Reference Claim System: Colophon, Storage, Signing

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

Generated from HELIX docs. Source: docs/helix/02-design/claim-system.md. Edit the source, not this file or site/ HTML.
Source frontmatter
ddx:
  id: aibadge.design.claim-system
  type: solution-design
  links:
    - target: aibadge.prd
      kind: informed_by
    - target: aibadge.design.attestation-prior-art
      kind: informed_by
    - target: aibadge.design-system
      kind: informed_by
status: draft
activity: 02-design
created: 2026-07-22

Claim System: Colophon, Storage, Signing

Solution-level design for composition declaration and optional attestation. Normative field names here are design intent; freeze in a Contract before implementing the CLI.

Prior art stance: in-toto-shaped subject/predicate; PGP/DKIM-shaped long-lived keys; TOFU key discovery for v1; optional later WoT cross-signs. Details: attestation-prior-art.md.

Goals

GoalSource
Typed colophon with named tools (Claude, sloptimizer, …)PRD FR-1–4, FR-4a
Sign content hash + bill + issuerPRD FR-9–12
Docs-friendly storage (no media embed required)UC-AI-docs
Social-safe mark without claim-in-fileUC-human-social
Not a detector; edit ≠ human-authoredPrinciples, FR-4a

Naming

TermMeaning
Colophon (colo)Declared recipe of how the work was made (composition + ingredients); short form colo
CompositionCoarse state: human-authored \mixed \model-primary
IngredientOne tool, model, or human role line item
ClaimJSON document: subjects + colophon + metadata (unsigned or to-be-signed body)
AttestationClaim body + signature by an issuer key
IssuerPerson or house key that signs
SubjectContent unit identified by digest (and optional URI)
Seal / markVisual Innsigle badge; valid signed or unsigned (see DESIGN.md)
MakerPublisher/operator who applies the seal (not human-author-only)
SigilBounded synonym for the mark as recognition surface; not occult
SignetOptional act of cryptographically signing; not always-on chrome

Avoid public "credentials" for the product object (C2PA collision). Internal type URIs may still say attestation.

Colophon schema (draft v1)

Conceptual model

Colophon
  composition: enum
  ingredients[]: Ingredient
  notes?: string          # short free text; not a loophole for hiding models
  provenance?: {          # optional pointer to session provenance (L2)
    kind: "session"
    digest: { alg, value }
    uri?: string
  }
  schema_version: "1"

Ingredient
  kind: model | tool | human | other
  name: string            # "Claude", "sloptimizer", "Erik LaBianca"
  role?: string           # "draft", "edit", "structure", "rewrite"
  version?: string        # model id or tool version when known
  uri?: string            # optional link to product/docs

Detailed machine history (prompt counts, skill runs, compact timeline) lives in a session provenance document—see session-provenance.md and FEAT-004. The colo stays short; L2 is optional and linked by digest.

Composition enum

ValueWhen to use
human-authoredSubstantive prose/media produced by humans; models not primary authors
mixedMaterial human and model authorship both present
model-primaryModel(s) produced most of the substantive content; humans may edit/structure

Rule (FR-4a): Running sloptimizer (or similar) on model output does not by itself change model-primaryhuman-authored. List sloptimizer as kind: tool, role: rewrite (or similar).

Claim document (unsigned body)

{
  "innsigle": "1",
  "type": "https://innsigle.dev/claim/colophon/v1",
  "issued_at": "2026-07-22T18:00:00Z",
  "issuer": {
    "id": "azgaard",
    "name": "Azgaard",
    "key_id": "ed25519:BASE64URL_FINGERPRINT",
    "key_url": "https://azgaard.net/.well-known/innsigle/keys.json"
  },
  "subjects": [
    {
      "uri": "https://example.com/docs/page/",
      "digest": {
        "alg": "sha256",
        "value": "hex-or-base64url"
      }
    }
  ],
  "colophon": {
    "schema_version": "1",
    "composition": "model-primary",
    "ingredients": [
      {
        "kind": "model",
        "name": "Claude",
        "role": "draft",
        "version": null
      },
      {
        "kind": "tool",
        "name": "sloptimizer",
        "role": "rewrite",
        "uri": "https://github.com/easel/easel-skills"
      },
      {
        "kind": "human",
        "name": "Erik",
        "role": "structure-edit"
      }
    ],
    "notes": null
  }
}

Aligns with in-toto mentally: subjects ≈ subject digests; colophon ≈ predicate; type ≈ predicateType. v1 may ship this JSON without full DSSE.

Canonical content hashing

Contentv1 approach
Single fileSHA-256 of raw bytes
HTML pageSHA-256 of canonical bytes defined by CLI (document exact rules in Contract): prefer raw file as published, or normalized UTF-8 without volatile fields
Multi-page sitePer-page claims, or one claim with multiple subjects (release set)

Open: strip HTML comments / CDN query strings? Prefer: hash the artifact the operator points at; document foot-guns.

Storage mechanisms

Design constraints

  • Docs sites: static hosting, no required DB.
  • Social: no reliance on platform-preserved metadata.
  • Verify: offline possible given claim + content + pubkey.

v1 stores

StoreWhat lives thereChannel
A. Sidecar filepage.innsigle.json next to content or in /.well-known/innsigle/claims/…Docs
B. Embedded linkFooter mark links to claim URL or #innsigle fragment pageDocs
C. Inline unsigned billHuman-readable bill in HTML (optional duplicate of JSON fields)Docs
D. Mark asset onlySVG/PNG + link to profile/colo explainer; no per-post signatureSocial
E. Key documentkeys.json (public keys, key_id, optional revoke)Discovery

Not v1 (parked)

StoreWhy park
C2PA embed in JPEG/PNGSocial strip; media-first
Central claim databaseScope
DNS TXT for full claimSize; use for key selectors later (DKIM-like)
Blockchain / always-on transparency logOptional later (Sigstore Rekor-class)

Docs (signed page):

site/
  docs/foo/index.html          # footer → seal + link
  .well-known/innsigle/
    keys.json
    claims/docs-foo.json       # attestation (claim + sig)

Social:

mark: innsigle-human.svg (or PNG)
bio: https://azgaard.net/innsigle
# no per-tweet claim file required in v1

Signing and attestation

Algorithms (v1 proposal)

ChoiceProposalRationale
SignEd25519Small keys, modern default, wide support
HashSHA-256Universal
Key encodeJWK or raw base64url in keys.jsonSimple; OpenPGP packets optional later

ADR to freeze.

Attestation envelope (v1 simple)

{
  "payload": { /* claim body as above */ },
  "payload_encoding": "json",
  "signatures": [
    {
      "key_id": "ed25519:…",
      "alg": "ed25519",
      "sig": "base64url",
      "signed_at": "2026-07-22T18:00:01Z"
    }
  ]
}

Signed bytes: canonical JSON of payload (rules in Contract: key sort, UTF-8, no insignificant whitespace) or hash of payload then sign hash. Pick one in Contract; prefer sign-over-hash of canonical payload.

Later (P2): DSSE envelope + in-toto statement for cosign/SLSA ecosystem alignment.

Verify algorithm

  1. Fetch attestation JSON.
  2. Load issuer key by key_id from key_url or local pin.
  3. Verify signature over payload (canonical).
  4. Recompute digest of local/canonical content; match subjects[].digest.
  5. Report: valid | bad_signature | content_mismatch | unknown_key | revoked.
  6. Display colophon fields regardless of validity, with clear banner if invalid.

Never report "this is 80% AI."

Key lifecycle (v1)

OperationBehavior
GenerateCLI creates Ed25519 keypair; private key local file; never log
PublishPublic key in keys.json at HTTPS URL
RotateNew key_id; old optional revoked_at; new claims use new key
DiscoverAbsolute HTTPS key_url inside signed claim (ADR-003); fetch issuer document from any durable host (not only self-hosted)
Social bootstrapIssuer card on profiles (fingerprint + keys URL); corroboration only (ADR-003 D7)
WoTOptional key-endorsement attestations listed on issuer document (ADR-003)

Trust policy (verifier) — ADR-003

LevelMeaning
Crypto validSignature + content match; key_url integrity included in signed payload
Issuer recognizedPin of key_id, and/or path of crypto-valid key-endorsements from a pin (transitive WoT)
Policy acceptUser/org treats that recognized issuer as trusted for this class of content

SLSA lesson: separate crypto success from policy trust.

Identity fields: issuer.id = non-unique display slug. Cryptographic identity = key_id. Discovery channel = absolute key_url (signed). See ADR-003.

CLI surface (intent only; Contract later)

Command intentResult
colo example / editWrite colophon fields
claim buildBind subjects + colo → claim payload
signAttach signature with local key
verifyPath or URL to attestation + content
keygen / key publish-templateKey material + sample keys.json

Exact flags belong in Contract, not here.

Alignment matrix

Prior artInnsigle v1 choice
PGP WoTADR-003: signed key-endorsements published at issuer URL; transitive path optional
DKIMSteal domain/URL-published pubkey + sig over content
in-totoSteal subject + predicate typing
SLSASteal provenance ≠ truth; policy separate
SigstoreOptional later keyless/transparency
C2PAOptional export; not primary store
SBOMSteal typed ingredients discipline
SloptimizerIngredient tool, not composition flip

Security notes

  • Private keys never in claims or site static files.
  • key_url must be HTTPS in production guidance.
  • Treat claim notes as untrusted display text (escape HTML).
  • Unsigned bills are allowed; UI must not look "more true" than signed ones

without labeling signed/unsigned clearly.

Open questions

  • [x] Freeze Ed25519 + canonicalization in ADR → ADR-001 accepted
  • [x] Claim/CLI normative surface → CONTRACT-001 (+ JSON Schema)
  • [x] Absolute issuer key_url in every signature + WoT endorsements → ADR-003
  • [ ] Type URI host (innsigle.dev vs azgaard.net path) when domain bought
  • [ ] Multi-subject release claims for whole site versions (schema allows array)
  • [ ] Whether mixed needs sub-ratios (human-led vs model-led)
  • [ ] P2: map ingredients to IPTC digitalSourceType / C2PA assertions

Implementation sequence (suggested)

  1. ~~Schema JSON Schema + examples~~
  2. ~~ADR + Contract freeze~~ (ADR-001, CONTRACT-001, ADR-003)
  3. ~~Keygen + hash + sign + verify CLI~~ (src/cli.mjs, npm test)
  4. ~~Golden test vectors~~ (tests/vectors/, tests/vectors.test.mjs)
  5. ~~Docs footer + sample claim~~ (docs/sample/)
  6. ~~Mark exploration pack~~ (docs/sample/assets/marks/)
  7. ~~Brand explainer / public site~~ (docs-driven microsite + Pages)
  8. Feature specs FEAT-001–003 + walkthroughs
  9. CLI: HTTPS fetch keys + WoT path check; optional in-toto/DSSE export
  10. Session provenance capture skill + provenance build / propose-colo (FEAT-004)