mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-26 10:26:26 +01:00
docs(runner): record phase 1 replay evidence
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
1b51f95c6c
commit
a4af3caea7
13 files changed
+520
-20
No files matched your search
@@ -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.
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user