Unreleased
in master · unreleasedTracks work landed in master after the most recent published version.
When the operator runs npm version <bump>, this section is renamed
to the new version and a fresh [Unreleased] is opened.
Changelog · public · Apache 2.0
The substrate follows Keep a Changelog 1.1.0 and Semantic Versioning. v1.0 (2026-05-12) crossed the schema-stability lock — closed-enum vocabularies and canonical forms are stable from that release forward. Every entry below ties to a dated ADR + a queryable audit trail in state.json.
Latest release
Phase R closeout · the four pillars (mutation, Python port, OTS anchor, ops controls)
Read full notes ↓All notable changes to the Promethean substrate (living-constraints)
are documented here. The format follows
Keep a Changelog and the project
adheres to Semantic Versioning.
Pre-1.0 (v0.x.x): API is unstable; each minor bump may introduce
breaking changes. Operators pin exact versions. See NPM_PUBLISH.md
for publish discipline and bundle composition.
Tracks work landed in master after the most recent published version.
When the operator runs npm version <bump>, this section is renamed
to the new version and a fresh [Unreleased] is opened.
Phase R closeout · the four pillars (mutation, Python port, OTS anchor, ops controls)
Closes the three deferred reliability pillars + operational controls from v1.1.7. See ADR (xx) 2026-05-13-runtime-ai-v1.2-closeout.md. Phase R is operationally complete.
stryker.conf.mjs at
substrate root. Vitest runner. Mutator scope: the 4 Phase R modules
(runtime-ai-{spec,receipt-log,sdk,federation}.ts). Runs against
the 14 Phase R test suites. Thresholds: high: 90, low: 80, break: 75 — CI fails below 75% kill rate.
npm run mutation-test / mutation-test:incremental.
@stryker-mutator/core + @stryker-mutator/vitest-runner
added to devDependencies.runtime-ai-py/).
Full byte-identical parity with the TS canonical-form + Ed25519
sign/verify primitives. canonicalise_entry, sha256_hex,
sign_canonical, verify_signature, derive_public_key. Issue
31 integer invariants enforced (id/recordedAtMs/latencyMs as
integers, id >= 1, all ≤ Number.MAX_SAFE_INTEGER). R4
tenantId optional placement preserved. 8 fixture-driven
differential tests (test_cross_language.py) load the
JS-authoritative cross-language-vector-v1.json and assert
byte-identity of canonical bytes / SHA-256 / Ed25519 signature /
round-trip verify under JS-derived pubkey / tamper-detection /
integer invariants / tenantId placement.contrib/jarvis/src/runtime-ai-l12-anchor.ts —
anchorL12Head(logPath, options) submits the L12 HEAD into the
Bitcoin blockchain via the ots CLI when available, or writes a
deterministic mock proof in mock mode (tests + air-gapped
operators). Sidecar <logpath>.ots-history.jsonl (append-only,
one line per attempt, closed-enum status:
submitted-pending-bitcoin / mock-only / submission-failed /
no-op-cooldown). Real .ots proofs at
<logpath>.anchors/<headHash>.ots. 60 s cooldown idempotence
makes over-scheduled crons safe. Refuses to anchor empty or
broken chains. Companion verifyRuntimeAIReceiptLogWithAnchor
surfaces latestAnchor + totalAnchorAttempts +
currentHeadHasRealAnchor (mock anchors NEVER satisfy the
latter — regulator-grade). 12 new tests
(runtime-ai-l12-anchor.test.ts). CLI:
npm run substrate:anchor-runtime-ai-head -- <log-path>.docs/OPERATIONS_RUNTIME_AI.md.
Comprehensive runbook covering: key ceremony (air-gapped
generation, Shamir 3-of-5 backup, rotation via chained
co-signing, compromise response); HSM integration (PKCS#11,
YubiHSM 2, AWS CloudHSM, Thales Luna); filesystem hardening
(chattr +a, S3 Object Lock COMPLIANCE, auditd FIM, Wazuh/
OSSEC); multi-process coordination (single-writer architecture,
sharded chains, sidecar pattern); OTS cron cadence + .ots
upgrade workflow + air-gapped operator path;
Prometheus monitoring metrics + alerting thresholds; daily
verification job; DR runbook (L12 file loss, signing key loss,
Bitcoin reorg); cross-language port operational notes; §10 audit
checklist for regulator certification.examples/generate-cross-language-fixture.ts produces the
JS-authoritative runtime-ai-py/tests/fixtures/cross-language-vector-v1.json.
Run via npm run substrate:gen-cross-lang-fixture whenever the
TS canonical form is intentionally bumped (regenerates the
fixture so Python's pytest re-aligns).npx tsc --noEmit: clean.npx vitest run across the 16 Phase R suites: 243 passed, 2
skipped, 0 failed.pytest runtime-ai-py/tests/ reserved for CI
(Python toolchain not part of local substrate dev environment).Phase R reliability stack · "demonstrably airtight, not just claimed"
Four reliability primitives that prove the v1.1.x runtime-AI hardening rather than just claim it. See ADR (ww) 2026-05-13-runtime-ai-reliability-stack.md.
tests/unit/runtime-ai-golden-chains.test.ts)
— 6 deterministic reference chains with pinned hashes.
Regenerates from fixed inputs + fixed test key + fixed
timestamps and asserts byte-identity. Catches accidental
changes to canonicaliseEntry field order, Node version drift
in JSON.stringify, Ed25519 implementation drift, any silent
canonical-form regression. Regenerable via
GOLDEN_CAPTURE=1 npx vitest run ….tests/unit/runtime-ai-property-tests.test.ts) — 8 fast-check
properties: append-then-verify, tamper-detect, chain-extension
monotonicity, idempotent canonical form, integer-invariant
rejection.tests/unit/runtime-ai-differential.test.ts) — plain-JS
verifier matches TS verifier byte-for-byte on the same input.
The regulator-grade verify.mjs is independently testable.substrate:watch-runtime-ai) — long-running
process that polls + reports anomalies (broken chains,
malformed lines, signature failures, ID gaps, timestamp
non-monotonicity). Production observability without the per-
entry cost.All four shipped in v1.2 — see [1.2.0] entry above.
Phase R hardening v6 · internal "hammer the system" pass
Sixth audit round (1 internal + 5 external prior). 40 findings
closed across the Phase R surface. The code is hardened along every
dimension I or external auditors could attack it from. See PR #15
and the runtime-ai-r-hardening-v6.test.ts suite (25 tests
covering Issue 33 entry-size cap + Issues 17/24 hash-format
validation + Issues 11/13/15/23 chain-integrity surfaces).
RUNTIME_AI_DEFAULT_MAX_ENTRY_BYTES (64 KB default) —
Issue 33: refuse to append a serialized entry > limit.
Operator-tunable via maxEntryBytes. Prevents memory-exhaustion
attacks via a single multi-MB entry.RuntimeAIIdentifierValidationError — Issue 24: kebab-caseproductId, specId,
substrateId at SDK entry and as defense-in-depth in
appendRuntimeAIReceipt.RuntimeAIHashFormatError — Issue 17: lowercase 64-char hex
SHA-256 validation on specHash, inputHash,
outputCanonicalHash, and the sidecar lastHash.RUNTIME_AI_RESERVED_TENANT_PREFIX — Issue R4 follow-up: __
prefix reserved for substrate-internal scopes; real tenants
cannot claim names starting with __.idsContiguous + firstNonContiguousEntryId (Issue 11);
malformedLines array of structured MalformedLine records
(Issues 6 + 12 + 13); timestampsMonotonic +
firstNonMonotonicEntryId (Issue 23).RuntimeAIChainCorruptionError — refuses to append on top of
a chain with malformed lines. Operator must explicitly repair or
rotate before appending. Prevents silent extension over a
truncated entry.head.json rebuild path verifies the cached
lastHash against the actual JSONL tail before trusting it.appendRuntimeAIReceipt enforces monotonic nowMs (Issue 15) —
backdated entries are rejected at append time.proper-lockfile companion deferred to operational layer per
v1.2 OPERATIONS doc §5).Phase R · Runtime-AI containment (L12)
Extends the substrate's "AI as building material, not arbiter" pattern to the LLM calls inside emitted products. See ADRs (tt) / (uu) / (vv):
RuntimeAISpec primitive
(contrib/jarvis/src/runtime-ai-spec.ts). Closed-enum
category (classifier / extractor / summariser / scorer /
router / generator), modelIdentity (provider + model +
version), Zod outputSchema, optional reviewerGate, mandatory
fallbackBehaviour. The spec is the contract bounding every
runtime AI call inside an emitted product.runConstrainedAI SDK
(contrib/jarvis/src/runtime-ai-sdk.ts). Single entry point;
enforces the spec at request-time; emits an L12 entry per call;
invokes the fallback when the LLM output fails the Zod schema
or the reviewer rejects.contrib/jarvis/src/runtime-ai-receipt-log.ts). Mirrors L10 /
L11 shape: SHA-256 hash chain + per-entry Ed25519 attestation
(runtime decisions have no underlying signed object so the
entry itself must be signed). Covers specHash + inputHash
(PII-safe — raw input never recorded) + outputCanonicalHash +
modelIdentity + latencyMs + schemaValid + reviewerVerdictfallbackTriggered + prevHash + hash + attestation.
Head committed under L1 via state.runtimeAiReceiptLog.headHash.tenantId on L12 entries (kebab-
case ≤ 64 chars; reserved __substrate__ synthetic tenant for
single-tenant deployments; __ prefix reserved). Canonical form
omits the field when undefined so legacy single-tenant chains
hash byte-identically. Tenant-scoped verification and
summarisation. requireTenantField option for hosted-Author
deployments.RuntimeAIFederationClaim carrying
substrateId + headHash + entryCount + signedAt.contrib/jarvis/src/generators/runtime-ai.ts
emits product-side runtime-AI integration code from a
RuntimeAISpec.substrate:paysafe-runtime-ai-seed,
cliniclens-runtime-ai-seed, civicgate-runtime-ai-seed,
substrate:runtime-ai-demo,
substrate:verify-runtime-ai (regulator-grade chain
verifier CLI).id, recordedAtMs, and latencyMs are enforced as integers
(Number.isSafeInteger, id >= 1, all ≤
Number.MAX_SAFE_INTEGER). Closes the cross-runtime float-
serialisation drift class — JS's JSON.stringify(1.0) is "1"
but Python's json.dumps(1.0) is "1.0". Integer enforcement
means the cross-language port (v1.2) can be byte-identical
without runtime-language-specific number-formatting code.
Phase P close · v0.10–v0.18 omnibus
The v1.0 lock. Schema versions, canonical forms, and closed-enum vocabularies are stable from this release forward. See ADR (ss) 2026-05-12-v010-to-v10-omnibus.md for the full v0.10→v1.0 arc.
SubstrateComponentPolicy unattended;
signed AutonomousReflexiveCycleReceiptdiffSubstrateForecasts() per-metric
deltas including trend + confidence transitionsfalsifyForecast() closes the
epistemic loop (held / missed-above / missed-below / incomparable
per metric); heldHighConfidence regulator surfaceRegulatorySpec → derived
ProductSpec via 25-article mapping table across 7 frameworks
(GDPR, EU AI Act, PCI-DSS 4, ISO 27001, DORA, NIS 2, HIPAA);
hash-anchored DerivationProofs per article; from
"code-from-prompt" to "code-from-regulation"TargetStack closed-enum
(nextjs / python-fastapi / rust-axum); minimum-viable scaffolds for
Python+FastAPI and Rust+Axum alongside TypeScript+Next.jsbuildRunnableAuditBundle()
emits directory with bundle.json + verify.mjs (plain JS, Node
stdlib only, ~150 lines, zero external deps) + README; regulator
runs node verify.mjs, gets PASS/FAIL with no Promethean code; end-
to-end test spawns the verifier as a subprocessFederatedSignatureClaims signed under operator-specific Ed25519
keys; cross-substrate convergence detection at ≥ N distinct
substrates; NO CORPUS EXCHANGE — only signed signature summaries;
substrate becomes ecosystemtsc --noEmit clean throughoutFrom v1.0 forward:
promethean-*-1.0) are stable; bumping requires
ADR + migration path@promethean/verify,
@promethean/gap-detect, runnable bundle's verify.mjs) is stableEight numbered commitment layers + two receipt species, all anchored to a single Ed25519 trust anchor, externally verifiable, with portable audit bundle for offline regulator handoff.
state.json Ed25519 attestation (ADR z). Every substrate
state publication signed; verifier checks against
SUBSTRATE_ATTESTATION_PUBLIC_KEY.promotion-log.jsonl; head in state.json under L1.corpus.merkle.rootHash covering every promoted corpus entry.*.receipt.json with Ed25519 signature over the canonical form;
metaGeneratorLineage field (v0.3-4) commits to every meta-generated
generator that contributed to the product, with back-compat preserved
for pre-v0.3-4 receipts.signed-observations.jsonl with one signed entry per harvester
observation; state.signedObservations (per-stream counters) under L1.state-transparency-log.jsonl recording every state.json regeneration;
head in state.json under L1; silently rewriting past self-attestations
is detectable.state.timeAnchor
carries base64 OTS receipts; standard ots verify traces to Bitcoin
blocks; backdating past the anchor block becomes provably impossible.state.selfEvaluationLog head under L1 (v0.5-1 + v0.8-1 wire-in).substrate:verify-all run; audit conclusions
signed at point of recording (no underlying signed object to delegate
to); state.auditReceiptLog head under L1.state.substrateComponentLog head under L1, L7, L8
(v0.8-1 placed on partial so L7+L8+L1 all cover it).policyHash, detectionResultHash, every
proposal decision + reason; Ed25519 signing under L1 trust anchor;
signCycleReceipt + verifyCycleReceiptSignature mirror
signBuildReceipt.The substrate now authors substrate.
contrib/jarvis/src/meta-generator.ts):
GeneratorIntent → synthesizeGenerator() → deterministic .ts file
matching the canonical product-generator signature. POC: rate-limiter
v2 (172 lines, intentHash 9b2847ce…).intent-synthesizer.ts):
natural-language description → LlmClient.complete() →
structured-output prompt → validated GeneratorIntent → v0.1
deterministic synthesis unchanged. 3-layer defense in depth (JSON
extraction, shape check, validateIntent). Cost ~$0.04/intent.renderIntentForReview +
promptApproval): --review / --approve-stdin CLI flags gate
LLM-synthesized intents on explicit operator consent.generator-discovery.ts):
ProductBuilder scans contrib/jarvis/src/generators/ at runtime,
picks up meta-generated files with attestation sidecars,
registers them alongside the 54 hand-written generators.it.todo
stubs.metaGeneratorLineage field anchors NL→intent→generator chain
into the L4 build receipt's Ed25519 signature.capability-detector.ts): deterministic
capability-gap detector clusters uncovered corpus signatures into
proposed GeneratorIntents, returns sorted by composite score,
closed-enum 9-category taxonomy.capability-policy.ts +
autonomous-capability-loop.ts): operator authorises a
CapabilityPolicy once; nightly loop runs sandwich-gated synthesis
(cheap pre-LLM proposal check + expensive post-LLM intent check);
6-state cycle outcome; AutonomousCycleReceipt with cycleHash.self-build-evaluator.ts +
self-evaluation-log.ts): 8 deterministic structural checks on
emitted product output; L9 chain primitive mirrors L7 shape;
summariseQualityTrend returns rising/falling/flat/insufficient-data
with ≥3-entry threshold.signCycleReceipt /
verifyCycleReceiptSignature; L9 head in state.json under L1;
back-compat preserved (pre-v0.5 state.json re-canonicalises
identically).substrate-audit.ts):
substrate:verify-all walks every commitment chain in one pass
(L1 + L2 + L4 + L5 + L7 + L8 + L9 + AC); closed-enum LayerStatus
(pass/fail/skip); aggregate valid true iff every non-skipped
layer passes; read-only, no network, safe for CI gating.state.auditReceiptLog
head under L1; substrate:verify-all --append-to-l10 opt-in flag.substrate-audit-bundle.ts):
single self-contained JSON embedding state.json + every log + every
receipt + audit result + trusted public key; verifyAuditBundle
three-step (recompute hash + materialise + re-run live audit);
verifies after the original substrate directory is wiped — the
"verifiable disappearance contract."substrate-component-meta-generator.ts):
meta-generator now emits substrate components (modules under
contrib/jarvis/src/synthesized/), not just product generators.
L11 substrate-component-log with per-entry Ed25519. First synthesis:
corpus-trend-analyzer.ts (133 lines, intentHash ccc8e5c4…,
8 behavioural tests pass).buildSubstrateState
populates all three summaries on partial (not baseState) so
L7+L8+L1 all cover the heads simultaneously. Audit bundle embeds
the L11 log + the synthesized/ directory contents.substrate-component-policy.ts):
closed-enum gate for reflexive synthesis; conservative defaults
approve only utility + analyzer, forbid escape-vector imports
(node:child_process, worker_threads, vm), 200-line cap.lineage-chain-summarizer.ts
(150 lines, intentHash 52bde153…) — substrate component that
analyses the L11 log itself. Proves the reflexive pattern repeats.
6 behavioural tests against real appendSubstrateComponent chains.Factory output unit lifted from product to portfolio.
PortfolioSpec above ProductSpec with sharedEntities,
regulatoryScope, mission fields. One operator engagement =
one portfolio = N coordinated products sharing entities + regulatory
scope + mission anchor.PortfolioBuilder validates collisions, reconciles shared
entities, calls ProductBuilder per child, emits portfolio-level
README + manifest.PortfolioReceipt anchors N child BuildReceipt hashes +
shared-entity manifest under one L1 Ed25519 signature.verifyPortfolioReceiptCrossChild recomputes child hashes
for cross-child verification.Seventh evidence stream: maintainer-authored fix narratives from React/Next/Vue/Django/FastAPI/Express/Stripe/node-postgres release notes. The editorial layer complementing §47/§54/§54.1/§56.1/§68/§62.
CWE_ANTI_PATTERNS table
(no LLM dependency).llm-patchnote-extractor.ts) closes
false-negative gap; ~$0.34 per 8-library harvest, ~$4/year monthly
cadence.ProvenanceClass library-patchnotes (repos prefixed
patchnote:); 7th StreamId with trust weight 0.88.npm run harvest:patchnotes.substrate:autonomous-cycle CLI runs one unattended capability-
loop cycle under operator-authorised CapabilityPolicy; emits
signed AutonomousCycleReceipt.substrate:self-evaluate CLI runs 8 structural checks on a
product directory + appends to L9 chain.substrate:verify-all CLI walks every commitment chain in
one pass; exit 0 (all pass) / 2 (any layer failed) / 1 (usage);
--json mode + --append-to-l10 flag.substrate:audit-bundle build/verify CLI produces or verifies
portable regulator-handoff bundles; verifies offline after the
original substrate directory is wiped.substrate:capability-detect CLI runs the deterministic
capability-gap detector against a corpus + coverage set.substrate:component-synthesize CLI synthesizes a substrate
component from an intent + optionally appends to L11.tsc --noEmit clean.to be released
Initial public release. Captures the substrate's empirical-correctness
layer + the §63 gap-detector consumer artifact at the state proven
out across the multi-repo trial (see TRIAL_REPORT.md).
AuditKinds
spanning constraint lifecycle, evolution, healing, governance,
publish verdicts, harvest pipeline.EventBus adapterProductionRuntimeEmitter for closing the producer-side loop
from real Jarvis production runs back into the corpus.bin/promethean-gap-detect with flags
--include-anti-patterns, --include-cwe-coverage,
--include-regulatory, --include-architecture, --all,
--corpus, --allowlist, --no-allowlist, --max-gaps,
--sarif, --json, --quiet. Severity-ordered output, exit
codes 0/1/2/64/70.cli/sarif.mts): GitHub Security tab
compatible. Severity → SARIF level mapping (critical/high → error,
medium → warning, low → note)..github/actions/gap-detect):
composite action with fail-on threshold, SARIF upload, allowlist
auto-discovery. Used by the substrate's own CI for self-scan..promethean-allowlist.json auto-
discovered. Six gap kinds supported. Wildcard match patterns
(axe-*, GDPR Art. *). Each entry requires kind, match,
reason, reviewer, reviewedAt. Documented in the action's
README.package.json keywords
/ topics / pyproject.toml / file paths. Framework detection
(FastAPI, Django, React, Next.js, Vue, Express). UI detection
for axe-core scope. Test-file walker (slash-pattern + suffix-
pattern, per isTestFile).coverageByLanguage breakdown per
detected language (§63 v3: filters to languages the repo actually
uses, no phantom buckets).null when applicable subset
is too small (< 5).import / export from / dynamic
import() / side-effect imports. NodeNext .js → .ts rewrite.
Self-edge filter for generator-style template-literal false
positives.import foo / from foo import bar
including relative dots (from . import x, from ..parent import y). Heuristic absolute-import resolution via package-root walk.vendor/ and _test.go excluded (matches go build semantics).import type { X } from '...', import type X from '...', and import type * as X from '...' are excluded from the import graph. Type-only imports
get erased by the TS compiler before runtime, so they cannot
create the runtime initialisation cycles, ESM hoisting issues,
or build-time slowness that §64 was written to catch. Matches
the default behaviour of madge / dpdm.LineageTracker, ConflictDetector, ConflictResolver,
HealingLearner, ProvenanceGraph.The §64 self-scan against the substrate's own source surfaced four
real circular-import SCCs. All four were closed in code via the
"extract shared types into a tier-0 module" pattern, leaving the
substrate's --no-allowlist self-scan with zero architecture
violations — the first time ever. See TRIAL_REPORT.md for detail.
| Cycle | Files | Pattern | Commit |
|---|---|---|---|
| harvest 2-cycle | constraint-promoter ↔ harvest-feedback | harvest-types.ts |
6aaba9d |
| sensor 2-cycle | market-eyes ↔ omnisense | market-types.ts + text-utils.ts |
dfb261c |
| cortex 4-cycle | cognitive-loop ↔ planner ↔ counterfactual ↔ history-advisor | cortex-types.ts |
8e3289b |
| kernel 5-cycle | pool ↔ engine ↔ conflict ↔ learning ↔ provenance | §64 v0.4 type-only exclusion + import type |
9aae8f0 |
TRIAL_REPORT.md)Tested end-to-end against four real external EU-relevant repos: prowler-cloud/prowler (Python + TS, Django + React monorepo); plausible/analytics (Elixir + JS); laurent22/joplin (TS + React); forgejo/forgejo (Go + Vue). Architecture detector verified clean on prowler (5,878 .py files, 10,510 resolved edges, 0 cycles) and forgejo (4,000+ .go files, 0 cycles excluding tests).
The substrate's own .promethean-allowlist.json documents 11
absence-of-applicability decisions covering ~18 individual findings.
Each entry has a written reason + reviewer + date. None are
architectural debt; all are "this rule does not apply because…"
(no XML parsing → no XXE; no public web endpoints → no open-redirect
surface; no AI Act Art. 5 prohibited practices; etc.). Operators can
copy this file as a starting point for their own repo's allowlist.
140 test files, 5,808 tests, all passing. Build clean. Type errors
zero. CI runs build / test / lint / type-check / self-scan on every
push and PR (fail-on: critical).
Canonical source
substrate/CHANGELOG.md ↗Per-release ADRs
docs/adr/INDEX.md ↗Security disclosures
SECURITY.md ↗