Skip to content

docs: fix live drift in extension, responses API, and channel docs (doc-truth PR 1/5) - #7375

Merged
thisisjoshford merged 5 commits into
mainfrom
docs/fix-live-drift
Aug 8, 2026
Merged

thisisjoshford merged 5 commits into
mainfrom
docs/fix-live-drift

Conversation

@thisisjoshford

Copy link
Copy Markdown
Contributor

Summary

  • Rewrites the manifest sections of docs/extensions/building-a-tool.md to the current reborn.extension_manifest.v3 authoring format ([[tools]], [[tools.credentials]], [auth.<vendor>], [mcp]) — the page previously taught the legacy v2 [[host_api]] / [capability_provider.tools] shape, which the v3 parser hard-rejects (crates/extensions/ironclaw_extension_registry/src/v3.rs uses deny_unknown_fields), and never mentioned origin_gate_matrix. This is the exact drift class called out in Proposal: Doc-Truth Verification Pipeline #7317.
  • Adds an "Origin gate matrix" section documenting origins (loop_run/product/automation), the five policies from OriginGatePolicy, the forbidden-by-default rule, and the reborn_origin_gate_matrix_ratchet.rs shipping requirement.
  • Corrects docs/api/responses.mdx against crates/product/ironclaw_openai_compat: temperature is accepted (0.0–2.0 inclusive, forwarded) not rejected; model is required and any well-formed ≤256-byte name (not "must be default"); max_output_tokens and other unknown fields are accepted-and-ignored by DTO policy, not rejected; non-empty tools is rejected only without external-tools wiring. Adds the required model field to all 15 request examples (they would 400 as written — pinned by tests/dto_contract.rs).
  • Fixes docs/channels/building-a-channel.mdx install instructions, which pointed at crates/ironclaw_first_party_extensions/... and available_extensions.rs registration — neither mechanism exists; replaced with the package-directory + ironclaw_extension_support package-module mechanism.
  • Corrects the fenced docs/reborn/contracts/extensions.md claim that production manifests use v2 (they author v3, which lowers into the v2 resolved model), and banners docs/reborn/how-to-port-tool-to-reborn.md as superseded.

Change Type

  • Documentation

Linked Issue

Related #7317 — PR 1 of the 5-PR doc-truth pipeline plan (drift fixes land first so the follow-up gates land green). Follow-ups: docs path-reference gate (check-guidance), doc-fact contract tests, docs-live release automation + changelog, design doc.

Validation

  • python3 scripts/ci/docs_publication_boundary.py — every page published or fenced
  • grep -rn "extension_manifest.v2" docs/ — hits remain only in docs/internal/ (historical ADR/plans) and explicitly-labeled legacy examples in fenced docs/reborn/
  • Every repo path cited by the edited pages verified to exist (two dead crates/app/ironclaw_composition/src/mcp.rs references fixed to crates/extensions/ironclaw_extension_host/src/mcp.rs)
  • Manifest examples cross-checked against shipped v3 manifests (crates/extensions/packages/{github,notion-mcp,nearai-mcp}/manifest.toml) and RawManifestV3/RawToolV3/RawMcpV3 struct fields
  • Responses API claims cross-checked against validate_responses_supported_fields, validate_temperature, validate_model_name, and the DTO contract tests

Test Strategy

User behavior: documentation-only; no runtime behavior changes.

Risk areas: none of the listed categories (docs only).

Tests added or updated:

  • Unit or contract: Not applicable: docs-only PR; deterministic doc-fact contract tests pinning these exact claims (CLI reference, manifest schema version, Responses request policy) land in the follow-up PR so they arrive green.
  • Reborn integration / Recorded fixture / Browser E2E / Backend or runtime / Live canary: Not applicable: docs-only.

What the tests prove: n/a (see follow-up PR).

Commands run: python3 scripts/ci/docs_publication_boundary.py; greps above.

Security Impact

None. Documentation only; the corrected text describes existing enforced behavior (origin gate matrix, credential mediation) more accurately than before.

Reborn Trust-Boundary Checklist

N/A — documentation-only change; no code, policy, or trust-bearing types touched.

🤖 Generated with Claude Code

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of #7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 7, 2026 21:17
@railway-app

railway-app Bot commented Aug 7, 2026

Copy link
Copy Markdown

This PR was not deployed automatically as @thisisjoshford does not have access to the Railway project.

In order to get automatic PR deploys, please add @thisisjoshford to your workspace on Railway.

@github-actions github-actions Bot added the scope: docs Documentation label Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Updated Responses API guidance for model routing, temperature, external tools, validation, and unsupported fields.
    • Revised channel installation instructions for host-bundled packages and runtime discovery.
    • Updated tool-building guidance for the current extension manifest format, including authentication, MCP, packaging, OAuth, and validation.
    • Documented extension manifest support for tools, channels, vendor authentication, MCP, and origin controls.
    • Clarified that the tool-porting guide contains historical examples and is not the current authoring reference.

Walkthrough

The documentation updates revise Responses API request requirements and examples. They also update extension and channel guides for manifest v3, credentials, origin policies, hosted MCP, package registration, and Reborn v2 compatibility.

Changes

API and extension documentation

Layer / File(s) Summary
Responses API contract and examples
docs/api/responses.mdx
The Responses API now requires a validated model, documents temperature and 400 validation behavior, and updates examples, usage retrieval, ignored fields, and timeout limits.
Extension manifest v3 authoring and packaging
docs/extensions/building-a-tool.md, docs/channels/building-a-channel.mdx
The guides replace legacy manifest and package instructions with v3 tools, credentials, origin policies, hosted MCP configuration, self-contained packages, registry guidance, and PACKAGES registration.
Reborn manifest compatibility guidance
docs/reborn/contracts/extensions.md, docs/reborn/how-to-port-tool-to-reborn.md
The documentation identifies v3 as the production format, retains installed v2 parsing, excludes the former production shape, and marks historical v2 authoring examples as superseded.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • nearai/ironclaw#6745: Related Reborn skill-system and extension-loading documentation context.
  • nearai/ironclaw#6970: Related channel and tool-building documentation for Reborn v3 manifests and packaging.

Suggested reviewers: serrrfirat

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main changes and validation, but omits required Database Impact, Blast Radius, Rollback Plan, Review Follow-Through, and Review track sections. Add all missing template sections and state N/A with reasons where they do not apply to this documentation-only change.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title uses Conventional Commits style and accurately summarizes the documentation corrections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size: S 10-49 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: experienced 6-19 merged PRs labels Aug 7, 2026
@ironloopai

ironloopai Bot commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

🧭 IronLoop Run · Review

This comment updates in place as the Run moves through its stages.

🟥 Final result · Could not complete

🟨 Queued → 🟦 Working → 🟥 Could not complete

Automatic trigger · attempt 1 of 3 · failed after 10s

IronLoop could not complete the review for this Run.

Failure details

  • Failure reference: 853e1ece-34df-4350-9d8d-0ed315e1905a
Run details

