Skip to content

docs: pdfnative-cli 1.4.0 + pdfnative-react 1.2.0 ecosystem alignment - #77

Merged
Nizoka merged 13 commits into
mainfrom
docs/cli-1.4-react-1.2
Aug 29, 2026
Merged

docs: pdfnative-cli 1.4.0 + pdfnative-react 1.2.0 ecosystem alignment#77
Nizoka merged 13 commits into
mainfrom
docs/cli-1.4-react-1.2

Conversation

@Nizoka

@Nizoka Nizoka commented Aug 29, 2026

Copy link
Copy Markdown
Owner

docs: pdfnative-cli 1.4.0 + pdfnative-react 1.2.0 ecosystem alignment

Draft PR body — scratchpad, git-ignored. Branch: docs/cli-1.4-react-1.2main.
Documentation-only: git diff main --stat -- src/ is empty.

Summary

Aligns the entire documentation surface (project docs + /docs site) with the
two satellite releases of 2026-08-26 — pdfnative-cli 1.4.0 (17 → 21
commands, the complete PAdES ladder from the shell, pin ^1.7.0, Node ≥ 22)
and pdfnative-react 1.2.0 (100 % additive: charts v2, print production,
PDF/A diagnostics channel, HTTP caching, 25 lint rules, peer ^1.7.0) — and
ships three new deliverables: a GitHub social-preview image, an honest
"agent-extends-the-local-install" pattern, and a new Ecosystem use cases
guide (31st guide) with four SVG architecture diagrams.

Method: two analysis agents (CLI/react delta + docs-surface inventory, with a
fact-check of the MCP/math story against git history in three repos) + one
verifier agent that spot-checked every high-stakes claim against the sources
before the plan was implemented.

Axis A — CLI 1.4.0 alignment

  • Manifest first (docs/assets/ecosystem.json):
    version 1.4.0, pin ^1.7.0, commandCount 21, commandGroups rewritten
    (Create & edit +metadata · Security +ltv +doc-timestamp · Read &
    extract +compare), assertion cli-command-count → canonical "21
    commands"
    . versions.js fallback bumped.
  • cli.md — the big one: four new command sections
    (metadata, ltv with the air-gapped collect → embed split,
    doc-timestamp, compare); sign gains the full v1.4.0 flag set and the
    B-T note (--timestamp was a reserved flag that failed with
    E_UNSUPPORTED — now functional); verify scope extended
    (rsa-sha384/512, /DocTimeStamp, fieldName/isDocTimestamp) and the
    now-false "sign-side LTV out of scope" line replaced by the ladder;
    inspect --signatures + --check "signatures>=N" + an explicit
    behaviour-change callout (--check signed no longer counts unsigned
    placeholders); render --strict/print/charts-v2/image-blocks; batch --manifest (a 14-command whitelist, @id refs, --allow-network);
    E_* list → 12 (+E_NETWORK + troubleshooting entries); schema → 19
    subjects; security model rewritten (network is opt-in behind the SSRF
    guard — the old "opens no network connections" absolute was about to become
    false); Node ≥ 22; new "What's new in v1.4.0" release-history entry with
    the historical verify-docs:allow markers.
  • Cross-surface truth updates: surfaces.json
    ltv row supported: falsetrue (since: 1.4.0) + new
    capability rows Update metadata, Compare two PDFs, Runtime font
    registration
    ; choose.md matrix + the "LTV differs
    by surface" honest note rewritten around per-invocation opt-ins and the air
    gap; README, llms.txt ×2, agent-brief, architecture (ASCII + SVG <desc> +
    visible label), quickstart, onboarding, learn/08, guides TOC, AGENTS.md.
  • "semver-accepts 1.7.0" purged everywhere — the pins now match the
    engine version, so the workaround phrasing is retired.

Axis B — React 1.2.0 alignment

  • Manifest + versions.js: 1.2.0, peer ^1.7.0.
  • react.md: charts v2 (9 kinds, axis2, xAxis
    category/linear/time + log, dataLabels…), new Print production &
    conformance diagnostics
    section (<Document print>, PrintOptions,
    layout.strict/onDiagnostic, DocSpec print with the honest
    "only strict is JSON-safe" note), renderToResponse
    etag/cacheControl + eager streamability validation, lint 18 → 25
    (the 7 new rules, incl. L_PRINT_BOXES delegating to the engine),
    setDeflateImpl + the 8 new types, and a new Release history section
    (react.md had none). The prominent "resolveFonts produces an invalid
    fontRef"
    caveat is rewritten as fixed in 1.2.0 with a re-render
    advisory for documents produced through the buggy path.
  • index.html JSON-LD/badges/prose, playground card, guides TOC.

