diff --git a/packages/paperclip-runner/README.md b/packages/paperclip-runner/README.md index e6147ab6d72..e1c02e70b8d 100644 --- a/packages/paperclip-runner/README.md +++ b/packages/paperclip-runner/README.md @@ -4,10 +4,12 @@ This workspace is the standalone development boundary for Paperclip's native runner protocol, harness drivers, and normalized session backends. The production runner direction is Rust; `runner/` is its Cargo workspace. The TypeScript surface remains a control-plane/client reference implementation. -Phase 0 runs both implementations against one language-neutral fixture without -importing or starting Paperclip's server, UI, CLI, or production database. +Phase 0 runs both implementations against one language-neutral fixture. Phase 1 +adds executable PRP schemas, a cross-language conformance corpus, deterministic +static replay, and a standalone browser reference page. Neither phase imports or +starts Paperclip's server, UI, CLI, or production database. -## Phase 0 quick start +## Phase 0–1 quick start From the repository root: @@ -31,32 +33,47 @@ Run only the tracer with: pnpm --filter @paperclipai/paperclip-runner trace:phase0 ``` +Replay the Phase 1 happy path in the CLI or open the browser devtool: + +```sh +pnpm --filter @paperclipai/paperclip-runner replay:phase1 +pnpm --filter @paperclipai/paperclip-runner browser:dev --host 127.0.0.1 --port 4179 +``` + ## Package-owned commands | Command | Purpose | |---|---| -| `build` | Compile the TypeScript public surface and Rust workspace. | -| `typecheck` | Check both language surfaces without a release build. | +| `build` | Compile the TypeScript public surface, Rust workspace, and browser replay. | +| `typecheck` | Check TypeScript, Rust, generated schema sources, and browser types. | | `test` | Run Rust/TypeScript fixture, mock-contract, stable-output, and negative-boundary tests. | | `check:forbidden-imports` | Reject TypeScript imports and Cargo path dependencies that cross into Paperclip core. | | `check:phase0-parity` | Require byte-for-byte equivalent Rust and TypeScript tracer output. | +| `check:phase1-goldens` | Require all reducer snapshots and cross-language summaries to match checked goldens. | +| `check:phase1-parity` | Run TypeScript and Rust against the same Phase 1 fixture summaries. | +| `check:browser-tokens` | Reject component-local visual literals and require the standalone token layer. | | `docs:validate` | Validate local documentation links and the OKF v0.2 bundle. | | `trace:phase0` | Run the Rust mock-core tracer, print the stable result, and exit. | | `trace:phase0:typescript` | Run the TypeScript reference tracer directly. | -| `verify` | Run the complete Phase 0 acceptance sequence. | +| `replay:phase1` | Validate and reduce a fixture to a final snapshot. | +| `browser:dev` | Open the editable fixture/static replay reference page. | +| `test:browser` | Build the browser page, exercise replay states, and capture the screenshot. | +| `verify` | Run the complete Phase 0 and Phase 1 acceptance sequence. | ## Navigate - [Architecture and dependency boundary](docs/architecture.md) - [Tutorial index](docs/index.md) - [Phase 0 hand-run tutorial](docs/tutorials/phase-00-standalone-tracer.md) +- [Phase 1 hand-run tutorial](docs/tutorials/phase-01-static-replay.md) +- [PRP compatibility/versioning policy](docs/protocol-compatibility.md) - [Cumulative end-to-end tutorial](docs/tutorials/end-to-end.md) - [Journal guide](docs/journal.md) - [OKF knowledge bundle](knowledge/) - [Implementation plan](spec/paperclip-native-runner-implementation-plan.md) - [Normative spike specification](spec/paperclip-native-runner-spike-spec.md) -Phase 0 establishes `runner-core`, not the `paperclip-runnerd` daemon. Network -transport, process supervision, browser runtime, production Paperclip adapter, -and real model harnesses remain behind later phase checkpoints in the -implementation plan. +Phase 1 remains a static replay checkpoint, not the `paperclip-runnerd` daemon. +Network transport, process supervision, live browser transport, production +Paperclip integration, and real model harnesses remain behind later phase +checkpoints in the implementation plan. diff --git a/packages/paperclip-runner/docs/architecture.md b/packages/paperclip-runner/docs/architecture.md index fb1be47969a..abe821e6c79 100644 --- a/packages/paperclip-runner/docs/architecture.md +++ b/packages/paperclip-runner/docs/architecture.md @@ -31,9 +31,26 @@ The standalone package does not reach backward into a Paperclip implementation. The Phase 0 TypeScript contracts are deliberately sketches: they name responsibility and dependency direction without prematurely implementing the -Phase 1 protocol. The Rust `runner-core` crate establishes the production -language/package boundary and executes the same fixture; it is not yet the -Phase 2 runner daemon. +runtime transport. Phase 1 adds this executable static path: + +```text +protocol/schemas/*.json + | generate/check | shared fixtures + v v +TypeScript schema constants/types -> validator -> deterministic reducer + | | + v v + CLI browser devtool + | + golden parity summaries + | + v + Rust runner-core oracle +``` + +The Rust `runner-core` crate establishes the production language/package +boundary and checks the same fixture summaries; it is not yet the Phase 2 runner +daemon. ## Language ownership @@ -42,10 +59,12 @@ Phase 2 runner daemon. - TypeScript owns the control-plane/browser side and remains a useful reference client/test oracle. - JSON Schema and shared fixtures are the language-neutral authority. Phase 0 - begins with one checked JSON fixture; Phase 1 replaces its narrow validation - shape with the full PRP schema and conformance corpus. + keeps its narrow tracer fixture; Phase 1 adds the executable PRP v1 schema and + conformance corpus without silently changing the accepted Phase 0 path. - `check:phase0-parity` prevents either implementation from introducing a language-specific observable result. +- `check:phase1-parity` prevents TypeScript replay and the Rust production + direction from disagreeing on identity, terminal state, duplicates, or gaps. ## Allowed dependencies @@ -76,6 +95,7 @@ must fail the checker. ```sh pnpm --filter @paperclipai/paperclip-runner check:forbidden-imports pnpm --filter @paperclipai/paperclip-runner test +pnpm --filter @paperclipai/paperclip-runner check:phase1-parity ``` The first command scans the package source, scripts, and manifest. The test @@ -98,6 +118,19 @@ No socket, database, browser, Paperclip process, or model process is started. The default command executes this sequence in Rust. The TypeScript reference executes the same sequence, and the parity check compares their complete stdout. +## Phase 1 static replay boundary + +`replayPhase1FixtureText` is the single entry point used by the CLI and browser. +It parses JSON, validates JSON Schema plus cross-record bindings, and only then +calls the reducer. The reducer is pure: it clones input state, applies an event +at most once by source event ID, records source gaps/out-of-order deliveries, +and never performs I/O. + +The browser is a Vite application under `devtools/browser/`. Its Button, Badge, +Card, and Textarea are source-compatible adaptations of shadcn primitives; all +visual values live in its local `styles.css` token layer. It imports the same +replay module as the CLI and does not create a browser-only protocol model. + ## Future integration rule The [implementation plan](../spec/paperclip-native-runner-implementation-plan.md) diff --git a/packages/paperclip-runner/docs/index.md b/packages/paperclip-runner/docs/index.md index 44c3ccda1e9..d66664b3a49 100644 --- a/packages/paperclip-runner/docs/index.md +++ b/packages/paperclip-runner/docs/index.md @@ -5,11 +5,13 @@ The tutorials are cumulative and are always run from the repository root. ## Accepted implementation phases - [Phase 0: standalone tracer](tutorials/phase-00-standalone-tracer.md) — install the workspace, validate its Rust/TypeScript boundary and knowledge bundle, then run the deterministic Rust mock-core path and cross-language parity check. +- [Phase 1: static PRP replay](tutorials/phase-01-static-replay.md) — validate the shared schema/fixture corpus, reduce a fixture in the CLI, and inspect the same final snapshot in the standalone browser page. - [Cumulative end-to-end tutorial](tutorials/end-to-end.md) — the shortest complete workflow available at the current phase. ## Reference - [Architecture and dependency boundary](architecture.md) +- [PRP compatibility and versioning policy](protocol-compatibility.md) - [Engineering journal guide](journal.md) - [Dated shadcn/ui and AI Elements compatibility note](research/2026-08-07-ui-library-compatibility.md) - [Package README](../README.md) diff --git a/packages/paperclip-runner/docs/protocol-compatibility.md b/packages/paperclip-runner/docs/protocol-compatibility.md new file mode 100644 index 00000000000..a93a7d1c78a --- /dev/null +++ b/packages/paperclip-runner/docs/protocol-compatibility.md @@ -0,0 +1,72 @@ +# PRP Compatibility and Versioning Policy + +## Authority + +The JSON Schema files in [`protocol/schemas/`](../protocol/schemas/) are the +language-neutral source of truth for the Phase 1 executable contract. The +generated TypeScript schema module is checked against those files before every +TypeScript typecheck. Rust consumes the same fixtures and must produce the same +golden parity summaries. + +The broader normative protocol remains the +[native-runner spike specification](../spec/paperclip-native-runner-spike-spec.md). +Phase 1 intentionally implements only validation and static replay; it does not +add transport, persistence, or live control-plane behavior. + +## Version fields + +| Field | Phase 1 support | Compatibility rule | +|---|---:|---| +| `protocolVersion` | `1` | Required. Negotiate the highest overlapping version; no overlap fails closed. | +| `fixtureVersion` | `1` | Required by the conformance corpus. Unknown values fail closed. | +| `event.schemaVersion` | `1` | Required on every event. Unknown values fail closed before reduction. | +| Typed `schema` discriminators | `*.v1` | Required. Unknown required schema identities fail JSON Schema validation. | + +Wire protocol versions and fixture-corpus versions are independent. A fixture +format can evolve without changing PRP, and a future PRP version can be +represented only after the consumer advertises support for it. + +## Forward compatibility + +- Unknown object properties are accepted and preserved by validation. Reducers + ignore fields they do not understand until a later schema version gives those + fields defined behavior. +- Unknown required versions, schema discriminators, enum values, and required + fields fail closed. A consumer must never guess at their semantics. +- Scripted fixtures bind every event to the fixture run/session, require + contiguous controller command order, exactly one unique proposed result, and + exactly one unique terminal event. +- The top-level fixture result must equal the `run.result.proposed` payload after + canonical key ordering. Repeated `sourceEventId` deliveries must be + byte-equivalent after the same normalization. + +The forward-compatibility fixture proves that optional fields survive validation +without changing the v1 snapshot. The unsupported-version fixture proves that a +required v2 protocol cannot be replayed by this consumer. + +## Replay semantics + +- Events are applied in fixture order and ordered independently by + `(sourceKind, sourceInstanceId, sourceSeq)`. +- A repeated source event ID has no second projection effect. +- A forward source-sequence gap is recorded explicitly; the reducer never + invents a missing event. +- An event at or behind the committed source cursor is ignored and recorded as + out of order. +- Replaying an already-applied batch leaves the snapshot unchanged. + +The CLI and browser import the same `replayPhase1FixtureText` function, so +validation, compatibility errors, and final snapshots cannot drift between the +two surfaces. + +## Change policy + +1. Change JSON Schema first. +2. Regenerate the TypeScript schema module. +3. Add or revise a shared fixture and its golden snapshot/summary. +4. Prove TypeScript and Rust parity. +5. Update this policy and the normative spike specification when behavior + changes. + +Breaking changes require a new required version. Additive optional fields may +remain in v1 only when old consumers can safely ignore them. diff --git a/packages/paperclip-runner/docs/tutorials/end-to-end.md b/packages/paperclip-runner/docs/tutorials/end-to-end.md index 425daea8541..70472bb28c5 100644 --- a/packages/paperclip-runner/docs/tutorials/end-to-end.md +++ b/packages/paperclip-runner/docs/tutorials/end-to-end.md @@ -1,9 +1,10 @@ # Native Runner Cumulative End-to-End Tutorial -This tutorial grows with each accepted phase. At Phase 0, the complete runnable -system is the standalone Rust mock-core tracer plus its TypeScript parity oracle; -there is intentionally no daemon, network connection, browser console, real -harness, or Paperclip bridge. +This tutorial grows with each accepted phase. At Phase 1, the complete runnable +system includes the Phase 0 Rust mock-core tracer plus a language-neutral PRP +schema/fixture corpus, deterministic TypeScript reducer, Rust parity oracle, CLI +replay, and standalone browser replay. There is intentionally no daemon, network +connection, live harness, or Paperclip bridge. ## Current end-to-end path @@ -14,6 +15,11 @@ harness, or Paperclip bridge. 4. Confirm the shell prompt returns and no Paperclip service was started. 5. Open the [Phase 0 journal entry](../../knowledge/journal/2026-08-07-phase-00.md) and its linked verification evidence. +6. Follow [Phase 1: Validate and Replay a PRP Fixture](phase-01-static-replay.md). +7. Compare the happy-path CLI snapshot with the browser page. +8. Exercise the duplicate, gap, unknown-field, and unsupported-version fixtures. +9. Open the [Phase 1 journal entry](../../knowledge/journal/2026-08-07-phase-01.md) + and its linked verification evidence. The one-command form after installation is: @@ -28,7 +34,12 @@ pnpm --filter @paperclipai/paperclip-runner verify - Rust and TypeScript printed output is covered by exact string and parity assertions; - deliberate TypeScript and Cargo references to Paperclip core are rejected; - documentation and journal indexes are machine checked; -- the package remains runnable without Paperclip core. +- the package remains runnable without Paperclip core; +- JSON Schema remains the language-neutral authority for TypeScript and Rust; +- replay is deterministic and idempotent under duplicate delivery; +- source gaps are visible and never synthesized away; +- CLI and browser paths use the same validator/reducer module; +- browser components keep visual values in the package-local token layer. The next phase may extend this tutorial only after its own implementation and human checkpoint are authorized. diff --git a/packages/paperclip-runner/docs/tutorials/phase-01-static-replay.md b/packages/paperclip-runner/docs/tutorials/phase-01-static-replay.md new file mode 100644 index 00000000000..a664694e1d5 --- /dev/null +++ b/packages/paperclip-runner/docs/tutorials/phase-01-static-replay.md @@ -0,0 +1,108 @@ +# Phase 1: Validate and Replay a PRP Fixture + +This tutorial exercises the complete Phase 1 tracer bullet from a clean checkout: +validate a language-neutral fixture, reduce its events in the CLI, and inspect +the same snapshot in the standalone browser page. + +## Prerequisites + +- Node.js 20 or newer +- pnpm 9 or newer +- a stable Rust toolchain with `cargo` +- a Chromium-compatible browser + +Run every command from the repository root on the +`PAP-16679-paperclip-runner` branch. Install only this workspace without writing +the root lockfile: + +```sh +pnpm install --filter @paperclipai/paperclip-runner --lockfile=false --ignore-scripts --dev +pnpm --filter @paperclipai/paperclip-runner exec playwright install chromium +``` + +On a minimal Linux host, Playwright may also request system browser libraries: + +```sh +pnpm --filter @paperclipai/paperclip-runner exec playwright install-deps chromium +``` + +## 1. Check the contract and golden corpus + +```sh +pnpm --filter @paperclipai/paperclip-runner typecheck +pnpm --filter @paperclipai/paperclip-runner check:phase1-goldens +pnpm --filter @paperclipai/paperclip-runner check:phase1-parity +pnpm --filter @paperclipai/paperclip-runner check:forbidden-imports +``` + +Expected: generated schema sources are current, TypeScript and Rust accept the +same fixtures, all parity summaries match, and the standalone boundary passes. + +## 2. Replay the happy path in the CLI + +```sh +pnpm --filter @paperclipai/paperclip-runner replay:phase1 +``` + +Expected JSON facts: + +- `ok` is `true`; +- `snapshot.integrity` is `complete`; +- `snapshot.timeline` contains 9 entries; +- `snapshot.terminal.runTerminalState` is `succeeded`. + +Pass a different fixture path to inspect another case: + +```sh +pnpm --filter @paperclipai/paperclip-runner replay:phase1 packages/paperclip-runner/protocol/fixtures/phase-01/source-gap.json +``` + +Expected: `snapshot.integrity` is `gap_detected` and the missing source sequence +is `3`. + +An unsupported required version exits non-zero and returns a structured error: + +```sh +pnpm --filter @paperclipai/paperclip-runner replay:phase1 packages/paperclip-runner/protocol/fixtures/phase-01/unsupported-required-version.json +``` + +## 3. Open the standalone replay page + +Start the package-local Vite server: + +```sh +pnpm --filter @paperclipai/paperclip-runner browser:dev --host 127.0.0.1 --port 4179 +``` + +Open `http://127.0.0.1:4179`, then: + +1. Select `Happy path` and confirm the terminal badge reads `succeeded`. +2. Edit the fixture summary in the JSON textarea and select **Validate & replay**. +3. Select `Duplicate event` and confirm one duplicate is ignored. +4. Select `Source sequence gap` and confirm the missing sequence diagnostic. +5. Select `Unsupported required version` and confirm replay is rejected. +6. Expand **Inspect snapshot JSON** and compare it with the CLI output. + +Stop Vite with `Ctrl+C`. + +## 4. Run the browser regression path + +```sh +pnpm --filter @paperclipai/paperclip-runner check:browser-tokens +pnpm --filter @paperclipai/paperclip-runner test:browser +``` + +Expected: two Playwright tests pass and the happy-path screenshot is written to +`packages/paperclip-runner/knowledge/evidence/phase-01-static-replay.png`. + +## What this proves + +- JSON Schema is the executable source for validation and TypeScript types. +- The CLI and browser call the same validator and reducer. +- Duplicate delivery is idempotent and sequence gaps remain visible. +- Unknown optional fields do not change the v1 projection. +- No Paperclip server, UI, CLI, adapter, or production database module starts or + imports into the standalone path. + +Phase 2 is outside this tutorial and must not start before the Phase 1 human +checkpoint. diff --git a/packages/paperclip-runner/knowledge/evidence/2026-08-07-phase-01-verification.md b/packages/paperclip-runner/knowledge/evidence/2026-08-07-phase-01-verification.md new file mode 100644 index 00000000000..e4e73d991dd --- /dev/null +++ b/packages/paperclip-runner/knowledge/evidence/2026-08-07-phase-01-verification.md @@ -0,0 +1,138 @@ +--- +type: Verification Evidence +title: Phase 1 verification +description: Exact tools, commands, results, and browser artifact for PRP static replay. +tags: [native-runner, phase-1, verification, protocol, browser] +status: stable +generated: { by: openai/gpt-5, at: 2026-08-07T19:10:00Z } +phase: "1" +--- + +# Environment + +- OS: `Linux 6.17.0-1019-aws aarch64` +- Node.js: `v22.22.2` +- pnpm: `9.15.4` +- TypeScript: `5.9.3` +- Vitest: `4.1.10` +- Vite: `6.4.1` +- Playwright: `1.61.1` +- Rust/Cargo: `1.97.1` in the run scratch directory + +# Commands and observed results + +1. TypeScript schema/type/reducer tests: + +```sh +pnpm --filter @paperclipai/paperclip-runner test:typescript +pnpm --filter @paperclipai/paperclip-runner typecheck:typescript +pnpm --filter @paperclipai/paperclip-runner typecheck:browser +``` + +Result: exit 0. Six Vitest files and 29 tests passed. The generated schema module +matched all eight JSON Schema sources, and both TypeScript configurations passed. + +2. Golden corpus and standalone boundary: + +```sh +pnpm --filter @paperclipai/paperclip-runner check:phase1-goldens +pnpm --filter @paperclipai/paperclip-runner check:forbidden-imports +pnpm --filter @paperclipai/paperclip-runner check:browser-tokens +``` + +Result: exit 0. All six valid fixture snapshots/summaries were current; forbidden +Paperclip core imports were absent; component visual values remained in the +standalone `styles.css` token layer. + +3. Rust conformance/parity tests: + +```sh +PATH="$PAPERCLIP_RUN_SCRATCH_DIR/cargo/bin:$PATH" \ +CARGO_HOME="$PAPERCLIP_RUN_SCRATCH_DIR/cargo" \ +RUSTUP_HOME="$PAPERCLIP_RUN_SCRATCH_DIR/rustup" \ +pnpm --filter @paperclipai/paperclip-runner test:rust +``` + +Result: exit 0. Twelve Rust tests passed, including all six parity fixtures, +unsupported protocol/fixture versions, a mismatched declared result, the Phase 0 +stable tracer, and sequence-gap rejection. + +4. CLI tutorial paths after `build:typescript`: + +```sh +node packages/paperclip-runner/dist/cli/phase1-replay.js +node packages/paperclip-runner/dist/cli/phase1-replay.js packages/paperclip-runner/protocol/fixtures/phase-01/source-gap.json +node packages/paperclip-runner/dist/cli/phase1-replay.js packages/paperclip-runner/protocol/fixtures/phase-01/unsupported-required-version.json +``` + +Observed summaries: + +```json +{"ok":true,"integrity":"complete","timelineCount":9,"runTerminalState":"succeeded"} +{"ok":true,"integrity":"gap_detected","gaps":[{"sourceKey":"runner:runner_phase1","expected":3,"received":4,"missing":[3]}]} +{"ok":false,"issues":[{"code":"unsupported_required_version","path":"/protocolVersion"}]} +``` + +The first two commands exited 0. The unsupported required version exited 1. + +5. Browser build and Playwright replay: + +```sh +LD_LIBRARY_PATH="$PAPERCLIP_RUN_SCRATCH_DIR/playwright-libs/usr/lib/aarch64-linux-gnu:/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu" \ +pnpm --filter @paperclipai/paperclip-runner test:browser +``` + +Result: exit 0. Vite transformed 218 modules and emitted the standalone page; +both Playwright cases passed in 2.0 seconds. They covered the happy snapshot, +ordered timeline, duplicate diagnostic, and unsupported-version error state. + +6. Repository UI token gate baseline: + +```sh +pnpm check:token-gates +``` + +Result: exit 1 with 12 existing color-literal findings in +`ui/src/components/onboarding/PaperclipOrbit3D.tsx`. Phase 1 changes no `ui/` +file. The package-local token check above is green. + +7. Complete package acceptance sequence: + +```sh +PATH="$PAPERCLIP_RUN_SCRATCH_DIR/cargo/bin:$PATH" \ +CARGO_HOME="$PAPERCLIP_RUN_SCRATCH_DIR/cargo" \ +RUSTUP_HOME="$PAPERCLIP_RUN_SCRATCH_DIR/rustup" \ +LD_LIBRARY_PATH="$PAPERCLIP_RUN_SCRATCH_DIR/playwright-libs/usr/lib/aarch64-linux-gnu:/lib/aarch64-linux-gnu:/usr/lib/aarch64-linux-gnu" \ +pnpm --filter @paperclipai/paperclip-runner verify +``` + +Result: exit 0. Build, all three typechecks, current goldens, 29 TypeScript +tests, 12 Rust tests, 3 negative/positive boundary tests, browser token check, +2 Playwright tests, documentation/OKF validation, Phase 0 parity, Phase 1 +parity, the Rust Phase 0 tracer, and the Phase 1 CLI replay all passed. + +# Browser artifact + +[Phase 1 static replay screenshot](phase-01-static-replay.png) + +- PNG: 1440 × 1137, RGB +- SHA-256: `eecdc71e35c76764916317239c2fd3dd1e2f60ab609ee48d12c2a1b6b67897ce` +- Shows editable happy-path fixture input, validated terminal snapshot, result + summary, ordered nine-event timeline, and snapshot JSON disclosure. + +# Acceptance mapping + +- Schema validation and schema-derived TypeScript types: passed. +- Happy/failure/interruption/duplicate/gap/unknown-field/version fixtures: passed. +- Determinism, idempotency, duplicate, gap, and forward compatibility: passed. +- CLI and browser use the same replay entry point: verified by imports and tests. +- Rust and TypeScript shared-fixture summaries: passed. +- Standalone browser build, interaction path, and screenshot: passed. +- Forbidden core imports: passed. +- Reference docs, tutorial index, cumulative tutorial, version policy, and OKF + journal: linked and machine-validated. + +# Known limitations + +See the linked [Phase 1 journal entry](../journal/2026-08-07-phase-01.md) for +intentional Phase 2+ gaps and the host-only browser dependency note. diff --git a/packages/paperclip-runner/knowledge/evidence/index.md b/packages/paperclip-runner/knowledge/evidence/index.md index 9778590d360..8b16787b11c 100644 --- a/packages/paperclip-runner/knowledge/evidence/index.md +++ b/packages/paperclip-runner/knowledge/evidence/index.md @@ -4,3 +4,4 @@ * [Phase 0 verification](2026-08-07-phase-00-verification.md) - Clean install, build, tests, boundary, documentation, OKF, and tracer results. * [Phase 0 Rust correction verification](2026-08-07-phase-00-rust-correction-verification.md) - Rust build/tests, cross-language parity, and corrected boundary evidence. +* [Phase 1 verification](2026-08-07-phase-01-verification.md) - Schema, golden, reducer, Rust parity, CLI, browser, token, boundary, and screenshot evidence. diff --git a/packages/paperclip-runner/knowledge/evidence/phase-01-static-replay.png b/packages/paperclip-runner/knowledge/evidence/phase-01-static-replay.png new file mode 100644 index 00000000000..5937e7fb980 Binary files /dev/null and b/packages/paperclip-runner/knowledge/evidence/phase-01-static-replay.png differ diff --git a/packages/paperclip-runner/knowledge/journal/2026-08-07-phase-01.md b/packages/paperclip-runner/knowledge/journal/2026-08-07-phase-01.md new file mode 100644 index 00000000000..5425facbc68 --- /dev/null +++ b/packages/paperclip-runner/knowledge/journal/2026-08-07-phase-01.md @@ -0,0 +1,94 @@ +--- +type: Engineering Journal Entry +title: Phase 1 protocol, fixtures, reducer, and static replay +description: Decisions and evidence for the executable PRP v1 schema and standalone replay checkpoint. +tags: [native-runner, phase-1, protocol, reducer, replay, browser] +status: stable +generated: { by: openai/gpt-5, at: 2026-08-07T19:10:00Z } +entry_kind: phase +phase: "1" +--- + +# Context + +Phase 1 makes the language-neutral runner contract executable before networking +or a real harness exists. The checkpoint must validate a scripted PRP fixture, +reduce ordered events deterministically, and show the same snapshot in a CLI and +standalone browser without importing Paperclip core. + +# Decisions + +1. Keep JSON Schema under `protocol/schemas/` as the language-neutral source of + truth. Generate checked TypeScript schema constants and derive public types + with `json-schema-to-ts`. +2. Accept unknown optional object properties for forward compatibility while + failing closed on unknown required protocol, fixture, event, schema, enum, or + required-field semantics. +3. Treat scripted fixtures as bound records: all run/session identities agree, + controller commands are contiguous, duplicate event IDs are byte-equivalent, + and the single proposed result matches the declared fixture result. +4. Keep the reducer pure and I/O-free. It deduplicates before projection, + records source gaps/out-of-order delivery, never invents events, and returns + an unchanged snapshot when an applied batch is replayed. +5. Import one `replayPhase1FixtureText` path from both CLI and browser so static + replay cannot develop two validation or projection contracts. +6. Use source-compatible shadcn Button, Badge, Card, and Textarea wrappers in the + standalone Vite page. Component files contain no visual literals; semantic + values live in the page's local CSS token layer. +7. Keep Rust at the production boundary by validating required versions and + fixture bindings, then comparing its parity summaries against the same + checked golden corpus. +8. Target current evergreen browsers in Vite. Ajv remains in the Phase 1 + devtool bundle so the browser validates the authoritative schemas directly. + +# Evidence + +Exact tool versions, commands, observed results, CLI summaries, browser test +output, screenshot digest, and boundary/token findings live in +[Phase 1 verification evidence](../evidence/2026-08-07-phase-01-verification.md). +The human path is documented in the +[Phase 1 tutorial](../../docs/tutorials/phase-01-static-replay.md). + +# Failures and corrections + +- The first browser build used Vite's default legacy target. The installed + esbuild cannot downlevel Ajv's runtime code to that target, producing 249 + transform errors. The devtool now declares `target: "esnext"`, matching its + current-evergreen-browser scope; the production build passes. +- The Playwright web-server command included a literal `--`, so Vite ignored the + requested port and attempted its default. The command now invokes + `pnpm exec vite preview` with explicit arguments. +- The first browser assertions used broad accessible-label/text selectors that + correctly matched more than one element. The tests now use an exact fixture + label and a scoped result-summary test ID. Both browser cases pass. +- The execution image had neither Cargo nor Chromium's optional Linux shared + libraries. A verified official stable Rust toolchain and extracted Ubuntu + browser libraries were placed only in the run scratch directory. No system or + repository runtime state was changed. +- The repository-wide token gate currently reports 12 existing onboarding color + literals outside this package. The new package-local browser token gate passes + and no `ui/` files were changed. + +# Known gaps + +- Static fixtures only: no runner daemon, network transport, durable outbox, + ACK, reconnect, or live browser subscription. +- No fake or real harness process and no control-plane persistence or authority. +- The browser is a first useful replay inspector, not the later full reference + console; it has no composer, live controls, request resolution, or dark theme. +- The unminified validation path keeps Ajv in the browser bundle. Bundle + optimization is deferred until behavior and schema boundaries are stable. +- Linux browser automation still requires the normal Playwright host libraries; + the tutorial names the standard installation command. + +# Follow-up questions + +- Should Phase 2 feed reducer batches per transport ACK or per animation frame + while preserving this exact snapshot result? +- Which fake-driver item payloads are the smallest useful addition to the + schema without prematurely implementing the Phase 5 console? +- Should a later build precompile Ajv validators after Rust schema conformance is + established, or keep runtime schema compilation for inspectability? + +No Phase 2 work begins from this entry; the next action is the Phase 1 human +checkpoint. diff --git a/packages/paperclip-runner/knowledge/journal/index.md b/packages/paperclip-runner/knowledge/journal/index.md index 9957ac589ee..da0f2e2a597 100644 --- a/packages/paperclip-runner/knowledge/journal/index.md +++ b/packages/paperclip-runner/knowledge/journal/index.md @@ -4,3 +4,4 @@ * [Phase 0 boundary, journal, and runnable skeleton](2026-08-07-phase-00.md) - Decisions, implementation evidence, failures, gaps, and next questions for the standalone skeleton. * [Phase 0 Rust boundary correction](2026-08-07-phase-00-rust-boundary-correction.md) - Root cause and corrected Rust/TypeScript ownership after the human checkpoint. +* [Phase 1 protocol, fixtures, reducer, and static replay](2026-08-07-phase-01.md) - Executable PRP schemas, deterministic replay decisions, browser findings, and checkpoint gaps. diff --git a/packages/paperclip-runner/knowledge/log.md b/packages/paperclip-runner/knowledge/log.md index c1e9c95a66f..b374e1d6f63 100644 --- a/packages/paperclip-runner/knowledge/log.md +++ b/packages/paperclip-runner/knowledge/log.md @@ -4,3 +4,4 @@ * **Creation**: Established the OKF v0.2 bundle, typed Phase 0 journal, verification evidence, template, and progressive-disclosure indexes. * **Rust boundary correction**: Added the production-direction Cargo workspace, shared-fixture parity evidence, negative Cargo boundary coverage, and a superseding journal entry after the Phase 0 checkpoint exposed the TypeScript-only omission. +* **Phase 1 static replay**: Added executable PRP v1 schemas, cross-language fixture/golden parity, deterministic reducer, CLI/browser replay, compatibility policy, tutorial, screenshot, and verification evidence. diff --git a/packages/paperclip-runner/spec/paperclip-native-runner-spike-spec.md b/packages/paperclip-runner/spec/paperclip-native-runner-spike-spec.md index 0c310f2ab52..55ac7f0568d 100644 --- a/packages/paperclip-runner/spec/paperclip-native-runner-spike-spec.md +++ b/packages/paperclip-runner/spec/paperclip-native-runner-spike-spec.md @@ -1385,6 +1385,28 @@ PRP v1 guarantees: Exactly-once network delivery is not claimed. Exactly-once **effects** are obtained through IDs, unique constraints, and transactional reducers. +#### 10.2.1 Phase 1 executable compatibility profile + +The Phase 1 standalone tracer makes the PRP v1 static contract executable under +`packages/paperclip-runner/protocol/`. JSON Schema is authoritative for identity, +capability, command, event, request, result, terminal, and scripted-fixture +shapes. TypeScript types are derived from the checked schema module; the Rust +reference reducer consumes the same fixtures and golden parity summaries. + +Required version fields and schema discriminators fail closed when unknown. +Unknown optional object fields are accepted and preserved, but have no reducer +effect until a later schema revision defines one. Scripted fixtures require one +unique `run.result.proposed` event whose payload matches the fixture result and +one unique `run.terminal` event. Repeated `sourceEventId` deliveries must be +byte-equivalent after canonical JSON key ordering. + +Static replay orders each source by `(sourceKind, sourceInstanceId, sourceSeq)`, +deduplicates before projection, records rather than fills source-sequence gaps, +and leaves an already-applied snapshot unchanged on replay. The package CLI and +standalone browser must import the same validator/reducer entry point. These +rules clarify the v1 compatibility contract; they do not add transport, +persistence, or control-plane authority in Phase 1. + ### 10.3 Common envelope ```ts