docs(runner): record phase 1 replay evidence

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-08-07 19:13:07 +00:00
1 parent 1b51f95c6c
commit a4af3caea7
13 files changed
+520 -20

No files matched your search

+27 -10
View File
@@ -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.
+38 -5
View File
@@ -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)
+2
View File
@@ -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)
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

@@ -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.
@@ -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.
@@ -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.
@@ -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