Axis C — Playgrounds

  • cli.html: full catch-up 9 → 21 panels
    (the 8 missing 1.3.0 commands and the 4 new 1.4.0 ones), 13 new presets
    (sign-timestamp B-T, ltv-add/air-gap, doc-timestamp, compare-ci,
    metadata-update, batch-manifest, render-strict…), new fields on existing
    panels (sign ×9, render --strict/--chunk-size, inspect
    --signatures/--check signatures>=N/--password, verify
    --revocation/--summary, annotate --password), per-command validation
    rules (ltv --online gate, doc-timestamp --url required, metadata
    exclusivity, batch mode conflicts…), positional handling for
    ltv/compare/schema/completion, and a fix for the latent reset
    bug
    (it only cleared 4 of the command states). Inline script passes
    node --check.
  • react.html: importmap →
    pdfnative-react@1.2.0; two new presets — Charts v2 (stackedBar +
    dual-axis line + scatter with xValues, shapes verified against the engine
    types) and Print production (print={{ bleed, marks }}); DocSpec section
    notes the print field.

Axis D — New deliverables

  1. GitHub social preview — the referenced
    repository-open-graph-template.png does not exist anywhere in the repo
    (verified: tree, git log --all, ignored files), so
    social-preview.svg was authored on the
    og-image brand charter at 1280×640 (2:1) with a 40 px safe margin, and
    rasterised to social-preview.png via the
    documented headless-Chrome procedure (verified IHDR 1280×640, 371 KB —
    under GitHub's 1 MB cap).
    → Manual step after merge: upload the PNG in GitHub Settings → General →
    Social preview.
  2. Agent-driven local extension (honest version) — the original memory
    ("MCP shipped math before the core") was fact-checked and corrected: the
    engine shipped Noto Sans Math first (1.5.0), the MCP bundles no fonts and
    resolves them from the local pdfnative install at runtime. What actually
    happened — a coding agent extended the local installation before the
    upstream release — is now documented as a pattern:
    agentic-workflows.md gains "Via the
    MCP server — the local install is the extension point"
    (with the two
    honest limits: closed lang enum in the published tool schema; no
    operator-level fonts variable yet — roadmap, never claimed as shipped),
    mcp.md gains a "Fonts come from the local pdfnative
    install"
    section, and surfaces.json gains the Runtime font registration
    row.
  3. use-cases.md — new guide (31st) with four
    architectures, each anchored on shipped APIs and closing with honest
    limits, plus four hand-authored SVG diagrams
    (use-case-{spec-storage,airgap-ltv,ci-gate,edge-cache}.svg, house
    conventions: 960×560, role="img", narrative <desc> mirrored in the
    alt, prefixed markers, literal hex):
    1. Store the spec, not the PDF — DocSpec JSON (~2 KB) + on-device render
      (uncompressed by default; optional sync zlib deflate via setDeflateImpl).
    2. Air-gapped PAdES B-LTAltv collect --online → JSON transfer →
      offline embeddoc-timestamp.
    3. CI document-regression gatecompare exit codes +
      render --strict + optional veraPDF.
    4. Edge-rendered PDFs with honest HTTP cachingrenderToResponse +
      etag/cacheControl.
      Full parity: shell (pre-rendered), TOC, sitemap (.html + .md), llms.txt ×2,
      derived.guides 31.

Axis E — Triple review + fixes (post-implementation audit)

Three audit agents (CLI vs source, React vs source + branch coherence,
SVG geometry / SEO / no-browser AI readability) plus a verifier re-checked
the whole branch. ~180 CLI claims and every react preset were verified against
the actual packages (600 CLI tests and in-memory renders executed). Everything
confirmed exact was left alone; the following was fixed:

  • Blocking (measured): the use-cases Case 1 snippet plugged an async
    CompressionStream('deflate-raw') into setDeflateImpl — the engine's
    hook is synchronous and expects a zlib (RFC 1950) stream, so the
    example produced a silently blank PDF. Rewritten: uncompressed by default
    (bytes stay local), with an honest opt-in via a synchronous zlib deflate
    (fflate zlibSync) and layout.compress. The claim was also purged from
    react.md and the diagram (desc, brick label, alt). downloadBlob usage
    fixed (it takes bytes and builds the Blob itself). Upstream note: the
    engine's own JSDoc carries the same CompressionStream/deflate-raw advice —
    tracked as a follow-up engine PR, out of this docs-only branch.
  • Factual: react.md — resolveFonts fix emits slash-prefixed names
    (/latin), not /F3; log scale lives on axis/axis2, not xAxis.
    cli.md — manifest error classes corrected (invalid flag/network-without-opt-in
    → exit 2/E_USAGE, not E_INPUT) and the example manifest now uses bare
    flag keys (dashed keys are rejected). index.html prose enumerated 20
    commands under "21 commands" (annotate restored). onboarding described
    --template as variable substitution (it deep-merges).
  • SVG geometry (the 3 user-reported defects + 3 found): spec-storage
    engine-brick overflow (split into two lines, boxes re-flowed);
    airgap-ltv corridor widened to 140 px — the enclave rect no longer paints
    over the transfer arrow and its labels; edge-cache return arrow now lands
    on the Browsers brick and the runtime bricks were widened; ci-gate promote
    loop no longer crosses its own labels; two dead zero-width lines removed;
    two sub-pixel overflows (Inter) fixed by widening bricks.
  • SEO: guides ItemList JSON-LD 30 → 31 (use-cases inserted, slug order);
    "30 reference guides" → 31 (×2); playgrounds og:description 493 → 200 chars;
    six >250-char descriptions trimmed; homepage canonical/og:url/hreflang get
    the trailing slash; learn/08 gains the llms.txt alternate link.
  • AI readability: agent-brief.md now names the 1.4.0/1.2.0 headline
    features (PAdES ladder, metadata, compare, charts v2, print,
    renderToResponse caching) and links the use-cases guide; the lone
    .md#fragment deep link and the lone .md guide link in llms.txt fixed;
    use-cases gains two natural inbound links (choose, learn/08).
  • Counters: test canonical bumped to 2691+ tests across 123 files (suite re-measured after the new recipe and perturbation tests)
    (suite re-measured; 20 hand-maintained sites + manifest updated).
  • CLI minors: sigObjNum added to the --signatures inventory,
    listSignatures to the compare dispatch row, --chunk-size default 65536,
    --digest+ECDSA documented as a hard usage error, trapped reported
    unconditionally, --pretty/--dry-run/render-options rows completed on
    verify/encrypt/batch, playground manifest-vs-input-dir now an error (as the
    CLI behaves).

Axis F — AI-readability hardening (post-evaluation)

Three evaluator agents (cold-start discovery, task-driven, adversarial) rated
the no-browser concept 8.5 / 7.5 / 7 out of 10 and confirmed it works; every
weakness they found was then instructed against the sources and fixed:

  • responsibility.html told a falsehood on the credibility page: it still
    claimed sign --timestamp "is not yet implemented". Rewritten around the
    five explicit network opt-ins + the SSRF guard; the §not-claimed item, the
    playground "nothing but the page" overclaim, the pre-render nuance, the
    "22 writing systems" wording and the missing Learn nav link fixed too. A
    new manifest assertion (cli-network-optins, canonical + forbid) pins the
    fact so it can never silently regress.
  • 23 of 31 llms-index summaries were severed mid-sentence (the FAQ's was
    a line of source code) — a deterministic generator bug that
    llms-index-sync could never catch, since it compares the bug against
    itself. The lede extraction is now anchored on the H1 and takes the whole
    blockquote; truncation cuts at sentence boundaries (budget 400, exported);
    and a new rule, llms-index-quality, asserts every committed summary
    is usable prose. Three weak guide ledes (tables, faq, streaming) rewritten.
  • Freshness is now a checked contract: llms.txt (×2) and agent-brief.md
    carry a Verified on stamp, and the new verified-on-parity rule
    requires every stamp (incl. surfaces.json / errors.json verifiedOn, which
    had already drifted 4 days) to equal the manifest's date exactly.
    sitemap-parity now also bounds every lastmod to the manifest's audit
    window, and the sitemap/build-guides comments cross-reference the
    "audit date, never a git date" doctrine.
  • llms.txt graph completed: the obsolete "guides render client-side"
    note replaced (guides are pre-rendered — CI-enforced), self-verify and
    choose gain their own entries (31/31 guides now directly linked),
    errors.json is finally referenced, and llms-index prices api.json
    (~30k tokens), surfaces.json and errors.json.
  • agent-brief.md gains verified pitfall chore(deps): bump eslint from 9.39.4 to 10.2.0 #6layoutOptions ?? params.layout REPLACES, never merges, so a second argument silently drops
    a tagged: 'pdfa2b' — plus direct links to choose.md and surfaces.json
    (the artefact that resolves the React-forms trap).
  • The PAdES ladder is now actually PAdES: use-cases Case 2 signs with
    --profile pades (the default pkcs7 is a valid CMS signature but not an
    ETSI EN 319 142-1 baseline), the diagram/desc/alt say so, and cli.md ports
    the CLI's own "Typical PAdES ladder" block next to --timestamp.
  • First non-library recipe: recipes/docspec-invoice.ts (@surface react) renders a stored DocSpec through pdfnative-react and reads it back
    with the engine's parser — CI-executed like the other 14 (now 15).
    devDependencies gain pdfnative-react + react (docs-infra only; the
    engine keeps zero runtime dependencies).
  • npm run docs:all makes the mandatory regeneration order executable.
  • verify-docs: 22 → 24 rules across 137 files, all green; docs suites
    extended with three new perturbation tests.

Follow-ups planned (separate PRs): run pdfnative-cli's existing
samples/**/*.sh corpus in that repo's CI; embed the docs corpus in
pdfnative-mcp with list_guides/get_guide as MCP resources and one
search_docs tool (28 → 29), then mirror the manifest here after the npm
release. Engine-side JSDoc fix (CompressionStream/deflate-raw advice) also
tracked separately.

Counters before → after

Counter Before After
pdfnative-cli 1.3.0, pin ^1.6.0 1.4.0, pin ^1.7.0, Node ≥ 22
CLI commands (canonical) 17 commands 21 commands
CLI E_* codes 11 12 (+E_NETWORK)
CLI schema subjects 15 19
pdfnative-react 1.1.0, peer ^1.6.0 1.2.0, peer ^1.7.0
React lint rules 18 25
Guides 30 31 (use-cases)
Sitemap URLs 87 89
verify-docs scope 129 files 136 files
Test canonical 2691+ across 123 files 2691+ across 123 files

Unchanged: pdfnative 1.7.0 · mcp 1.6.0 (28 tools) · 10 playgrounds ·
14 recipes · 22 scripts · 13 block types.

Explicitly NOT claimed (verified not shipped)

CLI: optimize, visual/pixel diff, --font-file, link annotations in
annotate, man pages, category commands; ltv/compare inside batch --manifest (positionals). React: signatures/LTV/DSS, updateMetadata,
fill/merge/extract (post-process with engine or CLI — by design). MCP:
operator-level font extension (roadmap). veraPDF is never bundled anywhere.

Behaviour changes worth flagging to readers

  • inspect --check signed (CLI 1.4.0) no longer counts unsigned placeholders
    or /DocTimeStamp revisions — documented as a deliberate correctness fix in
    the command section and the release history.
  • React resolveFonts fix — documents rendered through
    resolveFonts/options.fonts under 1.1.0 should be re-rendered.
  • Node 20 dropped by the CLI (EOL 2026-04-30).

Verification

  • npm run verify:docs24 rules green across 137 files.
  • npx vitest run tests/docs/ — 44/44 incl. three new perturbation tests (one earlier needle updated:
    jsonld-version now patches "softwareVersion": "1.4.0").
  • Full npm test suite green (docs-only branch; git diff main -- src/ = 0).
  • Regeneration order respected: docs:guidesdocs:apidocs:llms;
    llms.txtdocs/llms.txt byte-identical.
  • CLI playground inline script: node --check clean; react playground preset
    shapes verified against src/types (scatter xValues, axis2 fields,
    PrinterMarksOptions).
  • Social preview PNG: IHDR verified 1280×640.

Post-merge manual steps

  1. Upload docs/assets/social-preview.png in GitHub Settings → General →
    Social preview
    .
  2. Optionally run npm run verify:docs -- --online once npm's caches settle
    to confirm registry alignment (manifest ↔ published versions).

Nizoka added 13 commits August 29, 2026 16:59
- manifest first: cli 1.4.0 (pin ^1.7.0, 21 commands in five groups,
  canonical assertion 17 -> 21), react 1.2.0 (peer ^1.7.0)
- cli.md: four new command sections (metadata, ltv, doc-timestamp, compare),
  functional sign --timestamp (PAdES B-T) and the full flag set, verify
  scope (rsa-sha384/512, /DocTimeStamp), inspect --signatures and the
  --check signed behaviour-change callout, batch --manifest with a
  14-command whitelist, E_NETWORK (12 codes), 19 schema subjects, opt-in
  network security model, Node >= 22, v1.4.0 release-history entry
- react.md: charts v2, print production + conformance diagnostics section,
  renderToResponse etag/cacheControl, lint 18 -> 25, setDeflateImpl + new
  types, resolveFonts caveat rewritten as fixed with re-render advisory,
  new Release history section
- choose.md + surfaces.json: CLI ltv row now supported (since 1.4.0),
  new update-metadata and compare capability rows, LTV transport note
  rewritten around per-invocation opt-ins and the air-gapped split
- playgrounds: cli.html catches up 9 -> 21 panels with presets, per-command
  validation, positional handling and the reset-state fix; react.html
  importmap 1.2.0 + charts-v2 and print presets (shapes checked against
  the engine types)
- purge the 'semver-accepts 1.7.0' phrasing now that pins match the engine;
  propagate 21 commands / versions across README, llms.txt x2, agent-brief,
  architecture (ascii + svg desc + visible label), quickstart, onboarding,
  learn/08 and the homepage (JSON-LD, badges, command table)
…review

- new guide docs/guides/use-cases.md (31st, derived.guides 30 -> 31):
  four architectures anchored on shipped APIs with honest limits — store
  the DocSpec instead of the PDF (on-device render via setDeflateImpl +
  CompressionStream), air-gapped PAdES B-LTA (ltv collect -> offline
  embed -> doc-timestamp), a CI document-regression gate on compare exit
  codes, and edge-rendered PDFs with etag/cacheControl; four hand-authored
  SVG diagrams following the house conventions (960x560, role=img,
  narrative desc mirrored in alt, prefixed markers, literal hex)
- agentic-workflows.md: new 'Via the MCP server — the local install is
  the extension point' pattern; the MCP bundles no fonts and resolves the
  local pdfnative package at runtime, so an agent can extend the local
  install ahead of an upstream release (how the math-symbols gap was
  closed before Noto Sans Math shipped in 1.5.0), with the two honest
  limits stated (closed lang enum; operator-level extension is roadmap);
  mcp.md gains the matching 'Fonts come from the local install' section
- docs/assets/social-preview.svg (1280x640, 2:1, 40px safe margin, brand
  charter) + rasterised social-preview.png via the documented headless
  Chromium procedure (IHDR verified); GitHub upload stays a manual step
- parity: guides TOC, sitemap (.html + .md entries, lastmod bumps),
  llms-full/llms-index regenerated (docs:guides -> docs:api -> docs:llms)
The sandbox perturbation patched softwareVersion 1.3.0, which no longer
exists in docs/index.html after the CLI bump; the needle is now 1.4.0
(patched to 1.3.0 to provoke the mismatch).
- use-cases case 1 rewritten to be runnable: setDeflateImpl is synchronous
  and expects a zlib (RFC 1950) stream, so the async CompressionStream
  deflate-raw example produced silently blank content streams — the case now
  renders uncompressed by default (bytes stay on-device) with an honest
  opt-in via a synchronous zlib deflate (fflate zlibSync) and
  layout.compress; downloadBlob takes the bytes and builds the Blob itself
- react.md: the resolveFonts fix emits slash-prefixed names (/latin), not
  /F3-style ones; the log scale lives on axis/axis2 (value axes), never on
  xAxis; the CompressionStream claim removed from Fonts & environment
- cli.md: manifest error classes corrected (invalid flag name/value or a
  network flag without --allow-network exit 2/E_USAGE; ids, non-whitelisted
  commands and broken @refs exit 1/E_INPUT; malformed JSON 1/E_PARSE) and
  the example manifest now uses bare flag keys, which is what the parser
  accepts; sigObjNum added to the --signatures inventory; listSignatures
  added to the compare dispatch row; --chunk-size default 65536 documented;
  --digest sha384/512 with ECDSA documented as a hard usage error; trapped
  reported unconditionally; --pretty (verify), --dry-run (encrypt) and the
  batch report/render-option rows completed; --manifest declared mutually
  exclusive with --input-dir
- onboarding: --template deep-merges a base document, it does not inject
  variables
- homepage: the 21-command prose enumeration was missing annotate; the
  inspect row now lists --signatures and the signatures>=N check
- playground: the --signatures hint lists the full field set and the
  manifest/--input-dir conflict is an error, matching the CLI's exit 2
- choose.md: charts v2 note on the React cell (parity with surfaces.json)
  and a Further-reading link to the use-cases guide
- agent-brief: names the 1.4.0/1.2.0 headline features and links use-cases
- mcp.md: the deep link to the agentic-workflows anchor now targets the
  .html rendering so the fragment resolves
Verified against per-character text metrics; fixes the three user-reported
defects plus three found in review:

- spec-storage: the engine-brick caption overflowed its box — split into two
  lines (and reworded per the compression fix), the flow below re-spaced,
  and the crossed-out storage box widened past its own caption
- airgap-ltv: the enclave rect was painted over the controlled-transfer
  arrow and its labels (z-order) and the 80px corridor could not fit them —
  both zones narrowed to 370px for a 140px corridor, children recentred,
  amber/indigo bricks widened; the labels now clear both zones
- edge-cache: the return arrow ended 6px right of and 30px below the
  Browsers brick — it now lands on its corner; the runtime bricks widened
  to 286px so their captions no longer touch the borders
- ci-gate: the promote loop crossed its own three labels — control points
  pulled in (x max ~786 vs labels at x>=795); two dead zero-width lines
  removed
- guides ItemList JSON-LD 30 -> 31 with the use-cases entry in slug order;
  'All 30 reference guides' -> 31 on the learn index and step 8
- playgrounds og:description cut from 493 to 200 chars; the six >250-char
  descriptions trimmed (homepage, cli, choose, mcp, use-cases) — the guide
  generator mirrors the meta into the TechArticle JSON-LD
- homepage canonical/og:url/hreflang gain the trailing slash to match the
  sitemap; learn/08 gains the llms.txt alternate link and a use-cases entry
- llms.txt x2: the one .md guide link now points at choose.html like its 29
  siblings
- test canonical bumped to '2687+ tests across 123 files' after re-measuring
  the suite (manifest declared.tests + 20 hand-maintained sites)
- docs:guides + docs:llms regenerated in one pass; verify:docs green
  (22 rules across 136 files); docs suites 40/40
The credibility page still claimed sign --timestamp 'is not yet
implemented' — false since pdfnative-cli 1.4.0 shipped it, and the kind of
drift the page exists to forbid. The scoped exception now names the five
explicit network opt-ins (verify --revocation online, sign --timestamp,
ltv --online, doc-timestamp --url, batch --allow-network) and the SSRF
guard, both in the claim block and in the not-claimed section; the
verify-it pointer now targets evidence that actually supports the claim
(the CLI guide's security model and fetch-guard.ts) instead of
SECURITY.md, which has no network section. Also: the playground claim no
longer overstates ('nothing but the page you already loaded' — the engine
is loaded from a pinned CDN URL), the marked/DOMPurify note says they are
a progressive-enhancement fallback since the pre-render, '22 writing
systems' now also states the canonical '22 scripts' form so the
script-count assertion covers this page, and the nav gains the Learn link
every other page has.
llms-index-sync proves the machine index is fresh by rebuilding it and
comparing bytes — which made it structurally blind to a deterministic
generator bug: the lede extraction stopped at the first physical line
($ under /m), matched anywhere in the file, and slice(300) cut
mid-word, so 23 of 31 summaries shipped severed and the FAQ's was a line
of source code, green forever.

- build-llms-full: ledeQuote() anchors on the H1 and takes the whole
  contiguous blockquote; cleanSummary() un-italicises a fully-italic lede
  without touching inline code; truncateSummary() cuts at sentence
  boundaries (budget SUMMARY_MAX=400, exported) or word+ellipsis; the
  firstPara fallback refuses fenced code. Measured: 30/31 summaries end
  on a full stop, 1 ellipsis, 0 mid-word cuts.
- new rule llms-index-quality reads the committed index as content:
  non-empty, not code-shaped, sentence-terminal, within budget, no
  unstripped Markdown, title not a filename fallback.
- new rule verified-on-parity: llms.txt x2, agent-brief.md, surfaces.json
  and errors.json must carry exactly the manifest's verifiedOn
  (errors.json had already drifted four days behind).
- sitemap-parity now bounds every lastmod to the manifest's audit window
  (verifiedOn -45d .. +1d); the sitemap header and the build-guides
  no-dateModified note cross-reference the shared doctrine: lastmod is an
  audit date, never a git date (shallow CI checkout).
- manifest: cli-network-optins assertion (canonical + forbid) pins the
  responsibility-page fact; script-count now also requires
  responsibility.html; derived.recipes 15; declared tests re-measured.
- three perturbation tests added; prose counters 22 -> 24 offline rules.
- llms.txt (x2, byte-identical): the 'guides render their markdown
  client-side' note was obsolete — every guide is pre-rendered and
  CI-enforced; rewritten to say so (the .md stays the cheaper fetch).
  self-verify gains the entry it never had (the graph now links all 31
  guides directly), choose gets its own entry, errors.json is finally
  referenced, and a 'Verified on' stamp sits between the summary and the
  first section, tied to the manifest by verified-on-parity.
- agent-brief.md: same stamp; new verified pitfall #6 — the second
  argument of buildDocumentPDFBytes REPLACES params.layout (never a
  merge), so { creationDate } alone silently drops a tagged: 'pdfa2b'
  claim; spread params.layout instead. Same semantics in
  inspectDocumentLayout and the streaming variants; buildPDFBytes is the
  mirror case (PdfParams has no layout field). Plus direct links to
  choose.md and surfaces.json — the artefact that resolves the
  React-cannot-fill-forms trap the task evaluation hit.
- three weak guide ledes rewritten as real page summaries (tables, faq,
  streaming) in the house '> **...**' form.
use-cases Case 2 signed with the default pkcs7 profile — a valid CMS
signature, but /SubFilter /adbe.pkcs7.detached is not an ETSI EN 319
142-1 baseline, so the whole B-T -> B-LTA chain sat on a non-PAdES
foundation while claiming otherwise. The sign command now passes
--profile pades with a one-line note; the diagram brick, its desc and
the markdown alt say the same thing (kept word-identical). cli.md pairs
--timestamp with --profile pades on the flag row and ports the CLI's own
'Typical PAdES ladder' block next to the B-T callout — the pairing
existed only in the tool's --help until now.
recipes/docspec-invoice.ts (@surface react) renders a persisted DocSpec
through renderSpecToBytes — synchronous, DOM-free — and reads the bytes
back with the engine's own parser, CI-executed like the other fourteen.
It is the recipe the task evaluation was missing: the store-the-spec
architecture now has a mechanically proven reference.

devDependencies gain pdfnative-react + react (docs-infra only: they
exercise the published renderer in the recipe suite; the engine keeps
zero runtime dependencies and src/ is untouched). The recipe import
allow-list widens to pdfnative-react; package.json gains docs:all so the
mandatory docs:api -> docs:guides -> docs:llms order is executable.
docs:all pass after all source edits: llms-full/llms-recipes/llms-index
rebuilt (all 31 summaries are now complete prose; api.json, surfaces.json
and errors.json are finally priced in the artefacts table), the five
edited guide shells re-rendered, and the test canonical re-measured at
2691+ tests across 123 files after the new recipe and perturbation tests
(manifest + the twenty hand-maintained sites).

verify:docs green — 24 rules across 137 files; docs suites 44/44; full
suite 2691/2691.
The 'produces byte-identical output' test built the document twice with
the wall-clock /CreationDate, so it flaked whenever the two calls
straddled a second boundary (the content-derived trailer /ID diverges
with it). Pin the date as pdf-stream-pagebypage.test.ts already does —
merged into the single layout object, not passed as a second argument,
because layoutOptions replaces params.layout and would silently drop the
viewerPreferences under test. 5 consecutive runs green.
@Nizoka Nizoka self-assigned this Aug 29, 2026
@Nizoka Nizoka added the documentation Improvements or additions to documentation label Aug 29, 2026
@Nizoka
Nizoka merged commit 257abdf into main Aug 29, 2026
8 checks passed
@Nizoka
Nizoka deleted the docs/cli-1.4-react-1.2 branch August 29, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant