From ab7b85878a91f669451f7a1fc14e7aebd54046ff Mon Sep 17 00:00:00 2001 From: Dotta Date: Sun, 9 Aug 2026 14:46:49 +0000 Subject: [PATCH] docs(runner): strip leaked generation wrappers, sync Phase 7 counts, guard against regressions Remove trailing generation-wrapper markup (, plus in the tutorial) that had leaked at EOF into eleven committed Phase 7 reference, tutorial, evidence, and OKF-journal files. Sync the stated suite counts in the current-state docs (tutorial, scenario-explorer reference, verification-commands reference, and OKF journal) to the verified results: test:phase7 49, test:browser:phase7 25, docs:validate 73 files / 28 OKF concepts / 5 indexes. Drop a brittle wall-clock timing from the journal. The dated 7F verification evidence and log.md milestone entry keep their point-in-time 45/19 figures on purpose. Add a wrapper-markup guard to docs:validate (via scripts/lib/doc-wrappers.mjs) that fails with the exact file and line when generator envelope tags reappear, plus a node:test regression suite wired into the package test script. Co-Authored-By: Claude Opus 4.8 --- .../phase-07-authorization-and-exposure.md | 1 - .../docs/phase-07-capability-disposition.md | 1 - .../docs/phase-07-eval-conformance.md | 1 - .../docs/phase-07-future-binding-boundary.md | 1 - .../docs/phase-07-mock-control-plane-port.md | 1 - .../docs/phase-07-scenario-explorer.md | 5 +-- .../docs/phase-07-semantic-tools.md | 1 - .../docs/phase-07-verification-commands.md | 7 ++- .../tutorials/phase-07-scenario-explorer.md | 4 +- .../2026-08-09-phase-07-verification.md | 1 - .../knowledge/journal/2026-08-09-phase-07.md | 9 ++-- packages/paperclip-runner/package.json | 2 +- .../scripts/lib/doc-wrappers.mjs | 21 +++++++++ .../scripts/validate-doc-links.mjs | 5 +++ .../scripts/validate-doc-links.test.mjs | 45 +++++++++++++++++++ 15 files changed, 82 insertions(+), 23 deletions(-) create mode 100644 packages/paperclip-runner/scripts/lib/doc-wrappers.mjs create mode 100644 packages/paperclip-runner/scripts/validate-doc-links.test.mjs diff --git a/packages/paperclip-runner/docs/phase-07-authorization-and-exposure.md b/packages/paperclip-runner/docs/phase-07-authorization-and-exposure.md index 05e5c61e76e..dc7aadc303f 100644 --- a/packages/paperclip-runner/docs/phase-07-authorization-and-exposure.md +++ b/packages/paperclip-runner/docs/phase-07-authorization-and-exposure.md @@ -96,4 +96,3 @@ prohibition, and the test-only, explicitly granted, allowlisted escape hatch. - [Capability disposition](phase-07-capability-disposition.md) - [Semantic tool catalog](phase-07-semantic-tools.md) - [Scenario explorer](phase-07-scenario-explorer.md) - diff --git a/packages/paperclip-runner/docs/phase-07-capability-disposition.md b/packages/paperclip-runner/docs/phase-07-capability-disposition.md index bd9c3b72e1e..941d490874a 100644 --- a/packages/paperclip-runner/docs/phase-07-capability-disposition.md +++ b/packages/paperclip-runner/docs/phase-07-capability-disposition.md @@ -82,4 +82,3 @@ contract cannot silently fall out of sync. - [Semantic tool catalog](phase-07-semantic-tools.md) - [Authorization and exposure](phase-07-authorization-and-exposure.md) - [Eval conformance](phase-07-eval-conformance.md) - diff --git a/packages/paperclip-runner/docs/phase-07-eval-conformance.md b/packages/paperclip-runner/docs/phase-07-eval-conformance.md index 76f71ab8c57..7a10c00db1c 100644 --- a/packages/paperclip-runner/docs/phase-07-eval-conformance.md +++ b/packages/paperclip-runner/docs/phase-07-eval-conformance.md @@ -80,4 +80,3 @@ OKF frontmatter). See the - [Capability disposition](phase-07-capability-disposition.md) - [Semantic tool catalog](phase-07-semantic-tools.md) - [Scenario explorer](phase-07-scenario-explorer.md) - diff --git a/packages/paperclip-runner/docs/phase-07-future-binding-boundary.md b/packages/paperclip-runner/docs/phase-07-future-binding-boundary.md index 772cb35bd38..cc754d100ab 100644 --- a/packages/paperclip-runner/docs/phase-07-future-binding-boundary.md +++ b/packages/paperclip-runner/docs/phase-07-future-binding-boundary.md @@ -49,4 +49,3 @@ CTO approval at the Phase 7 checkpoint (`PAP-16908`). Until then: - [Architecture and dependency boundary](architecture.md) - [Mock ControlPlanePort](phase-07-mock-control-plane-port.md) - [Capability disposition](phase-07-capability-disposition.md) - diff --git a/packages/paperclip-runner/docs/phase-07-mock-control-plane-port.md b/packages/paperclip-runner/docs/phase-07-mock-control-plane-port.md index 3add9e4526f..04a4236c7fd 100644 --- a/packages/paperclip-runner/docs/phase-07-mock-control-plane-port.md +++ b/packages/paperclip-runner/docs/phase-07-mock-control-plane-port.md @@ -92,4 +92,3 @@ Nine tests, no npm alias of their own — they also run inside - [Semantic tool catalog](phase-07-semantic-tools.md) - [Authorization and exposure](phase-07-authorization-and-exposure.md) - [Future binding boundary](phase-07-future-binding-boundary.md) - diff --git a/packages/paperclip-runner/docs/phase-07-scenario-explorer.md b/packages/paperclip-runner/docs/phase-07-scenario-explorer.md index 4e5fe85a0bc..93eec30023a 100644 --- a/packages/paperclip-runner/docs/phase-07-scenario-explorer.md +++ b/packages/paperclip-runner/docs/phase-07-scenario-explorer.md @@ -68,10 +68,10 @@ a time with zero horizontal overflow. # Open the explorer on 127.0.0.1:4183. pnpm --filter @paperclipai/paperclip-runner demo:phase7 -# Scenario runtime, explorer components, and route determinism (45 tests). +# Scenario runtime, explorer components, and route determinism (49 tests). pnpm --filter @paperclipai/paperclip-runner test:phase7 -# Browser IA, determinism, evidence routes, boundary, a11y, responsive (19). +# Browser IA, determinism, evidence routes, boundary, a11y, responsive (25). pnpm --filter @paperclipai/paperclip-runner test:browser:phase7 # Deterministic 24-image acceptance set (12 routes x 2 viewports). @@ -83,4 +83,3 @@ pnpm --filter @paperclipai/paperclip-runner record:phase7 - [Eval conformance](phase-07-eval-conformance.md) - [Verification commands](phase-07-verification-commands.md) - [Phase 7F explorer verification](../knowledge/evidence/2026-08-09-phase-07f-explorer-verification.md) - diff --git a/packages/paperclip-runner/docs/phase-07-semantic-tools.md b/packages/paperclip-runner/docs/phase-07-semantic-tools.md index 0578be33296..a0bed432ed6 100644 --- a/packages/paperclip-runner/docs/phase-07-semantic-tools.md +++ b/packages/paperclip-runner/docs/phase-07-semantic-tools.md @@ -84,4 +84,3 @@ that every optional group is present. - [Authorization and exposure](phase-07-authorization-and-exposure.md) - [Mock ControlPlanePort](phase-07-mock-control-plane-port.md) - [Eval conformance](phase-07-eval-conformance.md) - diff --git a/packages/paperclip-runner/docs/phase-07-verification-commands.md b/packages/paperclip-runner/docs/phase-07-verification-commands.md index 054125b4318..b86c0396190 100644 --- a/packages/paperclip-runner/docs/phase-07-verification-commands.md +++ b/packages/paperclip-runner/docs/phase-07-verification-commands.md @@ -14,10 +14,10 @@ acceptance record are in | Semantic tools + authorization/redaction | `exec vitest run src/tools/phase7-semantic-tools.test.ts` | 9 tests pass | | 106-case conformance | `test:phase7-evals` | 1 file (all 106 cases) passes | | Fake-agent matrix + bounded Codex + parity report | `report:phase7-evals` | `Phase 7 eval conformance passed: 106 cases across 16 groups.` | -| Scenario runtime + explorer + routes | `test:phase7` | 45 tests pass | -| Browser IA, accessibility, determinism, boundary | `test:browser:phase7` | 19 Playwright tests pass | +| Scenario runtime + explorer + routes | `test:phase7` | 49 tests pass | +| Browser IA, accessibility, determinism, boundary | `test:browser:phase7` | 25 Playwright tests pass | | Screenshot acceptance set | `record:phase7` | 24 deterministic images | -| Doc links + OKF bundle | `docs:validate` | 62 files, 26 OKF concepts, 5 indexes | +| Doc links + OKF bundle | `docs:validate` | 73 files, 28 OKF concepts, 5 indexes | ## Notes @@ -39,4 +39,3 @@ acceptance record are in - [Clean-start tutorial](tutorials/phase-07-scenario-explorer.md) - [Eval conformance](phase-07-eval-conformance.md) - [Scenario explorer](phase-07-scenario-explorer.md) - diff --git a/packages/paperclip-runner/docs/tutorials/phase-07-scenario-explorer.md b/packages/paperclip-runner/docs/tutorials/phase-07-scenario-explorer.md index 0b566d53e43..4ad01e8f26a 100644 --- a/packages/paperclip-runner/docs/tutorials/phase-07-scenario-explorer.md +++ b/packages/paperclip-runner/docs/tutorials/phase-07-scenario-explorer.md @@ -144,7 +144,7 @@ pnpm --filter @paperclipai/paperclip-runner exec vitest run \ pnpm --filter @paperclipai/paperclip-runner test:phase7-evals pnpm --filter @paperclipai/paperclip-runner report:phase7-evals -# Scenario runtime, explorer components, and route determinism (45 tests). +# Scenario runtime, explorer components, and route determinism (49 tests). pnpm --filter @paperclipai/paperclip-runner test:phase7 # Browser information architecture, accessibility, determinism, and boundary. @@ -184,5 +184,3 @@ The exact results captured for the acceptance record are in the (PAP-16903), 7F browser explorer (PAP-16904, UX gate PAP-16905), 7G docs and evidence (PAP-16906), 7H clean-room QA (PAP-16907), Phase 7 checkpoint (PAP-16908). - - diff --git a/packages/paperclip-runner/knowledge/evidence/2026-08-09-phase-07-verification.md b/packages/paperclip-runner/knowledge/evidence/2026-08-09-phase-07-verification.md index 384f199fd28..12daf9dabb7 100644 --- a/packages/paperclip-runner/knowledge/evidence/2026-08-09-phase-07-verification.md +++ b/packages/paperclip-runner/knowledge/evidence/2026-08-09-phase-07-verification.md @@ -102,4 +102,3 @@ Results were captured on 2026-08-09 between 13:37Z and 13:39Z. provider exercise is the bounded binding sample in `report:phase7-evals`. - No Paperclip control plane, database, or provider is contacted anywhere in Phase 7. Real integration is Phase 8 (ACPX) and requires separate approval. - diff --git a/packages/paperclip-runner/knowledge/journal/2026-08-09-phase-07.md b/packages/paperclip-runner/knowledge/journal/2026-08-09-phase-07.md index 43ba3b4dafd..399985a9a20 100644 --- a/packages/paperclip-runner/knowledge/journal/2026-08-09-phase-07.md +++ b/packages/paperclip-runner/knowledge/journal/2026-08-09-phase-07.md @@ -56,15 +56,15 @@ All commands ran from the repository root, offline, on Node 22.22.2 / pnpm 152 skill/reference headings, 106 eval cases, 258 normative rows, and 41 legacy MCP aliases folded one-to-one. - Mock control plane (9 tests), semantic tools and authorization/redaction - (9 tests), scenario runtime and explorer (45 tests), and the 106-case + (9 tests), scenario runtime and explorer (49 tests), and the 106-case conformance suite all pass in-process. - `report:phase7-evals` reports 106 cases across 16 groups, 18/18 fake-agent operations, and the bounded Codex binding sample. -- `test:browser:phase7` passes 19 Playwright checks (6.8s) for information +- `test:browser:phase7` passes 25 Playwright checks for information architecture, route determinism, evidence routes, the credential boundary, accessibility, and responsive layout. -- On a clean tree `docs:validate` passes 62 documentation files and an OKF - bundle of 26 concepts across 5 indexes. +- On a clean tree `docs:validate` passes 73 documentation files and an OKF + bundle of 28 concepts across 5 indexes. # Evidence @@ -99,4 +99,3 @@ All commands ran from the repository root, offline, on Node 22.22.2 / pnpm with generator-authored OKF frontmatter, or out of the bundle entirely? - Which of the eight reference pages should the Phase 8 binding work extend first when the real adapter lands behind the seam? - diff --git a/packages/paperclip-runner/package.json b/packages/paperclip-runner/package.json index 812dd6cdc1d..eaf24ebec6b 100644 --- a/packages/paperclip-runner/package.json +++ b/packages/paperclip-runner/package.json @@ -36,7 +36,7 @@ "typecheck:typescript": "pnpm run check:protocol-types && tsc -p tsconfig.json --noEmit", "typecheck:rust": "cargo check --manifest-path runner/Cargo.toml --locked --workspace", "typecheck:browser": "tsc -p tsconfig.browser.json --noEmit", - "test": "pnpm run build:phase2-binaries && pnpm run test:typescript && pnpm run test:rust && node --test scripts/check-forbidden-imports.test.mjs scripts/record-phase4-evidence.test.mjs", + "test": "pnpm run build:phase2-binaries && pnpm run test:typescript && pnpm run test:rust && node --test scripts/check-forbidden-imports.test.mjs scripts/record-phase4-evidence.test.mjs scripts/validate-doc-links.test.mjs", "test:typescript": "vitest run", "test:rust": "cargo test --manifest-path runner/Cargo.toml --locked --workspace", "test:browser": "pnpm run build:typescript && pnpm run build:phase2-binaries && pnpm run build:browser && playwright test --config devtools/browser/playwright.config.ts", diff --git a/packages/paperclip-runner/scripts/lib/doc-wrappers.mjs b/packages/paperclip-runner/scripts/lib/doc-wrappers.mjs new file mode 100644 index 00000000000..efe1e9bb4c1 --- /dev/null +++ b/packages/paperclip-runner/scripts/lib/doc-wrappers.mjs @@ -0,0 +1,21 @@ +// Detects leaked model/tool generation-wrapper markup in documentation. +// +// When a generator writes its raw completion envelope into a file, tags such as +// a trailing `` or `` escape into the committed prose. Plain +// link and OKF validation do not notice them, so `docs:validate` scans every +// markdown file with this detector and fails on the exact file and line. Prose +// docs never legitimately contain these tags, so any match is a defect. +export const WRAPPER_MARKUP = + /<\/?(?:antml:[a-z0-9_-]+|content|invoke|parameter|function_calls|function_results)\b[^>]*>/i; + +export function wrapperMarkupIn(markdown) { + const hits = []; + const lines = markdown.split("\n"); + for (let index = 0; index < lines.length; index += 1) { + const match = lines[index].match(WRAPPER_MARKUP); + if (match) { + hits.push({ line: index + 1, tag: match[0] }); + } + } + return hits; +} diff --git a/packages/paperclip-runner/scripts/validate-doc-links.mjs b/packages/paperclip-runner/scripts/validate-doc-links.mjs index e28f666a165..61e92bbc541 100644 --- a/packages/paperclip-runner/scripts/validate-doc-links.mjs +++ b/packages/paperclip-runner/scripts/validate-doc-links.mjs @@ -2,6 +2,8 @@ import { access, readFile, readdir } from "node:fs/promises"; import { dirname, extname, relative, resolve } from "node:path"; import { fileURLToPath } from "node:url"; +import { wrapperMarkupIn } from "./lib/doc-wrappers.mjs"; + const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const documentationRoots = [ resolve(packageRoot, "README.md"), @@ -80,6 +82,9 @@ const markdownFiles = ( for (const file of markdownFiles.sort()) { const markdown = await readFile(file, "utf8"); + for (const { line, tag } of wrapperMarkupIn(markdown)) { + errors.push(`${relative(packageRoot, file)}:${line} -> leaked generation-wrapper markup ${tag}`); + } for (const rawLink of linksIn(markdown)) { if (/^(?:https?:|mailto:|skill:)/.test(rawLink)) { continue; diff --git a/packages/paperclip-runner/scripts/validate-doc-links.test.mjs b/packages/paperclip-runner/scripts/validate-doc-links.test.mjs new file mode 100644 index 00000000000..44c9d61258e --- /dev/null +++ b/packages/paperclip-runner/scripts/validate-doc-links.test.mjs @@ -0,0 +1,45 @@ +import assert from "node:assert/strict"; +import { test } from "node:test"; + +import { wrapperMarkupIn } from "./lib/doc-wrappers.mjs"; + +test("clean prose reports no leaked generation-wrapper markup", () => { + const markdown = [ + "# Title", + "", + "Body prose that talks about content and invoking tools without any tags.", + "", + "- [A link](other.md)", + "", + ].join("\n"); + + assert.deepEqual(wrapperMarkupIn(markdown), []); +}); + +test("a trailing wrapper is caught with its exact line", () => { + const markdown = ["# Title", "", "Body.", ""].join("\n"); + + assert.deepEqual(wrapperMarkupIn(markdown), [{ line: 4, tag: "" }]); +}); + +test("a tutorial's wrapper is caught", () => { + const markdown = ["Body.", "", ""].join("\n"); + + assert.deepEqual(wrapperMarkupIn(markdown), [ + { line: 2, tag: "" }, + { line: 3, tag: "" }, + ]); +}); + +test("assorted generator envelope tags are all caught", () => { + for (const tag of [ + "", + "", + "", + "", + "", + "", + ]) { + assert.deepEqual(wrapperMarkupIn(`prose\n${tag}\n`), [{ line: 2, tag }]); + } +});