Skip to content

Latest commit

 

History

History
143 lines (117 loc) · 9.39 KB

File metadata and controls

143 lines (117 loc) · 9.39 KB

Versioning & Deprecation Policy

How the @quantakrypto/* packages are versioned and how breaking changes are introduced. This policy operationalises ADR-0002 (@quantakrypto/core is the shared contract) and ADR-0003 (independent publish from one monorepo).

1. SemVer

All packages follow Semantic Versioning 2.0.0: MAJOR.MINOR.PATCH.

  • MAJOR — a backward-incompatible change to a package's public surface.
  • MINOR — backward-compatible new functionality.
  • PATCH — backward-compatible bug fixes (including detection-accuracy fixes that do not change the data contract).

Pre-1.0 reality (all packages are in the 0.x range)

Under SemVer's 0.x rule, anything may change in a minor release and the public API is explicitly pre-stable. We make no compatibility promises before 1.0 — pre-1.0 breaking cleanups land in a 0.x minor even though they would be breaking post-1.0. (The two earlier honesty items — the baseline-fingerprint schism P1-1 and the dead ScanOptions.include option P1-2 — have both since been fixed this way.) Reaching 1.0.0 requires a documented, frozen public API surface (the core contract), a generated API reference, and a maintained CHANGELOG.

Status (2026-07-20): the generated API reference and the frozen surface are now in place — docs/API.md (human) and docs/api-surface.json (the machine-readable contract) are generated by npm run api:docs from each package's public entry point, and npm run api:check (a CI gate in the lint job) fails if a package's real exports drift from the snapshot. So adding or removing a public symbol is now a deliberate, reviewed change to the checked-in surface, not an accident — the remaining 1.0 work is to keep the CHANGELOG current (ongoing) and to make a considered decision that the surface is stable enough to freeze under the post-1.0 breaking-change rules.

Independent versions, coordinated bumps

Each package versions independently (it has its own package.json and publishes on its own line). But because five tools consume @quantakrypto/core — qScan, MCP, the Action, agent, and qProbe (ADR-0002; Sieve is standalone and depends on no other package):

  • A MAJOR bump of @quantakrypto/core that changes the contract forces, at minimum, a MINOR bump of every consumer that adopts the new core (a new compatible feature) or a MAJOR bump where the consumer's own surface changes as a result.
  • Consumers declare their @quantakrypto/core dependency with a range that does not cross a core MAJOR (e.g. ^1). Crossing a core MAJOR is itself a breaking change for the consumer.

2. The public surface, per package

Only the documented surface is covered by SemVer. Internal modules (anything not re-exported from a package entry point, anything under a src/internal-style path, dist layout) are not part of the contract and may change in a PATCH.

Package Public surface (SemVer-covered)
@quantakrypto/core The exports of src/index.ts + the types in src/types.ts (see §3).
@quantakrypto/qscan The qscan CLI (flags, exit codes, output-format shape) and the qremediate CLI (flags, --mode diff|apply|pr, exit codes 0/2) and the programmatic API: runQscan, EXIT, parseArgs, defaultOptions, REMEDIATE_EXIT, severity + baseline helpers.
@quantakrypto/mcp The MCP tool contract: tool names, their inputSchema, and result shape; the supported JSON-RPC methods. The bin name quantakrypto-mcp.
@quantakrypto/action The action interface: action.yml inputs, outputs, and documented exit behavior; the uses: ref.
@quantakrypto/sieve The SUT protocol (PROTOCOL.md, PROTOCOL_VERSION), the CLI flags/exit codes, and runSieve/formatHuman.
@quantakrypto/agent The exported BYOK client API: resolveClient, triageFindings, proposeFix, validateAgainstSchema, the LlmClient/LlmConfig/LlmRequest types, and the prompt-version constants (TRIAGE_PROMPT_VERSION, FIX_PROMPT_VERSION). The internal provider adapters (anthropicClient, openAiCompatibleClient) and the response-cache layout are not the contract.
@quantakrypto/qprobe The qprobe CLI (flags — incl. the ownership attestation --i-own-this/--owned-hosts — exit codes, output-format shape) and the programmatic API: runProbe, parseTarget, authorizeTargets, the classify/report helpers, and their types. The internal wire parsers are not the contract.

Non-API-but-still-contract surfaces — the qScan exit codes (0/1/2), the SARIF 2.1.0 output schema, the Sieve wire protocol, the baseline file format — are versioned too: changing them is breaking. The Sieve protocol additionally carries its own PROTOCOL_VERSION integer that bumps on any breaking wire change independently of the package version.

3. What counts as breaking on the core contract

A change to @quantakrypto/core is MAJOR (breaking) if it alters the meaning or shape that a consumer relies on. Concretely, breaking:

  • Removing or renaming any src/index.ts export — e.g. scan, scanParallel, walkFiles, toSarif, toJson, toCbom, formatSummary, buildInventory, remediationFor, verifyFix, detectors, vulnerableDependencies, the shared baseline surface (fingerprintFinding, applyBaseline, loadBaseline, saveBaseline), the offline agent-plane primitives (buildContext, buildTriageRequest, buildRemediateRequest, checkPatchPolicy, withWorktree, codemodFor, remediateFindings), loadConfig, and VERSION. (The re-export surface has grown ~3× since 0.1.0; packages/core/src/index.ts is the full list.)
  • Narrowing an input or widening an output type incompatibly — e.g. removing a Finding field, making an optional field required, or removing a member from the Severity, AlgorithmFamily, or FindingCategory string-literal unions.
  • Changing the shape of ScanResult, CryptoInventory, or a reporter's output object in a way existing consumers cannot read.
  • Changing the semantics of a stable field — e.g. flipping the meaning of an hndl flag, or changing the readinessScore formula (the score is a contract output; tweaks that move existing scores are breaking).
  • Changing SARIF output structure in a way a conformant consumer would reject.

Not breaking (MINOR or PATCH):

  • Adding a new src/index.ts export, a new optional Finding field, or a new detector (MINOR — new findings may appear; see the note below).
  • Adding a new member to an output-only union that consumers switch on with a default branch — treated as MINOR, and called out in the CHANGELOG, because a consumer that exhaustively switches may need a new case.
  • A detection accuracy fix (fixing a false positive/negative) that does not change any type — PATCH. Detection-result changes are expected within a major: new detectors and accuracy fixes mean the set of findings on a given codebase can change between MINORs/PATCHes by design. The data contract is stable; the set of findings is not promised stable, and baselines exist precisely to absorb that. This distinction is the contract.

4. Deprecation policy

We deprecate before we remove. The window scales with the change's blast radius.

  1. Mark — annotate the symbol/flag with @deprecated (JSDoc) and/or a runtime warning (CLI/MCP), naming the replacement. Add a CHANGELOG entry.
  2. Keep working — the deprecated surface keeps functioning for at least the window below.
  3. Remove — only in a subsequent MAJOR release, never in a MINOR/PATCH.
Surface Minimum deprecation window before removal
@quantakrypto/core public export / type field one MAJOR cycle, ≥ 6 months, whichever is longer.
qScan / Sieve CLI flag one MINOR with a deprecation warning, removed no earlier than the next MAJOR.
MCP tool or tool input field one MINOR announcing it; removal in the next MAJOR. Hosted clients get the longer of one MAJOR or 6 months.
Action input/output one MINOR with a warning in the job log; removal in the next MAJOR of the action.
Sieve wire protocol field bump PROTOCOL_VERSION; keep the prior version accepted for one MAJOR where feasible (SUTs are external code).
File formats (baseline, SARIF additions) additive only within a MAJOR; format removal/restructuring is MAJOR with a documented migration.

Security fixes are exempt from deprecation windows where a window would prolong an exposure: a P0 security change may change behavior in a MINOR (e.g. hosting filesystem MCP tools OFF by default), documented clearly in the CHANGELOG as a security-driven break.

5. Process

  • Every release updates the CHANGELOG ("Keep a Changelog" style) with an explicit Breaking section when MAJOR.
  • Breaking changes to @quantakrypto/core reference (or add) an ADR when they reflect a decision, not just a fix.
  • Releases are cut through the gated release workflow with npm provenance (see SUPPLY-CHAIN.md).