Run: 5a8a21dd-9e57-405d-a83a-37b0b26a5d5c
Base: main at d27dba3
Head: docs/fix-live-drift at d5b1d20
Created: 2026-08-07 21:18 UTC
Updated: 2026-08-07 21:19 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/channels/building-a-channel.mdx`:
- Line 323: Update the installation-flow documentation around the host-bundled
and local-development paths to include WebUI Extensions imports, runtime
discovery via /system/extensions/<extension-id>/manifest.toml, and that ironclaw
extension search lists discovered packages while ironclaw extension install
accepts only an extension ID. Keep the local-development directory guidance
separate from the supported Reborn user installation flow.

In `@docs/extensions/building-a-tool.md`:
- Around line 256-264: Clarify the host-port guidance near the “Host ports are
derived from effects” text: state that HostPortCatalog is a validation
allowlist, not a runtime adapter registry, and that effects only select or
validate policy. Specify that host/runtime service crates create adapters only
after authorization and obligation preparation, never from manifests.

In `@docs/reborn/how-to-port-tool-to-reborn.md`:
- Around line 3-14: Update the decision tree in this guide so it no longer
directs authors to retired RuntimeKind::Script or RuntimeKind::Mcp targets.
Either rewrite the affected rows to use the v3 manifest format, including
top-level [mcp] where applicable, or clearly mark the entire decision tree as
historical and not an authoring reference.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97033822-201e-4fac-8499-ca2fcb42fdc5

📥 Commits

Reviewing files that changed from the base of the PR and between d27dba3 and d5b1d20.

📒 Files selected for processing (5)
  • docs/api/responses.mdx
  • docs/channels/building-a-channel.mdx
  • docs/extensions/building-a-tool.md
  • docs/reborn/contracts/extensions.md
  • docs/reborn/how-to-port-tool-to-reborn.md

Comment thread docs/channels/building-a-channel.mdx Outdated
Comment thread docs/extensions/building-a-tool.md
Comment thread docs/reborn/how-to-port-tool-to-reborn.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This documentation-only PR updates Reborn extension and OpenAI-compatible Responses API docs to match current shipped behavior and manifests, reducing “doc drift” that causes users to hit runtime/parser errors when following the guides.

Changes:

  • Updates extension/tool docs to the reborn.extension_manifest.v3 authoring surface ([[tools]], [auth.<vendor>], [mcp], origin_gate_matrix) and removes legacy v2 authoring guidance.
  • Refreshes Responses API documentation and examples to reflect current request validation/acceptance behavior (notably model required and temperature supported).
  • Fixes channel installation guidance to the current host-bundled package + ironclaw_extension_support mechanism, and marks a legacy porting guide as superseded.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/reborn/how-to-port-tool-to-reborn.md Adds a “superseded” banner clarifying the guide’s legacy status and pointing to current v3 authoring docs.
docs/reborn/contracts/extensions.md Corrects the manifest schema version guidance (v3 authoring that lowers into v2 resolved model).
docs/extensions/building-a-tool.md Rewrites the manifest/tutorial sections to v3 ([[tools]], [auth.<vendor>], [mcp], origin_gate_matrix) and updates packaging/runtime lane guidance.
docs/channels/building-a-channel.mdx Fixes host-bundled channel install steps to use crates/extensions/packages/<id>/ + ironclaw_extension_support PACKAGES.
docs/api/responses.mdx Updates supported fields/rules and fixes request examples to include required model.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/api/responses.mdx Outdated
- `temperature` (configure via settings)
- `max_output_tokens` (not yet wired)
- Any `model` other than `"default"`
- `tool_choice` (always — there is no per-request tool-choice surface)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified and fixed in 889f4b3. You're right: validate_responses_supported_fields rejects tool_choice unconditionally (responses_workflow.rs:1179), but the external-tools variant validate_responses_supported_fields_with_external_tools (responses_workflow.rs:1199-1222) never checks it, so with external tools wired tool_choice passes validation and is currently ignored. The bullet now says it is rejected only on deployments without external-tools support, and accepted-but-ignored otherwise.

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 7, 2026 22:34
…ce claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/api/responses.mdx`:
- Around line 172-174: Update the tool_choice behavior documented near the
request error description to match the conditional contract already stated
nearby: reject it when external-tools support is unavailable, but accept and
currently ignore it when external-tools support is enabled. Remove the blanket
claim that every request containing tool_choice returns 400.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8f7fc748-3f0e-405a-894f-db064d145e0b

📥 Commits

Reviewing files that changed from the base of the PR and between d5b1d20 and 889f4b3.

📒 Files selected for processing (4)
  • docs/api/responses.mdx
  • docs/channels/building-a-channel.mdx
  • docs/extensions/building-a-tool.md
  • docs/reborn/how-to-port-tool-to-reborn.md

Comment thread docs/api/responses.mdx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (1)

docs/api/responses.mdx:549

  • The “Limits and quirks” summary says tool_choice is always rejected with 400, but earlier in this doc (and in validate_responses_supported_fields_with_external_tools) tool_choice is only rejected when external-tools support is disabled; with external tools enabled it is currently accepted and ignored. The summary should match that behavior to avoid reintroducing the earlier drift.
- **`tool_choice`**: rejected with `400` on deployments without external-tools support; with external tools enabled it is accepted but ignored. `max_output_tokens` and other unlisted OpenAI fields are accepted and ignored.

Copilot AI review requested due to automatic review settings August 7, 2026 22:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (1)

docs/reborn/how-to-port-tool-to-reborn.md:12

  • The inline code span for the v3 runtime kinds is split across two quoted lines, which breaks Markdown rendering (code spans can’t contain newlines). Keep the entire [runtime] kind = ... snippet on a single line (or use a fenced code block).
> historical: v3 authoring accepts only `[runtime] kind = "wasm" |
> "first_party"`, hosted MCP servers use a top-level `[mcp]` section instead

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 7, 2026 22:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot removed the size: S 10-49 changed lines label Aug 7, 2026
@github-actions github-actions Bot added the size: M 50-199 changed lines label Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/extensions/building-a-tool.md (1)

310-323: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep optional v3 references optional.

Line 320 incorrectly makes output_schema_ref mandatory. The executable v3 contract accepts a tool with output_schema_ref = None.

Line 322 also makes prompt_doc_ref mandatory. docs/reborn/contracts/extensions.md defines it as optional lazy metadata.

Update the field list and checklist. Require packaged assets only for references that the manifest declares.

Proposed wording
- `output_schema_ref`: relative path to JSON schema.
- `prompt_doc_ref`: relative path to concise operation guidance.
+ `output_schema_ref`: optional relative path to JSON schema.
+ `prompt_doc_ref`: optional relative path to concise operation guidance.

- bundled package assets include every manifest ref;
+ bundled package assets include every declared manifest ref;

Also applies to: 696-703

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/extensions/building-a-tool.md` around lines 310 - 323, Update the
required tool-entry field list and the related checklist to make
output_schema_ref and prompt_doc_ref optional, matching the v3 contract and lazy
metadata behavior. Require packaged assets only when the manifest declares the
corresponding references, while keeping declared references subject to
validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/extensions/building-a-tool.md`:
- Around line 789-798: Before finalizing the documentation update in the Quick
implementation checklist, run both required checks from the docs directory: mint
dev and mint broken-links. Resolve any reported issues and confirm both checks
pass.

---

Outside diff comments:
In `@docs/extensions/building-a-tool.md`:
- Around line 310-323: Update the required tool-entry field list and the related
checklist to make output_schema_ref and prompt_doc_ref optional, matching the v3
contract and lazy metadata behavior. Require packaged assets only when the
manifest declares the corresponding references, while keeping declared
references subject to validation.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 08925847-7513-4d60-9b12-a1d1249fc559

📥 Commits

Reviewing files that changed from the base of the PR and between e406099 and 8a7f0e5.

📒 Files selected for processing (4)
  • docs/api/responses.mdx
  • docs/extensions/building-a-tool.md
  • docs/reborn/contracts/extensions.md
  • docs/reborn/how-to-port-tool-to-reborn.md

Comment thread docs/extensions/building-a-tool.md
Copilot AI review requested due to automatic review settings August 7, 2026 23:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@thisisjoshford
thisisjoshford added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit 6dccbfb Aug 8, 2026
44 checks passed
@thisisjoshford
thisisjoshford deleted the docs/fix-live-drift branch August 8, 2026 05:08
thisisjoshford added a commit that referenced this pull request Aug 10, 2026
…drift

Applies the verified findings from the PR #7376 code review:

- The loop-exit and turn-runner contract docs claimed the deleted
  loop_driver_host checkpoint-rejection test had 'moved into the
  module'; it was deleted in #6696 and the fenced verification command
  could not run. Both now cite the real surviving pins
  (planned_driver.rs executor test + the ironclaw_turns projection
  test mapped in scripts/reborn-e2e-rust.sh), with runnable commands.
- An unterminated comment now refuses at EOF like an unterminated
  fence; before, one typo'd closer silently un-scanned the rest of the
  file.
- Markdown links in the re-included corpora are now checked as repo
  paths (they are never published, so the Mintlify-route rationale did
  not apply); this alone added ~165 verified references.
- Each DOCS_REINCLUDED_PREFIXES entry must match at least one tracked
  page or discovery refuses, so the planned docs/reborn consolidation
  cannot silently drop the corpus from the scan.
- The living extension-runtime spec pages (overview.md,
  standard-operations.md) and guidance-conventions.md join the scan;
  guidance-conventions.md now describes the docs surface and the MDX
  marker form, and its one dangling test path is repointed.
- Floors comment corrected (57 rule globs, not 38).

Also fixes four drifted claims from #7375's pages, verified against
live code: the interleaved function_call_output example was rejected
with 400 (resume input must be exclusively function_call_output items
with previous_response_id); model is echoed only on create (GET/cancel
report the 'reborn' placeholder); output_schema_ref is optional; and
the unknown-fields claim now names the two deliberate exemptions.

Self-tests: 43 pass (three new arms — unterminated comment refusal in
both syntaxes, re-included links as repo claims, stale re-included
prefix refusal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
JadeCong pushed a commit to CloudEngineHub/ironclaw that referenced this pull request Aug 11, 2026
…earai#7381)

* docs(internal): record the doc-truth pipeline design (issue nearai#7317)

The as-built design for keeping the public Mintlify docs in sync with
released binaries: the problem evidence, the decisions of record (single
doc tree deploying from a docs-live branch; deterministic gates only;
human-curated changelog), the three enforcement layers (PR-time static
gates, release-time cut/publish automation, human checklist), a
surface-to-gate enforcement table, the deferred follow-ups (release-time
live probes on the packaged binary, an openwiki-style non-blocking LLM
fix-PR generator, flag-level CLI coverage, link integrity, zh freshness,
contract-doc pinned-test re-verification), and the risk register.

Part of nearai#7317 (doc-truth pipeline, PR 5 of 5). Companions: nearai#7375 nearai#7376
nearai#7378 nearai#7379.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(internal): record review hardening in the doc-truth design

Post-implementation review found five gaps; this records their
resolutions where the design doc already claims the guarantees:
planner routing so doc-fact tests run on docs-only PRs, the
changelog entry landing on main before the Monday cut, a
newest-stable-tag guard on publish-docs-live, the force-push
allowance in the docs-live branch-protection shape, and the
docs-hotfix repoint recipe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
pull Bot pushed a commit to Stars1233/ironclaw that referenced this pull request Aug 13, 2026
…oc-truth PR 2/5) (nearai#7376)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): extend the reference gate to the docs/ surface

The public Mintlify tree had no path-reference validation — a published
tutorial told contributors to edit files that no longer exist and nothing
caught it. check-guidance.py already owned the machinery (tracked-tree
resolution, fence exclusion, suppress markers, shrink-only debt, fail-closed
floors), so the docs surface joins the same gate rather than a fork.

- discover_guidance() now collects every tracked docs/**.md|.mdx: published
  pages, the zh/ locale mirror, and the living contract corpus
  docs/reborn/contracts/. Dated archives (docs/internal/, the non-contract
  parts of docs/reborn/) are excluded as classes — measured 2026-08-07,
  705 of 709 dangling docs references sat in those historical corpora, and
  forcing dated plans/ADRs to track today's tree would either rewrite
  history or drown KNOWN_MISSING.
- docs/ files extract backticked inline paths only; Mintlify markdown link
  targets are site routes (extensionless pages, site-absolute /using/cli),
  a different namespace than the tracked tree, so the link extractor is off
  there by design.
- _reference_lines learns MDX comments ({/* ... */}), including
  {/* check-guidance: path-ok */} as the .mdx suppress-marker form, with the
  same one-reference-per-marker and multi-line semantics as HTML comments.
- Floors re-measured and re-dated (364 files / 2276 references; floors
  180/1100), plus a dedicated MIN_DOCS_FILES=60 floor: the aggregate floors
  sit below the guidance-only remainder, so the docs branch of discovery
  silently breaking needs its own refusal. --json now reports docs_files.
- Fixes the four real dangles the new scan found in docs/reborn/contracts/
  (moved nested_dispatch_stream.rs test home, retired event-store migrations
  directory, loop_driver_host tests->src move). KNOWN_MISSING stays empty.
- Self-tests: 8 new cases (dangling docs path fails; Mintlify links are not
  references; MDX marker suppresses exactly one reference; multi-line MDX
  comment hides content; zh discovered; archives excluded but contracts
  scanned; docs fence fails closed; docs floor refuses).
- ws12_workflow_contracts.py: docs/api/responses.mdx and docs/zh/index.mdx
  join the has_guidance in-scope probes so a narrowed trigger regex cannot
  silently skip the gate for public docs.

Part of nearai#7317 (doc-truth pipeline, PR 2 of 5); stacked on nearai#7375.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(contracts): repoint delivery_resolution.rs to its family directory

PR nearai#7157 (merged to main 2026-08-07) cited
crates/ironclaw_outbound/src/delivery_resolution.rs in the
communication-delivery-resolution contract; the crate lives at
crates/domains/ironclaw_outbound/. Caught by this branch's docs surface of
check-guidance.py on the first merge of main after the gate landed —
exactly the drift class it exists for.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): harden the docs gate and fix review-surfaced doc drift

Applies the verified findings from the PR nearai#7376 code review:

- The loop-exit and turn-runner contract docs claimed the deleted
  loop_driver_host checkpoint-rejection test had 'moved into the
  module'; it was deleted in nearai#6696 and the fenced verification command
  could not run. Both now cite the real surviving pins
  (planned_driver.rs executor test + the ironclaw_turns projection
  test mapped in scripts/reborn-e2e-rust.sh), with runnable commands.
- An unterminated comment now refuses at EOF like an unterminated
  fence; before, one typo'd closer silently un-scanned the rest of the
  file.
- Markdown links in the re-included corpora are now checked as repo
  paths (they are never published, so the Mintlify-route rationale did
  not apply); this alone added ~165 verified references.
- Each DOCS_REINCLUDED_PREFIXES entry must match at least one tracked
  page or discovery refuses, so the planned docs/reborn consolidation
  cannot silently drop the corpus from the scan.
- The living extension-runtime spec pages (overview.md,
  standard-operations.md) and guidance-conventions.md join the scan;
  guidance-conventions.md now describes the docs surface and the MDX
  marker form, and its one dangling test path is repointed.
- Floors comment corrected (57 rule globs, not 38).

Also fixes four drifted claims from nearai#7375's pages, verified against
live code: the interleaved function_call_output example was rejected
with 400 (resume input must be exclusively function_call_output items
with previous_response_id); model is echoed only on create (GET/cancel
report the 'reborn' placeholder); output_schema_ref is optional; and
the unknown-fields claim now names the two deliberate exemptions.

Self-tests: 43 pass (three new arms — unterminated comment refusal in
both syntaxes, re-included links as repo claims, stale re-included
prefix refusal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): sync module docstring with re-included link checking

CodeRabbit caught the docstring still claiming the link extractor is
off for all of docs/** — stale since b172f69 enabled it for the
re-included corpora. The docstring now states the exception and the
current re-include set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): drop the docs/reborn re-include machinery after the docs/internal migration

The docs-surface scan carried a double negative — exclude docs/reborn/ as
an archive class, then re-include its living pages via
DOCS_REINCLUDED_PREFIXES — because the old tree mixed dead archives with
living specs. nearai#7559 moved everything under docs/internal/, so the structure
is now: one excluded archive class (docs/internal/), and the living spec
pages (the contract corpus, the two extension-runtime spec pages,
guidance-conventions.md) named in INTERNAL_GUIDANCE_PREFIXES and scanned as
first-class guidance files — full link checking, guarded by the same
per-prefix zero-match refusal. The published-docs floor now counts only the
Mintlify surface (measured 2026-08-13: 82 pages; floor re-halved to 40).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): validate docs discovery against docs.json navigation instead of a count floor

MIN_DOCS_FILES was an arbitrary magnitude tripwire (half of last measured,
hand-re-dated) that only caught the docs branch of discovery losing ~half
its pages. The published surface already has an independent definition —
docs.json navigation, owned by docs_publication_boundary.py — so the gate
now asserts every navigation page's source file is in the reference scan
(reusing the boundary script's nav walker and OpenAPI pseudo-page filter).
Discovery breaking refuses on the first missing published page, unreadable
or page-less navigation refuses rather than passing vacuously, and there
is no docs count floor left to tune. --json reports nav_pages_covered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): count the living internal spec pages in the docs_files metric

CodeRabbit: docs_files under-reported the scan — the living internal spec
pages are scanned docs files but were excluded from the count, a leftover
of the deleted MIN_DOCS_FILES floor's published-only semantics. The metric
now reports every scanned file under docs/ (131 at measurement); published
surface health has its own signal in nav_pages_covered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): tighten comments and docstrings

Same behavior; the docs-surface comments and test docstrings were carrying
paragraph-length rationale better kept in the PR description.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Kampouse pushed a commit to Kampouse/ironclaw that referenced this pull request Aug 13, 2026
…oc-truth PR 1/5) (nearai#7375)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Kampouse pushed a commit to Kampouse/ironclaw that referenced this pull request Aug 13, 2026
…oc-truth PR 1/5) (nearai#7375)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
pull Bot pushed a commit to soitun/ironclaw that referenced this pull request Aug 17, 2026
…claims (doc-truth PR 3/5) (nearai#7378)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): extend the reference gate to the docs/ surface

The public Mintlify tree had no path-reference validation — a published
tutorial told contributors to edit files that no longer exist and nothing
caught it. check-guidance.py already owned the machinery (tracked-tree
resolution, fence exclusion, suppress markers, shrink-only debt, fail-closed
floors), so the docs surface joins the same gate rather than a fork.

- discover_guidance() now collects every tracked docs/**.md|.mdx: published
  pages, the zh/ locale mirror, and the living contract corpus
  docs/reborn/contracts/. Dated archives (docs/internal/, the non-contract
  parts of docs/reborn/) are excluded as classes — measured 2026-08-07,
  705 of 709 dangling docs references sat in those historical corpora, and
  forcing dated plans/ADRs to track today's tree would either rewrite
  history or drown KNOWN_MISSING.
- docs/ files extract backticked inline paths only; Mintlify markdown link
  targets are site routes (extensionless pages, site-absolute /using/cli),
  a different namespace than the tracked tree, so the link extractor is off
  there by design.
- _reference_lines learns MDX comments ({/* ... */}), including
  {/* check-guidance: path-ok */} as the .mdx suppress-marker form, with the
  same one-reference-per-marker and multi-line semantics as HTML comments.
- Floors re-measured and re-dated (364 files / 2276 references; floors
  180/1100), plus a dedicated MIN_DOCS_FILES=60 floor: the aggregate floors
  sit below the guidance-only remainder, so the docs branch of discovery
  silently breaking needs its own refusal. --json now reports docs_files.
- Fixes the four real dangles the new scan found in docs/reborn/contracts/
  (moved nested_dispatch_stream.rs test home, retired event-store migrations
  directory, loop_driver_host tests->src move). KNOWN_MISSING stays empty.
- Self-tests: 8 new cases (dangling docs path fails; Mintlify links are not
  references; MDX marker suppresses exactly one reference; multi-line MDX
  comment hides content; zh discovered; archives excluded but contracts
  scanned; docs fence fails closed; docs floor refuses).
- ws12_workflow_contracts.py: docs/api/responses.mdx and docs/zh/index.mdx
  join the has_guidance in-scope probes so a narrowed trigger regex cannot
  silently skip the gate for public docs.

Part of nearai#7317 (doc-truth pipeline, PR 2 of 5); stacked on nearai#7375.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): pin CLI, manifest, and Responses doc claims to code

Three deterministic doc-fact contract tests, each living in the crate that
owns the truth it checks, so the drift nearai#7317 describes fails CI instead of
shipping:

- crates/app/ironclaw_cli/tests/docs_cli_reference.rs: parses the real
  binary's --help and cross-checks docs/using/cli.mdx table rows both ways
  (every visible subcommand documented, any alias form counting; every
  documented command real), with a fail-closed row floor. Doc gaps this
  surfaced are fixed here: ironhub had no rows at all, completion was
  fence-only, and the Trace Commons table lacked the `ironclaw` prefix the
  rest of the page uses.
- crates/extensions/ironclaw_extension_registry/tests/
  docs_manifest_schema_version.rs: walks the published docs tree (the
  frozen .mintignore fence mirrored as constants) and asserts zero
  occurrences of the retired reborn.extension_manifest.v2 literal, fenced
  code included; asserts building-a-tool.md names
  MANIFEST_SCHEMA_VERSION_V3 verbatim and documents origin_gate_matrix.
- crates/product/ironclaw_openai_compat/tests/docs_responses_contract.rs:
  docs/api/responses.mdx now carries a machine-readable
  {/* doc-fact:responses-request-policy */} marker block (invisible when
  rendered); the test parses it and drives every claim through the same
  route-level seam as the sibling *_contract.rs suites — the marker's
  values parameterize the assertions (temperature accepted at the
  documented max and rejected just above it, model accepted at the byte
  cap and rejected past it, tool_choice always 400, tools 400 without /
  registered with external-tool wiring, empty tools treated as omitted,
  unknown fields like max_output_tokens accepted and ignored, and one
  request carrying every documented field accepted).

Part of nearai#7317 (doc-truth pipeline, PR 3 of 5); stacked on nearai#7376.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): tool_choice is conditionally rejected, not always

Copilot review on the docs PR caught that
validate_responses_supported_fields_with_external_tools never checks
tool_choice — with external tools wired it is accepted and ignored, not
400'd. The doc-fact marker moves tool_choice into
rejected_without_external_tools, and the dedicated test now proves both
sides: 400 naming the param on the plain router, accepted-and-ignored
(submit succeeds, nothing registers) with external-tool wiring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(contracts): repoint delivery_resolution.rs to its family directory

PR nearai#7157 (merged to main 2026-08-07) cited
crates/ironclaw_outbound/src/delivery_resolution.rs in the
communication-delivery-resolution contract; the crate lives at
crates/domains/ironclaw_outbound/. Caught by this branch's docs surface of
check-guidance.py on the first merge of main after the gate landed —
exactly the drift class it exists for.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(test-plan): route docs pages to the doc-fact tests that read them

docs/ sat in IGNORED_PREFIXES as a pure-prose class, which this PR's
doc-fact tests falsify: three cargo tests now read published pages, so
a docs-only PR would have selected zero crate tests and merged green,
leaving the failure to land on whichever unrelated change ran the full
plan next.

Published Markdown now selects the registry's schema-version sweep;
docs/using/cli.mdx and docs/api/responses.mdx additionally select
their owning crates. All selections are direct exact test targets —
no reverse-dependency widening, since prose only changes the doc-fact
assertions that read it. Fenced trees (docs/internal/, docs/reborn/,
drafts) and non-page files keep the prose classification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): harden the docs gate and fix review-surfaced doc drift

Applies the verified findings from the PR nearai#7376 code review:

- The loop-exit and turn-runner contract docs claimed the deleted
  loop_driver_host checkpoint-rejection test had 'moved into the
  module'; it was deleted in nearai#6696 and the fenced verification command
  could not run. Both now cite the real surviving pins
  (planned_driver.rs executor test + the ironclaw_turns projection
  test mapped in scripts/reborn-e2e-rust.sh), with runnable commands.
- An unterminated comment now refuses at EOF like an unterminated
  fence; before, one typo'd closer silently un-scanned the rest of the
  file.
- Markdown links in the re-included corpora are now checked as repo
  paths (they are never published, so the Mintlify-route rationale did
  not apply); this alone added ~165 verified references.
- Each DOCS_REINCLUDED_PREFIXES entry must match at least one tracked
  page or discovery refuses, so the planned docs/reborn consolidation
  cannot silently drop the corpus from the scan.
- The living extension-runtime spec pages (overview.md,
  standard-operations.md) and guidance-conventions.md join the scan;
  guidance-conventions.md now describes the docs surface and the MDX
  marker form, and its one dangling test path is repointed.
- Floors comment corrected (57 rule globs, not 38).

Also fixes four drifted claims from nearai#7375's pages, verified against
live code: the interleaved function_call_output example was rejected
with 400 (resume input must be exclusively function_call_output items
with previous_response_id); model is echoed only on create (GET/cancel
report the 'reborn' placeholder); output_schema_ref is optional; and
the unknown-fields claim now names the two deliberate exemptions.

Self-tests: 43 pass (three new arms — unterminated comment refusal in
both syntaxes, re-included links as repo claims, stale re-included
prefix refusal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): sync module docstring with re-included link checking

CodeRabbit caught the docstring still claiming the link extractor is
off for all of docs/** — stale since b172f69 enabled it for the
re-included corpora. The docstring now states the exception and the
current re-include set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): drop the retired reborn/ entry from the publication-fence mirrors

reborn/ left docs/.mintignore when nearai#7559 consolidated it into internal/;
the fence mirrors in docs_manifest_schema_version.rs and
reborn_pr_test_plan.py still listed it. Fixture paths follow the move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): tighten doc-fact comments and docstrings

Same behavior; module docs and test docstrings trimmed to the point.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): harden the doc-fact suites per CodeRabbit review

- CLI: validate full documented command paths via `ironclaw <path> --help`
  (immediately caught and removed the nonexistent `extension activate` row)
  and match visible aliases as exact tokens, not substrings.
- Responses: seed a real prior response so `previous_response_id` is
  actually submitted and accepted; document `metadata` in the visible table
  to match the marker.
- Manifest sweep: parse the publication fence from docs/.mintignore instead
  of mirroring it, so a removed fence entry widens the scan with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): correct the completion syntax and parse the fence in the planner

Review findings (sub-agent /code-review):
- docs/using/cli.mdx taught `ironclaw completion <shell>`; the binary only
  accepts `--shell <shell>`. The contract test stops extracting at flags,
  so it could not catch this.
- The planner's doc-fact arm mirrored the .mintignore fence as constants —
  the same hand-maintained-mirror class the PR removes elsewhere. It now
  parses docs/.mintignore via docs_publication_boundary, and a .mintignore
  edit itself routes to the published sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(test-plan): treat a missing docs/.mintignore as no fence, not a crash

Matches docs_publication_boundary.find_violations(): fence gone means
everything is published, so every page routes to the sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): replace the doc-fact count floors with derived anchors

Same move as nearai#7376's MIN_DOCS_FILES removal: MIN_DOC_COMMAND_ROWS was
redundant with the completeness check (the binary defines the expected
set), and MIN_SCANNED_PAGES is now a docs.json nav-coverage assertion —
every source-backed navigation route must be among the walked pages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): assert the current schema version instead of scanning for a retired literal

Hardcoding `reborn.extension_manifest.v2` was backward-looking: retiring
v3 would need a hand-edit or the test goes stale. The scan now extracts
every `reborn.extension_manifest.<version>` mention in published pages
and asserts it equals `MANIFEST_SCHEMA_VERSION_V3`, with the family
prefix derived from the same constant — the next schema bump retargets
the test by itself, and typo'd or older versions (v1, v33) are caught
too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
l3ocifer pushed a commit to l3ocifer/frick-ironclaw that referenced this pull request Sep 3, 2026
…oc-truth PR 1/5) (nearai#7375)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
l3ocifer pushed a commit to l3ocifer/frick-ironclaw that referenced this pull request Sep 3, 2026
…earai#7381)

* docs(internal): record the doc-truth pipeline design (issue nearai#7317)

The as-built design for keeping the public Mintlify docs in sync with
released binaries: the problem evidence, the decisions of record (single
doc tree deploying from a docs-live branch; deterministic gates only;
human-curated changelog), the three enforcement layers (PR-time static
gates, release-time cut/publish automation, human checklist), a
surface-to-gate enforcement table, the deferred follow-ups (release-time
live probes on the packaged binary, an openwiki-style non-blocking LLM
fix-PR generator, flag-level CLI coverage, link integrity, zh freshness,
contract-doc pinned-test re-verification), and the risk register.

Part of nearai#7317 (doc-truth pipeline, PR 5 of 5). Companions: nearai#7375 nearai#7376
nearai#7378 nearai#7379.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(internal): record review hardening in the doc-truth design

Post-implementation review found five gaps; this records their
resolutions where the design doc already claims the guarantees:
planner routing so doc-fact tests run on docs-only PRs, the
changelog entry landing on main before the Monday cut, a
newest-stable-tag guard on publish-docs-live, the force-push
allowance in the docs-live branch-protection shape, and the
docs-hotfix repoint recipe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
l3ocifer pushed a commit to l3ocifer/frick-ironclaw that referenced this pull request Sep 3, 2026
…oc-truth PR 2/5) (nearai#7376)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): extend the reference gate to the docs/ surface

The public Mintlify tree had no path-reference validation — a published
tutorial told contributors to edit files that no longer exist and nothing
caught it. check-guidance.py already owned the machinery (tracked-tree
resolution, fence exclusion, suppress markers, shrink-only debt, fail-closed
floors), so the docs surface joins the same gate rather than a fork.

- discover_guidance() now collects every tracked docs/**.md|.mdx: published
  pages, the zh/ locale mirror, and the living contract corpus
  docs/reborn/contracts/. Dated archives (docs/internal/, the non-contract
  parts of docs/reborn/) are excluded as classes — measured 2026-08-07,
  705 of 709 dangling docs references sat in those historical corpora, and
  forcing dated plans/ADRs to track today's tree would either rewrite
  history or drown KNOWN_MISSING.
- docs/ files extract backticked inline paths only; Mintlify markdown link
  targets are site routes (extensionless pages, site-absolute /using/cli),
  a different namespace than the tracked tree, so the link extractor is off
  there by design.
- _reference_lines learns MDX comments ({/* ... */}), including
  {/* check-guidance: path-ok */} as the .mdx suppress-marker form, with the
  same one-reference-per-marker and multi-line semantics as HTML comments.
- Floors re-measured and re-dated (364 files / 2276 references; floors
  180/1100), plus a dedicated MIN_DOCS_FILES=60 floor: the aggregate floors
  sit below the guidance-only remainder, so the docs branch of discovery
  silently breaking needs its own refusal. --json now reports docs_files.
- Fixes the four real dangles the new scan found in docs/reborn/contracts/
  (moved nested_dispatch_stream.rs test home, retired event-store migrations
  directory, loop_driver_host tests->src move). KNOWN_MISSING stays empty.
- Self-tests: 8 new cases (dangling docs path fails; Mintlify links are not
  references; MDX marker suppresses exactly one reference; multi-line MDX
  comment hides content; zh discovered; archives excluded but contracts
  scanned; docs fence fails closed; docs floor refuses).
- ws12_workflow_contracts.py: docs/api/responses.mdx and docs/zh/index.mdx
  join the has_guidance in-scope probes so a narrowed trigger regex cannot
  silently skip the gate for public docs.

Part of nearai#7317 (doc-truth pipeline, PR 2 of 5); stacked on nearai#7375.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(contracts): repoint delivery_resolution.rs to its family directory

PR nearai#7157 (merged to main 2026-08-07) cited
crates/ironclaw_outbound/src/delivery_resolution.rs in the
communication-delivery-resolution contract; the crate lives at
crates/domains/ironclaw_outbound/. Caught by this branch's docs surface of
check-guidance.py on the first merge of main after the gate landed —
exactly the drift class it exists for.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): harden the docs gate and fix review-surfaced doc drift

Applies the verified findings from the PR nearai#7376 code review:

- The loop-exit and turn-runner contract docs claimed the deleted
  loop_driver_host checkpoint-rejection test had 'moved into the
  module'; it was deleted in nearai#6696 and the fenced verification command
  could not run. Both now cite the real surviving pins
  (planned_driver.rs executor test + the ironclaw_turns projection
  test mapped in scripts/reborn-e2e-rust.sh), with runnable commands.
- An unterminated comment now refuses at EOF like an unterminated
  fence; before, one typo'd closer silently un-scanned the rest of the
  file.
- Markdown links in the re-included corpora are now checked as repo
  paths (they are never published, so the Mintlify-route rationale did
  not apply); this alone added ~165 verified references.
- Each DOCS_REINCLUDED_PREFIXES entry must match at least one tracked
  page or discovery refuses, so the planned docs/reborn consolidation
  cannot silently drop the corpus from the scan.
- The living extension-runtime spec pages (overview.md,
  standard-operations.md) and guidance-conventions.md join the scan;
  guidance-conventions.md now describes the docs surface and the MDX
  marker form, and its one dangling test path is repointed.
- Floors comment corrected (57 rule globs, not 38).

Also fixes four drifted claims from nearai#7375's pages, verified against
live code: the interleaved function_call_output example was rejected
with 400 (resume input must be exclusively function_call_output items
with previous_response_id); model is echoed only on create (GET/cancel
report the 'reborn' placeholder); output_schema_ref is optional; and
the unknown-fields claim now names the two deliberate exemptions.

Self-tests: 43 pass (three new arms — unterminated comment refusal in
both syntaxes, re-included links as repo claims, stale re-included
prefix refusal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): sync module docstring with re-included link checking

CodeRabbit caught the docstring still claiming the link extractor is
off for all of docs/** — stale since b172f69 enabled it for the
re-included corpora. The docstring now states the exception and the
current re-include set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): drop the docs/reborn re-include machinery after the docs/internal migration

The docs-surface scan carried a double negative — exclude docs/reborn/ as
an archive class, then re-include its living pages via
DOCS_REINCLUDED_PREFIXES — because the old tree mixed dead archives with
living specs. nearai#7559 moved everything under docs/internal/, so the structure
is now: one excluded archive class (docs/internal/), and the living spec
pages (the contract corpus, the two extension-runtime spec pages,
guidance-conventions.md) named in INTERNAL_GUIDANCE_PREFIXES and scanned as
first-class guidance files — full link checking, guarded by the same
per-prefix zero-match refusal. The published-docs floor now counts only the
Mintlify surface (measured 2026-08-13: 82 pages; floor re-halved to 40).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): validate docs discovery against docs.json navigation instead of a count floor

MIN_DOCS_FILES was an arbitrary magnitude tripwire (half of last measured,
hand-re-dated) that only caught the docs branch of discovery losing ~half
its pages. The published surface already has an independent definition —
docs.json navigation, owned by docs_publication_boundary.py — so the gate
now asserts every navigation page's source file is in the reference scan
(reusing the boundary script's nav walker and OpenAPI pseudo-page filter).
Discovery breaking refuses on the first missing published page, unreadable
or page-less navigation refuses rather than passing vacuously, and there
is no docs count floor left to tune. --json reports nav_pages_covered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): count the living internal spec pages in the docs_files metric

CodeRabbit: docs_files under-reported the scan — the living internal spec
pages are scanned docs files but were excluded from the count, a leftover
of the deleted MIN_DOCS_FILES floor's published-only semantics. The metric
now reports every scanned file under docs/ (131 at measurement); published
surface health has its own signal in nav_pages_covered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): tighten comments and docstrings

Same behavior; the docs-surface comments and test docstrings were carrying
paragraph-length rationale better kept in the PR description.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
l3ocifer pushed a commit to l3ocifer/frick-ironclaw that referenced this pull request Sep 3, 2026
…claims (doc-truth PR 3/5) (nearai#7378)

* docs: fix live drift in extension, responses API, and channel docs

The public tutorial taught the retired manifest v2 authoring format
([[host_api]] / [capability_provider.tools] / runtime_credentials), which
the v3 parser hard-rejects, and never mentioned origin_gate_matrix; the
Responses API page claimed temperature is rejected (accepted 0.0-2.0 and
forwarded), claimed model must be "default" (any well-formed name <= 256
bytes), claimed max_output_tokens is rejected (accepted and ignored by DTO
policy), and omitted the required model field from every request example;
the channel tutorial pointed at two files that no longer exist.

- docs/extensions/building-a-tool.md: rewrite manifest sections to the v3
  [[tools]] / [[tools.credentials]] / [auth.<vendor>] shape, document
  origin_gate_matrix (origins, policies, ratchet), correct the hosted-MCP
  [mcp] section, packaging via ironclaw_extension_support package modules,
  and v3 test references; drop the nonexistent script runtime kind.
- docs/api/responses.mdx: correct model/temperature/tools/tool_choice
  rejection rules, document unknown-field tolerance, add the required
  model field to all 15 request examples.
- docs/channels/building-a-channel.mdx: replace dead
  crates/ironclaw_first_party_extensions + available_extensions.rs
  registration instructions with the current package-directory mechanism.
- docs/reborn/contracts/extensions.md: state that production manifests
  author v3 (lowering into the v2 resolved model described there); label
  the v2 examples as legacy.
- docs/reborn/how-to-port-tool-to-reborn.md: superseded banner pointing at
  the v3 guides.

Part of nearai#7317 (doc-truth pipeline, PR 1 of 5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): extend the reference gate to the docs/ surface

The public Mintlify tree had no path-reference validation — a published
tutorial told contributors to edit files that no longer exist and nothing
caught it. check-guidance.py already owned the machinery (tracked-tree
resolution, fence exclusion, suppress markers, shrink-only debt, fail-closed
floors), so the docs surface joins the same gate rather than a fork.

- discover_guidance() now collects every tracked docs/**.md|.mdx: published
  pages, the zh/ locale mirror, and the living contract corpus
  docs/reborn/contracts/. Dated archives (docs/internal/, the non-contract
  parts of docs/reborn/) are excluded as classes — measured 2026-08-07,
  705 of 709 dangling docs references sat in those historical corpora, and
  forcing dated plans/ADRs to track today's tree would either rewrite
  history or drown KNOWN_MISSING.
- docs/ files extract backticked inline paths only; Mintlify markdown link
  targets are site routes (extensionless pages, site-absolute /using/cli),
  a different namespace than the tracked tree, so the link extractor is off
  there by design.
- _reference_lines learns MDX comments ({/* ... */}), including
  {/* check-guidance: path-ok */} as the .mdx suppress-marker form, with the
  same one-reference-per-marker and multi-line semantics as HTML comments.
- Floors re-measured and re-dated (364 files / 2276 references; floors
  180/1100), plus a dedicated MIN_DOCS_FILES=60 floor: the aggregate floors
  sit below the guidance-only remainder, so the docs branch of discovery
  silently breaking needs its own refusal. --json now reports docs_files.
- Fixes the four real dangles the new scan found in docs/reborn/contracts/
  (moved nested_dispatch_stream.rs test home, retired event-store migrations
  directory, loop_driver_host tests->src move). KNOWN_MISSING stays empty.
- Self-tests: 8 new cases (dangling docs path fails; Mintlify links are not
  references; MDX marker suppresses exactly one reference; multi-line MDX
  comment hides content; zh discovered; archives excluded but contracts
  scanned; docs fence fails closed; docs floor refuses).
- ws12_workflow_contracts.py: docs/api/responses.mdx and docs/zh/index.mdx
  join the has_guidance in-scope probes so a narrowed trigger regex cannot
  silently skip the gate for public docs.

Part of nearai#7317 (doc-truth pipeline, PR 2 of 5); stacked on nearai#7375.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): pin CLI, manifest, and Responses doc claims to code

Three deterministic doc-fact contract tests, each living in the crate that
owns the truth it checks, so the drift nearai#7317 describes fails CI instead of
shipping:

- crates/app/ironclaw_cli/tests/docs_cli_reference.rs: parses the real
  binary's --help and cross-checks docs/using/cli.mdx table rows both ways
  (every visible subcommand documented, any alias form counting; every
  documented command real), with a fail-closed row floor. Doc gaps this
  surfaced are fixed here: ironhub had no rows at all, completion was
  fence-only, and the Trace Commons table lacked the `ironclaw` prefix the
  rest of the page uses.
- crates/extensions/ironclaw_extension_registry/tests/
  docs_manifest_schema_version.rs: walks the published docs tree (the
  frozen .mintignore fence mirrored as constants) and asserts zero
  occurrences of the retired reborn.extension_manifest.v2 literal, fenced
  code included; asserts building-a-tool.md names
  MANIFEST_SCHEMA_VERSION_V3 verbatim and documents origin_gate_matrix.
- crates/product/ironclaw_openai_compat/tests/docs_responses_contract.rs:
  docs/api/responses.mdx now carries a machine-readable
  {/* doc-fact:responses-request-policy */} marker block (invisible when
  rendered); the test parses it and drives every claim through the same
  route-level seam as the sibling *_contract.rs suites — the marker's
  values parameterize the assertions (temperature accepted at the
  documented max and rejected just above it, model accepted at the byte
  cap and rejected past it, tool_choice always 400, tools 400 without /
  registered with external-tool wiring, empty tools treated as omitted,
  unknown fields like max_output_tokens accepted and ignored, and one
  request carrying every documented field accepted).

Part of nearai#7317 (doc-truth pipeline, PR 3 of 5); stacked on nearai#7376.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: address Copilot and CodeRabbit review on doc-drift PR

- responses.mdx: tool_choice is rejected only without external-tools wiring;
  with external tools enabled it passes validation and is currently ignored
  (validate_responses_supported_fields_with_external_tools never checks it).
- building-a-tool.md: clarify that effect-derived host ports are validation
  vocabulary against the HostPortCatalog allowlist; adapters are built by
  host-runtime services after authorization/obligations, never from manifests.
- how-to-port-tool-to-reborn.md: mark the decision tree's RuntimeKind targets
  historical (v3 accepts only wasm|first_party; MCP is top-level [mcp];
  process/CLI work is the sandbox lane).
- building-a-channel.mdx: document the user install flow — virtual package
  root /system/extensions/<id>/manifest.toml, ironclaw extension search /
  install <extension-id> (ID, not path), WebUI Extensions lifecycle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(responses): align the limits bullet with the corrected tool_choice claim

The rejection list was corrected in the previous commit (tool_choice is
rejected only without external-tools wiring); the "Limits and quirks"
bullet still said "not supported ... rejected with 400". Same claim, one
wording.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): tool_choice is conditionally rejected, not always

Copilot review on the docs PR caught that
validate_responses_supported_fields_with_external_tools never checks
tool_choice — with external tools wired it is accepted and ignored, not
400'd. The doc-fact marker moves tool_choice into
rejected_without_external_tools, and the dedicated test now proves both
sides: 400 naming the param on the plain router, accepted-and-ignored
(submit succeeds, nothing registers) with external-tool wiring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: apply verified code-review findings on the drift PR

