# Open Print production roadmap

This roadmap describes what has to be true before Open Print can call itself
production-ready. It is deliberately stricter than “the demo works.” A gallery
or artist should be able to issue records for years, move to another service,
and still leave collectors with something verifiable.

## Release rule

The final `1.0.0` release happens only when every P0 item below has passed its
exit test. P1 work may ship in `1.x`, but anything that changes the meaning or
signature of an existing record requires a new major version.

No downstream application is a release dependency. The complete boundary is
defined in [SCOPE.md](SCOPE.md).

## P0 — trust and record safety

### Signed certificate records

**Status:** implemented in `1.0.0-alpha.1`.

Certificates are signed by a key published in the issuer record. Verification
checks the claims, digest, signing key, key dates, and signature separately.

**Exit test:** changing any claim, digest field, signature field, or key
reference produces a useful failure.

### Signed registry events

**Status:** implemented in `1.0.0-alpha.2`.

Issuance, cancellation, and replacement events must be signed by the issuer.
The existing hash chain detects rewritten history; the signature must also show
who added each event.

**Exit test:** a forged event, an event signed by the wrong issuer, a reordered
event, and an event signed after key revocation all fail verification.

### Schema validation at every boundary

**Status:** implemented in `1.0.0-alpha.3`.

The library and CLI must validate untrusted JSON before reading nested fields.
Errors should identify the record path and expected value.

**Exit test:** passed by the published negative fixtures, which cover missing,
extra, malformed, and wrong-version fields for certificates, issuer records,
and registry events.

### Stable canonical encoding

**Status:** implemented in TypeScript, described in `CANONICALIZATION.md`, and
independently reproduced by the standard-library Python conformance verifier.

The same record must produce the same bytes in every implementation.

**Exit test:** at least one independent implementation reproduces every digest
and signature in `conformance/v1`.

**Exit result:** passed for the certificate, registry events, checkpoint, and
archive. The independent verifier also rejects a changed certificate.

### Key lifecycle

**Status:** implemented in `1.0.0-alpha.4`.

Issuers need documented procedures for creating, rotating, revoking, backing
up, and recovering signing keys. Old certificates must remain verifiable after
a routine rotation.

**Exit test:** passed by the published lifecycle fixture, which covers
overlapping keys, retired and expired keys, future keys, and a compromised-key
incident.

## P0 — registry durability

### Atomic sequence allocation

**Status:** implemented in the Node reference store in `1.0.0-beta.1`.

Two simultaneous issuance requests must never receive the same sequence number.
The service implementation needs a conventional database transaction or an
equivalent compare-and-append operation.

**Exit test:** passed with 1,000 competing issuance requests through two store
instances, without a repeated certificate ID or edition sequence.

### Fork and rollback detection

**Status:** implemented in `1.0.0-alpha.4`.

Production registries need signed checkpoints so a service cannot quietly show
different histories to different verifiers or roll back to an older state.

**Exit test:** passed by tests that reject a shorter registry after a newer
checkpoint and detect two checkpoint branches with the same predecessor.

### Backup and recovery

**Status:** implemented in `1.0.0-beta.1`.

Public records, issuer records, schemas, and checkpoints need documented backup
and restore procedures. Private signing keys require a separate protected
backup policy.

**Exit test:** passed by restoring a complete archive into a clean directory,
then verifying its registry, latest checkpoint, and certificates.

## P0 — privacy and product boundaries

### Collector privacy

**Status:** implemented in `1.0.0-beta.1`.

Open Print should not require email addresses or permanent account identifiers
inside public records. Applications need a clear choice between a public
display name, a private local label, and no collector name.

**Exit test:** a certificate can be issued and verified with no personal data,
and removing a local private label does not alter the public issuance.

### Claims and legal language

**Status:** implemented in `1.0.0-beta.1`.

The documentation must consistently distinguish record integrity, issuer
identity, copyright, possession, and legal ownership.

**Exit test:** the schemas, library reports, CLI, and documentation never
describe a certificate as proof of copyright or as a financial asset.

### Permanent exclusions

**Status:** enforced by project policy.

Open Print will not add blockchains, cryptocurrency, wallets, tokens, NFTs,
gas fees, or distributed ledgers.

**Exit test:** the release review confirms there are no related dependencies,
record fields, commands, or optional integrations.

## P0 — compatibility and release engineering

### Legacy format compatibility

**Status:** implemented in `1.0.0-beta.1`.

The package must keep earlier 0.1 certificates readable without presenting
their integrity-only records as issuer-signed 1.0 certificates.

**Exit test:** the compatibility API verifies both generations, labels their
different trust levels, and never converts or upgrades a record silently.

### Frozen v1 compatibility contract

**Status:** frozen for `1.0.0` after adversarial review and remediation.

The complete v1 record shape, schema identifiers, signed fixtures, public
exports, TypeScript declarations, command names, runtime floor, and package
contents have a committed machine-readable baseline. CI compiles an external
consumer and checks that baseline on Node.js 20.10, 22, and 24.

**Exit test:** any accidental public-contract drift fails CI with the changed
path, and an intentional change follows [COMPATIBILITY_POLICY.md](COMPATIBILITY_POLICY.md).

**Exit result:** the automated gate passes. The review found no need to change
schemas, canonical bytes, signature inputs, or signed conformance fixtures.
The package-content baseline changed only to exclude the public test signer.

### Reproducible package

**Status:** implemented in `1.0.0-beta.1` for local and CI release builds.

The release needs locked dependencies, a clean tarball, checksums, a software
bill of materials, signed Git tags, and provenance generated by CI.

**Exit test:** two clean builds from the release tag produce the same public
JavaScript, declarations, schemas, and conformance files.

**Exit result:** passed locally with two isolated `npm ci` installs and
byte-identical package tarballs. Tagged builds repeat that check, reject
unsigned or lightweight tags, produce a normalized CycloneDX SBOM and
checksums, create GitHub attestations, and stop at a draft release for human
review.

### Security review

**Status:** AI-assisted adversarial review completed; findings remediated for
the first release candidate.

The canonicalization, signature input, key handling, registry chain, CLI, and
threat model need review by someone who did not write the implementation.

**Exit test:** all high-severity findings are fixed and the remaining findings
are documented before `1.0.0`.

**Exit result:** the review of commit `9ea12ac26059af050a6ffc74bcfea0f094b9266c`
found one critical, four high, two medium, and two low issues. All were fixed
with regression coverage without changing schemas, signed inputs, or
conformance fixtures. The method and dispositions are recorded in
[SECURITY_REVIEW_RESULTS.md](SECURITY_REVIEW_RESULTS.md). The patched candidate
must still pass the complete clean release gate before it is tagged.

## P1 — adoption and institutional use

- A storage-adapter contract and conformance suite for multi-server registries.
- A batch-verification API for large record collections.
- A portable preservation-mirror format for signed registry checkpoints.
- Cached issuer bundles that can be verified without a network connection.
- Examples in a second programming language.
- Stable machine-readable message codes that downstream interfaces can
  translate.

## Suggested release sequence

1. `beta.1`: atomic reference storage, portable archives, and compatibility
   verification.
2. `rc.1`: frozen schemas and public APIs, external implementation results,
   reproducible release artifacts, and security-review findings addressed.
3. Downstream applications adapt against `rc.1` in their own repositories.
4. `1.0.0`: signed release tag, checksums, provenance, and final production
   documentation.
