pnpm install --frozen-lockfile (used by CI, including the examples gate) fails
because the lockfile drifted from the workspace package.json files:
- reactor-cli pins @openprose/reactor as workspace:* in the lockfile but
workspace:^ in package.json.
- reactor-evals is a workspace package but was never recorded in the lockfile.
Regenerated with the pinned pnpm 9.15.0 via pnpm install --lockfile-only.
pnpm install --frozen-lockfile now passes.
Live render path validated end-to-end on OpenAI gpt-5.4-mini direct (real
metered receipt 36/4/40) after the OpenRouter key hit its limit. Per
decision, the shipped headline is the deterministic, price-independent
174.71x fresh-token fold; the full metered N=1 dollar bill is a bounded
follow-up, not fabricated. Updates live_n1, model_pin, and limitations note.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The U12 poison guard used text.includes('256:0'), which false-matched the
'sha256:0…' content-hash prefix saturating every receipt ledger — so the
gate exited 1 on the committed runs-sample. Match poison tokens only when
they stand alone, so a reused FIGURE is still caught but a hash digest is not.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The '2026 H2' target was an unratified placeholder. Replace with 'tracked
but not yet scheduled (C3)' at the three disclosure sites so no public
artifact commits to a quarter that isn't on the roadmap.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A live provider 403 ('Key limit exceeded') echoes the key's SHA-256 in an
openrouter.ai/.../keys/<hash> management URL — a key fingerprint that reached
test output / CI logs. Add redactSecrets/redactError (scrubs sk-* key
families, Bearer/Authorization headers, /keys/<hash>, and bare long-hex
fingerprints) and apply at the two render error chokepoints (render-backend
re-throw + smokeRun). 7 redaction unit tests with fully fabricated fixtures;
verified the real BYO live 403 now surfaces as .../keys/***REDACTED***.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New packages/reactor-evals/ — preregistered, equal-correctness-gated
offline benchmark minting the first measured 'cost scales with surprise'
result (~174x fewer fresh tokens than an equal-correctness cron at lambda=1%,
decaying to 1.36x at lambda=1.0). Deterministic ledger, 30/30 chain-verified
receipts, poison-grep + decidability guards. Authored against the public
SDK barrel; spec + reactor/src read-only. U10 live dollar-run is operator-
gated (follow-up).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace both arrival-order FIFO drains (drain/drainAsync) with a
compile-time height-ordered, dirty-input-count-gated drain so a staggered
unequal-path diamond renders its join once per settled wave (kills the
double-render glitch reproduced live in masked-relay). reconcile/
reconcileAsync + single-flight guard reused byte-for-byte; public API
unchanged; no spec edit. 11 new red-first regression tests (sync+async).
Closes#132.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mints the first preregistered, equal-correctness-gated measurement that Reactor's
fresh-token spend scales with surprise, not time. New packages/reactor-evals/
authored against the PUBLIC @openprose/reactor barrel (EVALS.md discipline);
spec/ and packages/reactor/src/** read-only.
Headline (deterministic offline ledger): at lambda=1%, Reactor spends ~174x fewer
fresh tokens than an equal-correctness cron; the fold DECAYS with the change-rate
(~1390x at lambda=0 -> 1.36x at lambda=1.0). Per-tick fresh regresses on the
PREREGISTERED material-change indicator (slope=30, intercept~0, permutation
p~1e-4); the null 'spend tracks wall-clock/event-count' is rejected for Reactor
and not for the cron. Every cost row gated to equal correctness vs the oracle.
Units: U1 deterministic-cost-v1 (preregistered surrogate); U2 lambda world-gen +
material projection + labels + oracle; U3 sweep (real reconciler, per-tick fresh
off the receipts); U4 six contestants (reactor/oracle-cron/content-cache/
no-memo/byte-diff/react-loop); U5 prereg hashed before any run; U6 scorers
(surprise-cost regression + permutation test, propagation #2, amortization #9,
gateCommit #6, per-node chain-verify); U7 equal-correctness gate + regime matrix;
U9 offline invariants #4/#5; U11 report + hero figure + suite CLI; U12 poison-grep
+ decidability guards. 30/30 cells chain-verified; 8/8 unit tests pass; prereg
hash + REPORT.md byte-stable across runs.
Deviations/blocked (honest): .cjs not .ts (toolchain availability; layout matches
the PLAN 1:1); U10 real N=1 LIVE run BLOCKED (no OPENROUTER_API_KEY) and never
fabricated; U8 long-horizon + U9 #8/#12 scaffolded; baseline coincidences flagged
in REPORT.md. Full runs/ (87M) gitignored (byte-deterministic, regenerable);
runs-sample/ commits the headline pair as a frozen chain-verifiable replay.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The arrival-order FIFO drains rendered a recombinant (diamond) join with
UNEQUAL path lengths TWICE: once prematurely against a half-propagated input
set (a glitch — the short edge moved, the long path still stale), then again
once the long path settled (a redundant render). "Cost scales with surprise"
(Invariant 5) visibly failed for that topology — reproducible live in the
shipped masked-relay demo.
Replace both `drain` and `drainAsync` with a compile-time height-ordered,
dirty-input-count-gated drain (Minsky / self-adjusting computation): a node
fires exactly once, in ascending height, only after every dirty producer has
SETTLED — so a join renders once, against fully-settled inputs.
- `computeHeights` + producer/subscriber adjacency, derived once per epoch from
the frozen topology edges ∪ entry_points (NOT topology.nodes, which is [] in
the IR). Cycle-guard throw kept; static-topology marker left for the fixpoint.
- One shared `startFrontier` core (PASS-1 dirty closure + dirty-count, the
height-ordered ready pick, settle-based decrement, move-aware prune) drives
both the sync and async loops; only the render call differs. `reconcile` /
`reconcileAsync` — including the per-node single-flight/coalesce guard — are
reused byte-for-byte. Async awaits each fire fully before advancing the
frontier (closes the await-frontier gap); stays serial (no Change-B parallelism).
- Settle-based (not move-based) decrement so a memo-skipping producer never
starves a join; move-aware prune so a no-change re-drain renders zero and
mints only the seed's skip; interior-seed gate so a directly-woken interior
node still waits on its dirty upstreams.
Public API unchanged; no caller edits (drain returns fire-order, not FIFO —
audited: no consumer asserts arrival order). No spec edit.
Tests (red-first; the primary demonstrably failed on the pre-fix FIFO drain,
E=2 with a glitch, proven in a scratch build): staggered unequal-path diamond
(sync + async) → join renders once against settled inputs; symmetric equal-path
control; no-change re-drain → zero renders / one seed skip; two-seeds-on-one-
chain interior-seed gate; 3-deep prune-no-deadlock; computeHeights height
assertions + forged-cyclic-topology throw. Full @openprose/reactor suite green.
Refs: planning/plans/2026-06-07-mk1-drain-fix/PLAN.md; backlog MK-1;
prototype planning/ideation/minsky-experiments/c2-topo-drain/.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Align the public artifacts with what npm and the code actually deliver — the
seams the 2026-06-06 investor-DD fanout independently verified as overstated.
Presentation/disclosure only; no runtime, invariant, or spec edit.
- IDD-vers: fix the two stale "live on npm" version callouts to reactor 0.3.1 /
CLI 0.2.2 (devtools 0.2.0 unchanged); reactor README "ideal surface" 0.3.0->0.3.1.
- IDD-reuse (+G27): devtools --describe COST ROLLUP now leads with the defensible
memo-skip count and demotes provider-prompt-cache `reuse=%` to a labeled
secondary line ("provider-reported; can be 0% on the default model"); test added.
- BR-F7 (+G10): dated cryptographic-signer roadmap line (targeted 2026 H2, tracked
as C3) at the three null-signer disclosure sites + the tamper-evident-not-proof
threat-model sentence. Also fixed the broken `@openprose/reactor/sdk` subpath
cites in the devtools README -> root `@openprose/reactor` (NOT `/internals` as
the plan said; these symbols are root exports), and the non-public
`new FileSystemReceiptLedger` -> the public `createFileSystemReceiptLedger`.
- IDD-footprint: rewrote the "Air-gapped?" note + added a quickstart footprint
line with the measured ~99 MB / ~100 packages (2026-06-06), preserving the
true SDK-core zero-dep claim.
- IDD-skew: ranged the devtools/CLI `@openprose/reactor` workspace ref
workspace:* -> workspace:^ (pnpm pack now emits ^0.3.1, verified) so npm
dedupes one SDK copy. (Republish of devtools 0.2.1 still required to land it on
npm — separate release action.)
Gate: pnpm --filter @openprose/reactor-devtools test green (96/96).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes the prose-CLI scrub the spec already documents as shipped: deletes tools/cli (the @openprose/prose-cli Oclif binary + eval harnesses), drops tools/cli from the workspace and lockfile, and removes the separately-authored `### Criteria` section from the reactor and reactor-cli contract loaders (postconditions live solely in `### Maintains`). Updates the accompanying skill tests, changelog, and release docs. Verified green: reactor SDK 458/0/10, reactor-cli 186/1 (pre-existing doctor test), devtools 96/0, skill 413/0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repairs surfaced by an independent code-grounded verification pass. 00: cost is observed-not-budgeted (not 'resource budget the gates are constrained by'); Tenet 2's intelligence layer lists all three model-authored compile artifacts (Forme topology + canonicalizer + postcondition validators). 01: state the `### Invariants` actuation-boundary ideal in Part I (with a bridge note it is authored-only today); gateway compiles to a trigger the reactor serves (not `prose serve`); migration line corrected (`co` has no `kind: responsibility`; std has 3); note the language-root `receipts.jsonl` vs the harness `receipts.json`. 02: launch DoD no longer implies version-equality; new Part III §10 (declared-capability resolution + serve auth + async storage seam) so every Honest-Limit has a forward item. 03: signer rendered as shipped (`scheme: "none"`, no `kind:"null"|"signed"`); Part II honest that `### Tools`/`### Environment`/`### Skills` are name-only and not harness-consumed; `as_of` added to the gap-cluster-2 receipt set; gateway `### Schedule` forward item; no `reactor test` subcommand.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconcile the OpenProse spec so Part I states the implementation-agnostic ideal, Part II matches shipped code, and Part III is a real actual->ideal path. Memo key stated as the 3-tuple (shipped 2-tuple as a bridge note); ideal receipt schema gains as_of + failure reason + author-addressing; precedence-stack scope and commit-gate pillar reconciled across 00/02/03; prose-CLI and `### Criteria` residue removed from the ideal; Part III re-baselined off shipped reality (the corpus migration retired as done) with the receipt-shape and actuation gap-cluster items added so every Part II limit has a forward item.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the agent-observatory Reactor learnings as authoring doctrine,
scoped to multi-node Reactor pipelines so they are not over-applied.
guidance/authoring.md gains a `## Cost and Context Discipline` section
(tier with a cheap gatekeeper; bound each narrow render to its inline
input; validate the cost-shape; keep renders cheap-model-small) plus
four matching anti-patterns. SKILL.md's Authoring Guidance points to it
for continuous / fan-out / high-event-volume pipelines.
Opens with an explicit trigger and a Tenet-2 caveat: it applies to the
narrow-transform renders that dominate a pipeline's volume, not to
one-shot functions or single responsibilities, and a render whose job is
to explore should still explore. CLI/version gotchas are deliberately
left to reactor.md, not authoring doctrine.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The "Inbound email as a trigger" group was authored before the README index was
restyled to use a colon (not an em-dash) between each example link and its
description. Align the three bullets (support-inbox-router, feedback-pulse,
press-desk) to that convention. Cosmetic only.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(examples): inbound primitive.dev email as a Reactor trigger (3 examples)
Wire a primitive.dev email inbox in as an external-driven gateway and keep a
downstream world-model current from what arrives. Three distinct reactor shapes,
each shipping the full validity contract (committed replay/ + deterministic
tier-2 offline test) plus a key-gated tier-3 LLM-as-judge live test.
- support-inbox-router (marquee): a cheap-model spam/content filter + a faceted
router whose facets are channels. A per-email triage drops spam (its `routed`
facet stays the fixed NULL token, so junk lights nothing) and tags ham to a
channel; the router catalogues one facet per channel (bug-reports,
feature-requests, docs-questions, billing) so a docs question wakes ONLY the
docs-gap tracker, never the bug board. `billing` has zero consumers on purpose
(a facet is a subscription symbol). The docs-gap tracker feeds the agent-native
docs / llms.txt surface.
- feedback-pulse: rollup aggregation + self-driven weekly `valid_until`
freshness; the brief refreshes on cadence even when the inbox is quiet, at zero
tokens on an unmoved rollup.
- press-desk: a deterministic human gate (gateCommit: needs_human,
auto_reply:false) + a privacy projection facet that keeps sender PII out of the
public view by construction.
Tier-2 offline: 45/45 new tests pass, byte-deterministic, chain-verifying; no
regression to the existing suite. Tier-3 live tests passing-skip offline and run
the render on a cheap model with a smart judge model when keyed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(examples): validate tier-3 LLM-judge live tests on direct OpenAI
OpenRouter is over its account spend cap, so point the three live tests at the
OpenAI Chat Completions surface directly with OPENAI_API_KEY: the render-under-
test runs on the cheap model (gpt-5.4-mini) and the rubric judge on a smarter one
(gpt-5.5), both via the same key. gating now resolves OPENAI_API_KEY (process.env
then the .env at REACTOR_ENV_PATH, honoring REACTOR_OFFLINE) and the body still
passing-skips offline. temperature pinned to 1 (the gpt-5.x models reject 0).
All three live tests pass live at reliability >= 0.8 across their labeled sets
(support-inbox-router spam/bug/feature/docs, feedback-pulse themes, press-desk
relevance/kind/no-PII-leak), grounding guard held. Offline gate unchanged: 45/45
tier-2 pass, live bodies passing-skip.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Frame OpenProse as a declarative language: you declare the ideal world
state, the Reactor keeps it true. Make that the spine across both layers
and present cost-scales-with-surprise as its consequence rather than the
headline. Sweep em dashes for a cleaner read.
The open-prose skill ships as a plain folder, so everything under
skills/open-prose/examples/ reaches every install. Each runtime example
shipped a committed replay/ state-dir (around 480 binary world-model files), a
generator, and a test suite wired to the workspace through a dist alias with no
local package.json. That machinery is internal validation, not the template a
user lifts: it cannot run from a copied folder, and it shipped generated
artifacts nobody should copy.
Keep the shipped examples to what a user actually adapts, and move the
validation into the repo's test tree:
- Move each example's tests, generator, and committed replay/ into
tests/open-prose/examples/<name>/. The shipped example is now its .prose
contracts under src/, a README, and a .gitignore.
- Re-point the vitest include and the test scripts; the byte-deterministic
offline coverage runs unchanged, just rooted under tests/.
- Rewrite the example READMEs to point at the reactor CLI for producing and
replaying a run, and drop the stale committed-fixture sections.
- Update the examples-gate workflow description to match the new layout.
No language, CLI, or runtime behavior changes, and the example contracts are
untouched. Verified with the offline gate (REACTOR_OFFLINE=1): the conformance
suite, the relocated example tests, and the eval harness all pass.
* fix(cli): typecheck repository-reactor-bridge test against branded Receipt fields
#106 hard-branded the reactor Receipt identity fields (node: NodeId,
contract_fingerprint / fingerprints: Fingerprint) and added this bridge test in
the same commit, constructing the Receipt fixture from raw strings — so the test
was born failing tsc. CLI Release Check only runs on tools/cli + release-script
paths and main has no required checks, so #106 merged with the typecheck red and
it stayed hidden (no cli-path change re-ran the check) until a release-infra PR
surfaced it.
Author the fixture with the same brand constructors the production bridge uses
(asNodeId / asFingerprint from @openprose/reactor/internals). The constructors are
identity-at-runtime brands, so behavior is unchanged: the affected test passes
10/10 and tsc is clean.
Note: this unmasks a SEPARATE pre-existing failure, also from #106 — the
repository-ir compiler fixtures were regenerated with kind
"openprose.compile-phase-ir" while validateRepositoryIr and its tests still expect
"openprose.repository-ir" (23 failing tests). That is a distinct IR-reconciliation
fix, tracked separately.
* fix(cli): restore repository-ir v0 validator tests with CLI-owned fixtures
#106 migrated the SKILL compiler's golden outputs (repo-root
tests/open-prose/compiler/) from repository-ir v0 to compile-phase-ir v2, but the
CLI's own compile path (compileRepositorySource -> validateRepositoryIr ->
repositoryIrToTopology) stayed v0. repository-ir.test.ts and
responsibility-status.test.ts borrowed those golden files across the package
boundary, so the v0 validator was being fed v2 inputs -> 21 failing tests.
Give the CLI's v0 validator tests their OWN v0 fixtures under
tools/cli/tests/prose/fixtures/repository-ir/ (recovered from f12dcda~1, the last
commit before the migration; the CLI compiler and validator are unchanged since,
so they still describe the current contract). The two compilers no longer share
fixtures: the SKILL compiler's compile-phase-ir fixtures are validated by
compiler-ir.test.ts; these repository-ir v0 fixtures are the CLI's. A README in the
fixtures dir documents the split and the migration path.
No validator or compiler change (not papering over) — the v0 validator is simply
fed correct v0 inputs. tools/cli suite: 573 -> 594 passing; the v0 validator suite
is 30/30. The 2 remaining failures (quickstart's dangling deleted-demo reference
and the agent-observatory example's missing id) are unrelated non-IR #106 fallout,
tracked separately.
* chore: deprecate prose-cli npm publish flow; park the eval suite
The `prose` CLI (@openprose/prose-cli) is deprecated in favor of the reactor
harness (@openprose/reactor + @openprose/reactor-cli) and the SKILL/plugin. This
removes its npm publish flow (it will be marked deprecated on npm manually) and
parks the eval harness out of the working tree.
Rip out the prose-cli publish flow:
- delete .github/workflows/{release,cli-release-check,cli-real-harness-smoke}.yml
and scripts/release-preflight.sh (the "OpenProse Release" publisher + its
preflight/checks).
- drop the `cli` track from .version-bump.json (only the skill/plugin track
releases here now) and the prose-cli sections from RELEASE.md.
- decouple the root build/test/lint scripts from @openprose/prose-cli.
Park the eval suite (it is rethought from scratch in the reactor backlog):
- remove the judge-era harness tools/cli/src/evals (45) + tools/cli/tests/evals
(18) and spec/04-Evals.md; they are copied verbatim into the planning
backlog-reactor for rehydration, and the methodology is synthesized there.
The harness was import-isolated (no code imported it); removal breaks nothing.
- fix the now-dangling spec/02 cross-reference to 04-Evals.md.
- remove the obsolete quickstart.test.ts (it read a #106-deleted demo test file).
The reactor packages, the new reactor-native tools/eval-harness, the skill
examples gate, and plugin-manifest are unaffected; prose-cli still typechecks.
Re-skin the keyless DevTools replay SPA onto the apps/run design system's
"Reactor monitor" machine surface (DESIGN.md §1/§4 name it as a sanctioned dark
machine surface): a flat charcoal ground, single-voice self-hosted JetBrains
Mono, gold as the one brand accent, 1px hairlines + small radii + one soft
shadow framing, three-dot window chrome, and always-labeled status.
- Machine palette (variable NAMES preserved so app.js + every selector keep
working; only values changed): --bg #1a1c22 flat (radial gradient removed,
per "no gradients"), machine-bar chrome bars, machine-fg/dim text, white-alpha
hairlines.
- Disposition + wake-cause hues mapped to the machine signal palette, kept
distinct AND labeled (never colour-only): render = machine-ok green,
active/lit path + per-facet edge-light + cost-fresh + external-wake =
machine-gold, memo-skip = machine-dim grey, fail = machine red (deepened for
AA on charcoal), self-tick = labeled violet.
- Self-host JetBrains Mono (400/500/700 woff2, latin subset, ~65KB) under
src/public/fonts so the machine surface is the real face, offline + keyless.
- Fix copy:public to recurse (fs.cpSync) so the new fonts/ subdir builds and
ships (the old non-recursive copy threw ENOTSUP on a subdir).
Scope: CSS + index.html + fonts only. No app.js logic changes; all class names
and animation hooks preserved, so replay/scrub/animation behaviour is identical.
Verified: pnpm build + typecheck pass and the built server serves /app.css and
/fonts/*.woff2 (200).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Astro `reports` app (formerly apps/reports in openprose/platform,
publishing to reports.openprose.ai) is gone, leaving only this stale
`docs/reactor/v0.1/` content and a README describing a dead publishing
pipeline. The canonical documentation now lives at the Next.js/Fumadocs
site https://docs.openprose.ai (repo openprose/docs), which carries the
reactor technical report and architecture docs.
Removes `docs/` entirely and repoints the README's technical-report link
to the live docs site.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A Claude-Code session scanner piped into domain world-state. A cheap classifier
(session-signal) fans per-domain signals into four maintained truths
(decisions-log, eng-backlog, use-case-guide, attention-queue) and a coalesced
dashboard, so cost scales with surprise: a session moves only the domains it
touches; the rest memo-skip.
- 7 contracts + reactor.yml (OpenAI gpt-5.4-mini renders, gpt-5.4 compile),
inline-flow static fixtures, opt-in real scanner (connectors.cjs.example),
README + PIPELINE-DESIGN.md.
- Committed replay/ from a captured run (11 rendered, 2 skipped, 0 failed,
~38k fresh tokens) so the reactor eval-harness is reproducible.
- eval-harness: additive, env-gated Anthropic judge (JUDGE_PROVIDER=anthropic
+ JUDGE_MODEL, default claude-opus-4-8) via the CLI's native-Anthropic provider
builder. Default OpenRouter behavior unchanged; REACTOR_OFFLINE still forces
judges off. Eval result: 2/2 grade A (deterministic + opus judge).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The SKILL, the plugin manifests, and the prose CLI were pinned to one shared
X.Y.Z by an earlier "unify release flow" change. Nothing couples them at runtime
— the skill carries its own runtime_contract compatibility signal — so the
shared version was process convention, not necessity, and a partial bump
(SKILL.md 0.15.0 vs everything-else 0.14.0) was stranding the Plugin Manifest
gate red on main.
Split .version-bump.json into two independent tracks:
- skill: both plugin manifests + SKILL.md, locked together (the plugin
marketplace dedupes by manifest version, so a skill change only reaches plugin
users when the manifest advances).
- cli: @openprose/prose-cli + install.sh.
bump-version.sh becomes track-aware (--track <name> <X.Y.Z>, per-track --check,
--list); release-preflight.sh validates only the cli track so a CLI release is
no longer blocked by the skill version. RELEASE.md documents both tracks and the
skill release flow; CHANGELOG gets a 0.15.0 skill entry.
Release the skill track at 0.15.0 (plugin manifests 0.14.0 -> 0.15.0; SKILL.md
already there): the Intelligent React overhaul, runtime_contract 1 -> 2. The CLI
stays 0.14.0. Clears the red Plugin Manifest check.
Closes the 3 critical Dependabot alerts (one advisory, GHSA-5xrq-8626-4rwp, CVSS 9.8). vitest is a devDependency; both configs run environment: node only. Offline gate verified green on the 3→4 bump. Resolved a pnpm-lock.yaml conflict with main by regenerating from main's base.
Adds a forward-looking paragraph to §9 ("Deliberately not yet here"): the
authored source need not be text. Because compile is an intelligent render
and Forme's topology is itself a world-model, intent can arrive as a typed
image that the compile resolve inverts into `.prose.md` contracts — well-
typed by whether it compiles to an acyclic, round-trip-stable graph. Framed
honestly as a direction specified in the skill, not a shipped runtime path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds `visual-source.md` to the open-prose skill: a pixel-only image that
an intelligent compile *resolve* turns into Prose contracts. A multi-node
image is a visual projection of a Forme topology world-model; inverting it
reconstructs the `### Requires`/`### Maintains` graph. The image sits one
rung above Contract Markdown — a brief, not a binary — and is "well-typed"
by compilation succeeding, not by a parser: `prose compile <image>` is the
typechecker (acyclic + round-trip-stable).
Defines the type (conceptual, checked by compile), three scope tiers
(system / single responsibility / single function), and three requirement
tiers (required structural skeleton; pin-or-interrupt for safety-bearing
freshness/postconditions; elaborated goal prose the resolve authors and a
human ratifies). Wires it into SKILL.md (Format Detection, Command Routing
for compile/run/react, First 90 Seconds, File Locations) and cross-links
forme.md.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds `react` to the prose CLI command model so `prose react "<use case>"`
is a first-class forwarded command alongside run/serve/write — consistent
with the open-prose skill's `prose react` routing (reactor.md) added in #112.
- command-model.ts: add `react` to the CommandName union, supportedCommands,
and usageByCommand; validate `[use case...] [--start]` (free-form text plus
an optional --start flag; reject unknown long options and duplicate --start).
canonicalPrompt forwards `prose react <args>` to the agent unchanged.
- commands/index.ts: register the `react` forward command (auto-wired into the
command registry).
- command-model.test.ts: forwarding + validation cases for react.
- CHANGELOG: Unreleased entry.
Default forwards the reactor commands for the user to run; `--start` drives
the live lifecycle. Validated: command-model test (53 passing) + my files
typecheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Anthropic's OpenAI-compat endpoint is documented as testing-only and ignores
response_format, so it rejects Reactor's JSON-schema structured outputs with
400 response_format.json_schema.strict. That made `provider: anthropic` a
footgun for the structured compile/render path (compile + render are both
structured, and renders drive tools).
Route the built-in `anthropic` provider through the official @openai/agents
AI-SDK adapter over @ai-sdk/anthropic (native Messages API), where structured
outputs and tools both work. Mechanism:
- ProviderPlan gains a keyless `transport` discriminator (openai-compat |
anthropic-native); the anthropic built-in resolves to anthropic-native. The
module stays keyless, so the offline boundary holds.
- live-provider builds an AI-SDK-backed ModelProvider for that transport; every
other vendor keeps the scoped OpenAIProvider compat path. Both are scoped (no
global mutation). The compile/run/serve call sites are unchanged.
- doctor --live smokes the native provider for an anthropic project.
- A new gated live test drives a structured render + tool through the native
adapter (proven live: structured output parsed + tool called); it offline-skips
like every live test. The reactor BYO live test notes the compat subtest is
plain-text reachability only.
Bundles @openai/agents-extensions, ai, @ai-sdk/anthropic as CLI deps so an
installed reactor needs no extra setup. reactor-cli 0.2.1 -> 0.2.2.
The open-prose skill described Reactor as a concept but never taught the
real `reactor` binary (`@openprose/reactor-cli`, live on npm) or how to
stand a Reactor up. This adds that path end to end.
- New `reactor.md`: operator guide for the `reactor` binary — global
install, the keyless-vs-live boundary, the `compile → run → serve`
lifecycle, `reactor.yml` (connectors, sandbox, ask-the-user-for-model),
the `prose react` playbook, and the keyless `reactor-devtools` replay.
- SKILL.md: route `prose react [use case...] [--start]`, add a
First-90-Seconds row, register `reactor.md`, and note the one case where
an agent *does* shell out — the `reactor` binary is a deterministic host,
not a wrapper. Also fixes a mashed-together File Locations table row.
- help.md: surface `prose react` in Available Commands and the goal-true path.
Default behavior prints the `reactor` commands for the user; `--start`
drives the live lifecycle directly.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The readme-header.png render had overlapping headline text. Point the
README header at the opengraph-image route instead.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reactor was hard-wired to OpenRouter on the CLI (only OPENROUTER_API_KEY was
ever read), stranding users holding OpenAI / Anthropic / Google keys. The SDK
already supported a scoped provider; this makes it real and elegant at the CLI.
reactor-cli (0.2.0 -> 0.2.1):
- reactor.yml model.provider now switches the live provider; built-ins
openrouter|openai|anthropic|google resolve their endpoint + key env, and any
OpenAI-compatible vendor works via model.base_url + model.api_key_env.
- A keyless ProviderPlan resolver + a model-bearing OpenAIProvider factory
(reached only past the dynamic-import offline boundary), threaded into compile
sessions and the run/serve render (incl. the configured render_model, which
the run phase previously ignored).
- doctor reports the configured provider's key (not only OPENROUTER_API_KEY) and
doctor --live smokes the configured endpoint; a missing key fails non-zero with
the exact env var (never misdirects to OpenRouter, never exits 0).
- Tests: ProviderPlan resolver + a hermetic missing-key compile.
reactor (0.3.0 -> 0.3.1):
- Receipt Cost now reports the real provider + model instead of a hardcoded
openrouter / gemini-3.5-flash (cost-only labels, never fingerprinted). New
optional RunProjectRender.providerLabel + CostLabels.
- Tests: cost-labels + a key-gated bring-your-own-provider live smoke.
Build: each reactor package cleans its output dir before tsc, so local
incremental builds cannot accumulate orphaned dist test artifacts.
Known limitation: Anthropic's direct OpenAI-compat endpoint rejects our
structured-output response_format unless strict:true; route Anthropic models
through OpenRouter today (documented).
Speak directly to agents driving Reactor: when blocked, open a GitHub
issue rather than working around silently. Includes when to file, a
search-first step, and a good-issue checklist (type, context/use case,
expected vs actual, minimal repro, evidence, environment incl. OS/agent/
model/versions, prior attempts) plus an honesty note and new-issue link.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CLI-only, content-free, opt-out telemetry reusing the live POST /analytics backend (context.library + reactor.* discriminator). Zero SDK changes, zero new deps. 174 tests pass.
Lead with OpenProse the paradigm (declare outcomes in Markdown contracts +
ProseScript, runs on any Prose-Complete harness), then Reactor as the harness
built to run it (the fast path) — one system, two layers. Adds a 'shape:
OpenProse -> Reactor' connective section and an SDK front-door section
(reactor() facade + typed handle); agent-first setup path; honest-status kept;
React table demoted to an optional collapsible. Versions 0.3.0 / 0.2.0 / 0.2.0.
When reactor is already published, publish_pkg returns before its pnpm-pack
builds reactor/dist, so reactor-cli + reactor-devtools fail to resolve
@openprose/reactor (TS2307) on an idempotent re-run. Build all three up front.
npm --provenance validates package.json repository.url against the GitHub repo
from the OIDC attestation; these two lacked the field (reactor had it), so
publish failed E422 after reactor@0.3.0 already published. Additive metadata only.
Ships @openprose/reactor 0.3.0, @openprose/reactor-cli 0.2.0, @openprose/reactor-devtools 0.2.0: the Reactor harness (compile-once-intelligent then dumb reconciler, content-addressed receipts, cost scales with surprise) with the distilled ideal public API — curated front door, full @openai/agents passthrough, one typed handle, one Substrate, unified observe, branded ids, and additive forward seams for the fixpoint.
* docs/reactor/v0.1: publish article + technical report into prose
Canonical source location for the v0.1 launch documents — moves the
generalist launch article and the technical report out of planning
drafts and into the public prose repo, alongside the spec they're
derived from.
docs/reactor/v0.1/article.md (243 lines) — "When the Conversation Ends,
the Responsibility Doesn't." Clean copy from the planning draft with
the four tenet-alignment edits (subhead audit-floor qualifier; receipt
verb tightening; line-217 freshness fix). Footer link to the technical
report updated from a github.com placeholder to the sibling ./report.
docs/reactor/v0.1/report.md (273 lines) — "Reactor: Cost Scales With
Surprise, Not Time." Clean copy from the planning draft. Date stamped
to 2026-05-22 (v0.1.0 release). §0 TL;DR carries the audit-floor
qualifier matching §7a; §10 already correctly discloses raw-evidence
retention as future work.
docs/reactor/v0.1/README.md — editorial discipline, versioning policy,
how-edits-get-published flow (commit here → bump platform/external/prose
submodule pin → fly deploy from apps/reports), and the publish-gate
checklist carried over from the technical-report authoring plan.
docs/reactor/v0.1/assets/ — placeholder for figures, kept empty.
The Astro renderer is being scaffolded at openprose/platform/apps/
reports/ in parallel; it reads from this directory via the
external/prose submodule.
* docs: qualify cost-thesis tagline + front-door trust artifact
Tagline qualified across README + package READMEs to match spec invariant 5 /
Pattern Rule 5 and technical report §7a: 'surprise — plus a bounded periodic
audit floor — not the arbitrary clock' (the bare one-liner was empirically
falsifiable in the audience-validation pass). Adds a dated v0.1.0 trust-artifact
blockquote to the front door.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Establishes prose/spec as the canonical home for the OpenProse spec,
current as of the index working state — Tenet 7 (one bounded run, one
session; the DAG composes) plus the Language / Harness / Pattern / Evals
reconciliation. index/spec becomes a pointer to here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prepare the Reactor packages for the interim 0.1.0-rc.2 release.
Narrow the package publish workflow to reactor-v* tags, bump Reactor and Cradle package versions, refresh the Cradle package pin for the rc.2 tarball, and update release-candidate evidence helpers and package docs.
Sharpen the Reactor front door for the rc.2 cut by adding the flat-tokens 46-vs-92 memoization contrast and updating the repo/package READMEs to lead with the surprise-not-clock hook.