A full code review of this PR against live code surfaced claims the
original drift pass got wrong or missed; every fix below was re-verified
against the cited source before editing:

- responses.mdx: standard `ironclaw serve` deployments always wire
  external tools (OpenAiCompatRouteMountPorts requires the store/resume
  pair; mount.rs wires them unconditionally), so `tools` is accepted and
  `tool_choice` is accepted-and-ignored on shipped binaries — the
  conditional 400s apply only to custom compositions without the wiring
  (now a Note). temperature is validated and carried in the submitted turn
  payload but not applied as a provider sampling parameter. Non-streaming
  wait timeout is 30 s (DEFAULT_RESPONSES_WAIT_TIMEOUT), not 120. usage on
  retrieval is read best-effort from persisted run state incl. USD cost
  (read_run_usage), not always zero.
- building-a-tool.md: the [auth.example] oauth2_code recipe gains the
  required token_response map (deny_unknown_fields rejects the example as
  previously written); Gmail/Google Calendar corrected to first_party
  runtimes (their manifests declare kind = "first_party"); the worked
  api_key recipe is github's, not slack's; the tail "Quick implementation
  checklist" and reference list were still v2-era (script lane,
  assets/<extension>/ path, "manifest v2", v2.rs pointer) and now teach
  the v3 shape; composition/CLI package-naming claim narrowed (the binary
  does link slack/telegram adapter crates).
- contracts/extensions.md: legacy-format paragraph no longer claims
  host-bundled packages ship v2 (none do), and origin_gate_matrix is
  attributed to capability.rs + building-a-tool.md instead of
  extension-runtime/overview.md §3, which does not mention it.
- how-to-port banner: `script` manifest authoring is retired; the
  RuntimeKind::Script symbol survives as the process-sandbox lane's kind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(contracts): repoint delivery_resolution.rs to its family directory

PR nearai#7157 (merged to main 2026-08-07) cited
crates/ironclaw_outbound/src/delivery_resolution.rs in the
communication-delivery-resolution contract; the crate lives at
crates/domains/ironclaw_outbound/. Caught by this branch's docs surface of
check-guidance.py on the first merge of main after the gate landed —
exactly the drift class it exists for.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(test-plan): route docs pages to the doc-fact tests that read them

docs/ sat in IGNORED_PREFIXES as a pure-prose class, which this PR's
doc-fact tests falsify: three cargo tests now read published pages, so
a docs-only PR would have selected zero crate tests and merged green,
leaving the failure to land on whichever unrelated change ran the full
plan next.

Published Markdown now selects the registry's schema-version sweep;
docs/using/cli.mdx and docs/api/responses.mdx additionally select
their owning crates. All selections are direct exact test targets —
no reverse-dependency widening, since prose only changes the doc-fact
assertions that read it. Fenced trees (docs/internal/, docs/reborn/,
drafts) and non-page files keep the prose classification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): harden the docs gate and fix review-surfaced doc drift

Applies the verified findings from the PR nearai#7376 code review:

- The loop-exit and turn-runner contract docs claimed the deleted
  loop_driver_host checkpoint-rejection test had 'moved into the
  module'; it was deleted in nearai#6696 and the fenced verification command
  could not run. Both now cite the real surviving pins
  (planned_driver.rs executor test + the ironclaw_turns projection
  test mapped in scripts/reborn-e2e-rust.sh), with runnable commands.
- An unterminated comment now refuses at EOF like an unterminated
  fence; before, one typo'd closer silently un-scanned the rest of the
  file.
- Markdown links in the re-included corpora are now checked as repo
  paths (they are never published, so the Mintlify-route rationale did
  not apply); this alone added ~165 verified references.
- Each DOCS_REINCLUDED_PREFIXES entry must match at least one tracked
  page or discovery refuses, so the planned docs/reborn consolidation
  cannot silently drop the corpus from the scan.
- The living extension-runtime spec pages (overview.md,
  standard-operations.md) and guidance-conventions.md join the scan;
  guidance-conventions.md now describes the docs surface and the MDX
  marker form, and its one dangling test path is repointed.
- Floors comment corrected (57 rule globs, not 38).

Also fixes four drifted claims from nearai#7375's pages, verified against
live code: the interleaved function_call_output example was rejected
with 400 (resume input must be exclusively function_call_output items
with previous_response_id); model is echoed only on create (GET/cancel
report the 'reborn' placeholder); output_schema_ref is optional; and
the unknown-fields claim now names the two deliberate exemptions.

Self-tests: 43 pass (three new arms — unterminated comment refusal in
both syntaxes, re-included links as repo claims, stale re-included
prefix refusal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci(check-guidance): sync module docstring with re-included link checking

CodeRabbit caught the docstring still claiming the link extractor is
off for all of docs/** — stale since b172f69 enabled it for the
re-included corpora. The docstring now states the exception and the
current re-include set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): drop the retired reborn/ entry from the publication-fence mirrors

reborn/ left docs/.mintignore when nearai#7559 consolidated it into internal/;
the fence mirrors in docs_manifest_schema_version.rs and
reborn_pr_test_plan.py still listed it. Fixture paths follow the move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): tighten doc-fact comments and docstrings

Same behavior; module docs and test docstrings trimmed to the point.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): harden the doc-fact suites per CodeRabbit review

- CLI: validate full documented command paths via `ironclaw <path> --help`
  (immediately caught and removed the nonexistent `extension activate` row)
  and match visible aliases as exact tokens, not substrings.
- Responses: seed a real prior response so `previous_response_id` is
  actually submitted and accepted; document `metadata` in the visible table
  to match the marker.
- Manifest sweep: parse the publication fence from docs/.mintignore instead
  of mirroring it, so a removed fence entry widens the scan with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(docs): correct the completion syntax and parse the fence in the planner

Review findings (sub-agent /code-review):
- docs/using/cli.mdx taught `ironclaw completion <shell>`; the binary only
  accepts `--shell <shell>`. The contract test stops extracting at flags,
  so it could not catch this.
- The planner's doc-fact arm mirrored the .mintignore fence as constants —
  the same hand-maintained-mirror class the PR removes elsewhere. It now
  parses docs/.mintignore via docs_publication_boundary, and a .mintignore
  edit itself routes to the published sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(test-plan): treat a missing docs/.mintignore as no fence, not a crash

Matches docs_publication_boundary.find_violations(): fence gone means
everything is published, so every page routes to the sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): replace the doc-fact count floors with derived anchors

Same move as nearai#7376's MIN_DOCS_FILES removal: MIN_DOC_COMMAND_ROWS was
redundant with the completeness check (the binary defines the expected
set), and MIN_SCANNED_PAGES is now a docs.json nav-coverage assertion —
every source-backed navigation route must be among the walked pages.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(docs): assert the current schema version instead of scanning for a retired literal

Hardcoding `reborn.extension_manifest.v2` was backward-looking: retiring
v3 would need a hand-edit or the test goes stale. The scan now extracts
every `reborn.extension_manifest.<version>` mention in published pages
and asserts it equals `MANIFEST_SCHEMA_VERSION_V3`, with the family
prefix derived from the same constant — the next schema bump retargets
the test by itself, and typo'd or older versions (v1, v33) are caught
too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: experienced 6-19 merged PRs risk: low Changes to docs, tests, or low-risk modules scope: docs Documentation size: M 50-199 changed lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants