mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 17:45:53 +01:00
docs(runner): strip leaked generation wrappers, sync Phase 7 counts, guard against regressions
Remove trailing generation-wrapper markup (</content>, plus </invoke> 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 <noreply@anthropic.com>
This commit is contained in:
1 parent
2cd4462e95
commit
ab7b85878a
15 files changed
+82
-23
No files matched your search
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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)
|
||||
</content>
|
||||
@@ -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).
|
||||
</content>
|
||||
</invoke>
|
||||
@@ -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.
|
||||
</content>
|
||||
@@ -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?
|
||||
</content>
|
||||
@@ -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",
|
||||
|
||||
@@ -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 `</content>` or `</invoke>` 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 </content> wrapper is caught with its exact line", () => {
|
||||
const markdown = ["# Title", "", "Body.", "</content>"].join("\n");
|
||||
|
||||
assert.deepEqual(wrapperMarkupIn(markdown), [{ line: 4, tag: "</content>" }]);
|
||||
});
|
||||
|
||||
test("a tutorial's </invoke> wrapper is caught", () => {
|
||||
const markdown = ["Body.", "</content>", "</invoke>"].join("\n");
|
||||
|
||||
assert.deepEqual(wrapperMarkupIn(markdown), [
|
||||
{ line: 2, tag: "</content>" },
|
||||
{ line: 3, tag: "</invoke>" },
|
||||
]);
|
||||
});
|
||||
|
||||
test("assorted generator envelope tags are all caught", () => {
|
||||
for (const tag of [
|
||||
"<content>",
|
||||
"<invoke name=\"Bash\">",
|
||||
"<parameter name=\"x\">",
|
||||
"<function_calls>",
|
||||
"</function_results>",
|
||||
"<invoke>",
|
||||
]) {
|
||||
assert.deepEqual(wrapperMarkupIn(`prose\n${tag}\n`), [{ line: 2, tag }]);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user