Repository navigation
docs: upgrade documentation for IronClaw V1 - #6970
Conversation
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe pull request updates IronClaw documentation for IronHub, skill activation, channel and tool extensions, Agent Hub, local installation, and quickstart workflows. It adds IronHub navigation pages and ignores a local ChangesIronClaw documentation
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
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. Comment |
🔎 Review · PR #6970
Execution result is invalid The structured result could not be verified. Automatic · PR opened · attempt 1 of 3 · failed after 2m 17s Failure details
|
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/channels/building-a-channel.mdx (1)
213-296: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winUse the manifest
[[channel.egress]]credential model instead of placeholders.
docs/channels/building-a-channel.mdxnow describes two different secret-resolution paths: URL/header string placeholders ({TELEGRAM_BOT_TOKEN}/{WHATSAPP_ACCESS_TOKEN}) and the manifestcredential_handle+injectionmechanism. The manifests and docs elsewhere use the manifest-driven model, not placeholder string substitution, so Section 5 and the troubleshooting placeholder checks leave channel code with a broken, unimplemented contract.Update Section 5 to show
[[channel.egress]]+ acredential_handlesuch asmy_channel_api_tokenand the matchinginjection = { type = "header", name = "authorization", prefix = "Bearer " }, then remove the unsupported{SECRET_NAME}replacement wording from Section 6/5 and the troubleshooting hints.🤖 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/channels/building-a-channel.mdx` around lines 213 - 296, Update Section 5 to document manifest-driven egress credentials using [[channel.egress]], credential_handle, and matching header injection instead of URL/header placeholders. Remove the unsupported {SECRET_NAME} substitution examples and wording from Sections 5–6, including troubleshooting guidance, while retaining the manifest credential configuration as the single documented secret-resolution contract.
🤖 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 @.gitignore:
- Around line 112-114: Remove the root-level /app/ entry and its accompanying
comment from .gitignore, keeping this documentation-only change scoped to the
documentation site; defer the unrelated local TypeScript application ignore rule
to a separate change.
In `@docs/capabilities/skills.mdx`:
- Around line 29-44: Update the Skills “Gate” and warning text to describe
automatic criteria selection accurately: skills with auto_activate = false are
excluded before scoring, while eligible skills continue through scoring. Revise
the warning near the activation guidance to state only that skills without an
activation block cannot be selected automatically by criteria; preserve that
explicit $name and /name mentions can still activate them.
- Line 9: Update the documentation validation workflow for changes under
docs/**/* to include the required mint broken-links check executed from the docs
directory, alongside the existing mint dev and mint validate checks, before
merge.
In `@docs/channels/building-a-channel.mdx`:
- Around line 28-38: Update the first project layout’s built artifact entry to
use wasm/my_channel.wasm, matching Cargo’s library artifact naming and the later
manifest and build-output references, while keeping the crate and project name
as my-channel.
In `@docs/hub/overview.mdx`:
- Line 26: Update the Extension (Tool) entry in the overview table to specify a
WASM binary plus a TOML capability manifest, using manifest.toml rather than
JSON. Ensure the documentation reflects the v3 runtime discovery contract at
/system/extensions/<extension-id>/manifest.toml.
In `@docs/quickstart.mdx`:
- Around line 48-52: Update the SSH command in the quickstart code block to use
placeholders for the dashboard-provided username and host, while retaining the
existing port placeholder and `ironclaw chat` command.
---
Outside diff comments:
In `@docs/channels/building-a-channel.mdx`:
- Around line 213-296: Update Section 5 to document manifest-driven egress
credentials using [[channel.egress]], credential_handle, and matching header
injection instead of URL/header placeholders. Remove the unsupported
{SECRET_NAME} substitution examples and wording from Sections 5–6, including
troubleshooting guidance, while retaining the manifest credential configuration
as the single documented secret-resolution contract.
🪄 Autofix (Beta)
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: cd38df75-be4d-4e98-a8fd-917b7b1b175a
⛔ Files ignored due to path filters (2)
docs/zh/capabilities/skills.mdxis excluded by!docs/zh/**docs/zh/index.mdxis excluded by!docs/zh/**
📒 Files selected for processing (10)
.gitignoredocs/capabilities/skills.mdxdocs/channels/building-a-channel.mdxdocs/docs.jsondocs/extensions/building-a-tool.mddocs/hub/contributing.mdxdocs/hub/installing.mdxdocs/hub/overview.mdxdocs/index.mdxdocs/quickstart.mdx
|
|
||
| # for a local typescript app, but don't want to push with main repo | ||
| /app/ |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Remove the unrelated /app/ ignore rule or split it into a separate change.
This PR is scoped to documentation. The new root-level ignore rule changes repository hygiene for a local TypeScript application and is unrelated to the documentation upgrade.
As per coding guidelines, keep pull requests focused and avoid mixing unrelated concerns. The PR objectives state that the changes affect the documentation site only.
🤖 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 @.gitignore around lines 112 - 114, Remove the root-level /app/ entry and its
accompanying comment from .gitignore, keeping this documentation-only change
scoped to the documentation site; defer the unrelated local TypeScript
application ignore rule to a separate change.
Source: Coding guidelines
| Create a new crate with this layout: | ||
|
|
||
| ```text | ||
| my-channel/ | ||
| ├── Cargo.toml | ||
| ├── src/ | ||
| │ └── lib.rs | ||
| └── my-channel.capabilities.json | ||
| ``` | ||
|
|
||
| After building, deploy to: | ||
|
|
||
| ```text | ||
| ~/.ironclaw/channels/ | ||
| ├── my-channel.wasm | ||
| └── my-channel.capabilities.json | ||
| ├── wasm/ | ||
| │ └── my-channel.wasm # built artifact | ||
| └── manifest.toml | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate the target file and inspect the relevant sections without executing repo code.
if [ -f docs/channels/building-a-channel.mdx ]; then
echo "== file exists =="
wc -l docs/channels/building-a-channel.mdx
echo "== relevant line ranges =="
sed -n '20,45p' docs/channels/building-a-channel.mdx
echo "== later relevant occurrences =="
sed -n '240,260p' docs/channels/building-a-channel.mdx
sed -n '295,322p' docs/channels/building-a-channel.mdx
echo "== all wasm artifact mentions =="
rg -n 'my_?-channel\.wasm|my-channel|my_channel\.wasm|build.*\\.wasm|module' docs/channels/building-a-channel.mdx
else
echo "missing docs/channels/building-a-channel.mdx"
git ls-files | rg '(^|/)docs/channels/(building-a-channel\.mdx|.*\.mdx)$|Cargo\.toml|^\.claude/rules|CLAUDE\.md|AGENTS\.md' || true
fiRepository: nearai/ironclaw
Length of output: 3011
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import subprocess, sys
res = subprocess.run(["rustup", "run", "nightly", "cargo", "+nightly", "search"],
stdin=subprocess.DEVNULL, stderr=subprocess.PIPE, timeout=5)
print("rustup_cargo_available=", res.returncode == 0)
PY
tmp="$(mktemp -d)"
cd "$tmp"
cargo init --name my-channel --lib >/dev/null 2>&1
echo "== generated Cargo.toml =="
cat Cargo.toml
echo "== build output file names =="
cargo build --release --target wasm32-wasip2 >/dev/null 2>&1 || true
find target -name '*.wasm' -o -name '*.rmeta' 2>/dev/null | sed 's#^`#-` #' || true
PYRepository: nearai/ironclaw
Length of output: 145
🌐 Web query:
Cargo compiled library output name replaces hyphens with underscores cdylib
💡 Result:
In Cargo, library targets (including those with crate-type = "cdylib") automatically normalize their names by replacing hyphens with underscores [1]. This normalization occurs because the target name is used to derive the internal crate name, which is then used as the stem for the generated artifact file [1][2]. When you define a library in Cargo, it defaults to the name of the package [1]. If your package name contains hyphens (e.g., my-library), Cargo transforms this into an underscore-separated identifier (e.g., my_library) when determining the crate name and the resulting output filename (e.g., libmy_library.so, my_library.dll, or my_library.dylib) [1][3][2]. Key points regarding this behavior: - Normalization: Cargo applies this hyphen-to-underscore replacement to ensure valid identifier names, as crate names cannot contain hyphens [1][2]. - Metadata: While Cargo's configuration (Cargo.toml) may allow names with hyphens in certain contexts, the actual artifact generated on disk is consistently underscored [2]. External tools or scripts that expect the artifact to match the package name exactly may fail if they do not account for this automatic transformation [3]. - Workarounds: Because Cargo does not currently provide a native way to override the filename stem directly while keeping the hyphen, the common workaround for tools or build pipelines that require a specific filename is to use a post-build script to rename the resulting library file [4]. If you are developing a tool that consumes these artifacts (such as a WebAssembly or FFI-based deployment tool), you should be prepared to look for the underscored version of your library name [3].
Citations:
- 1: https://doc.rust-lang.org/cargo/reference/cargo-targets.html?highlight=cdylib
- 2: cargo: fix inconsistent dashes in lib.name rust-lang/cargo#12640
- 3: cargo-stylus fails to find WASM file when package name contains hyphens (cdylib TargetKind check bug) OffchainLabs/stylus-sdk-rs#439
- 4: Allow configuring name of generated shared library artifact rust-lang/cargo#1970
Fix the first project-layout artifact filename.
The crate is named my-channel, but Cargo library artifact stems use my_channel; later sections use my_channel.wasm for the manifest module, second layout, and build output. Update the first layout to wasm/my_channel.wasm and keep the project names as my-channel.
🤖 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/channels/building-a-channel.mdx` around lines 28 - 38, Update the first
project layout’s built artifact entry to use wasm/my_channel.wasm, matching
Cargo’s library artifact naming and the later manifest and build-output
references, while keeping the crate and project name as my-channel.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/capabilities/skills.mdx (1)
94-100: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy liftApply trust attenuation before budgeting.
As written, installed IronHub skills can consume the token budget at Line 95 and then be excluded at Line 99. This can drop eligible trusted skills from the same turn. Filter attenuated skills before budgeting, or state that they never enter the budget candidate set.
#!/bin/bash set -euo pipefail rg -n -C 8 \ 'auto_activate|skill_activate|token.?budget|budget|attenuat|trusted|IronHub|installed' \ --glob '*.rs' --glob '*.md' --glob '*.mdx' . rg -n -C 8 \ 'installed.*skill|IronHub|attenuat|budget|skill_activate' \ --glob '*test*' --glob '*.rs' .🤖 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/capabilities/skills.mdx` around lines 94 - 100, Update the Skills selection documentation so trust attenuation occurs before token budgeting: exclude installed IronHub skills from the budget candidate set, then sort and select only eligible skills. Revise the “Budget” and “Attenuate” steps to reflect this ordering and preserve activation access for skills in trusted directories.docs/quickstart.mdx (1)
113-123: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winAlign the IronClaw home path with the runtime default.
docs/quickstart.mdxdocuments~/.ironclaw, butdocs/capabilities/configuration.mdxstill documents~/.ironclaw/rebornandIRONCLAW_REBORN_HOME. Use the same path/document the migration because users can search forconfig.tomlandwebui-tokenin the wrong directory.🤖 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/quickstart.mdx` around lines 113 - 123, Update the quickstart storage-location documentation and related configuration references to use the runtime’s current IronClaw home path consistently, replacing legacy ~/.ironclaw/reborn and IRONCLAW_REBORN_HOME references where applicable. Document the migration from the legacy path so users can locate config.toml and webui-token correctly, while preserving the existing file descriptions.
🤖 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.
Outside diff comments:
In `@docs/capabilities/skills.mdx`:
- Around line 94-100: Update the Skills selection documentation so trust
attenuation occurs before token budgeting: exclude installed IronHub skills from
the budget candidate set, then sort and select only eligible skills. Revise the
“Budget” and “Attenuate” steps to reflect this ordering and preserve activation
access for skills in trusted directories.
In `@docs/quickstart.mdx`:
- Around line 113-123: Update the quickstart storage-location documentation and
related configuration references to use the runtime’s current IronClaw home path
consistently, replacing legacy ~/.ironclaw/reborn and IRONCLAW_REBORN_HOME
references where applicable. Document the migration from the legacy path so
users can locate config.toml and webui-token correctly, while preserving the
existing file descriptions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 32b24fda-283c-4142-b6c4-353f90fa60c6
📒 Files selected for processing (3)
docs/capabilities/skills.mdxdocs/hub/overview.mdxdocs/quickstart.mdx
thisisjoshford
left a comment
There was a problem hiding this comment.
Heads up: this PR is diffed against main, not the v1 release
The title and framing say "for IronClaw V1", but the branch is based on main (merge-base 31f42b790), and main is not where v1 was cut from. ironclaw-v1.0.0 (e3a075222) came off release-fix-1.0.0-rc.1, which branched on 2026-07-20 — main carries 271 commits that are not in the v1 tag.
That matters because several changes here document code that landed after the release. Counts below are git grep against the tag, restricted to code (*.rs / *.toml) so docs and comments can't inflate them:
| Documented here | Files at ironclaw-v1.0.0 |
On main |
|---|---|---|
ironclaw ironhub … (all of docs/hub/) |
0 | 51 |
reborn.extension_manifest.v3, [[tools]] |
0 | 20 |
[channel] manifest section (any .toml) |
0 | 3 |
crates/ironclaw_extension_host/ |
crate absent — lives at ironclaw_reborn_composition/src/extension_host/ |
present |
crates/ironclaw_product/src/adapter_registry.rs |
absent — three ironclaw_product_adapter* crates instead |
present |
So a reader who installs v1.0.0 from the releases page and runs ironclaw ironhub search github gets an unknown-subcommand error. Worth deciding explicitly whether docs.ironclaw.com tracks the released binary or main — I don't think that call has been made anywhere, and this PR quietly picks "main."
Everything below reviews the PR as-is against main, since that's the actual base.
Blocking
1. The flagship v3 manifest example does not parse — docs/extensions/building-a-tool.md
I ran the example through the real entry point (ExtensionManifestRecord::from_toml, the single dispatch point for v2/v3) rather than reading the validator. Verbatim output:
TOOL EXAMPLE: REJECTED -> invalid extension manifest: credential vendor `example`
has no [auth.example] recipe; v3 manifests must declare one for every
referenced vendor
CHANNEL EXAMPLE: PARSED OK
v3 requires an [auth.<vendor>] recipe for every vendor a credential references — the real Slack manifest carries [auth.slack] at crates/extensions/packages/slack/manifest.toml:277 for exactly this reason. The converse is enforced too (UnreferencedAuthRecipe), so you can't paper over it with a stray recipe.
Adding a minimal recipe makes it parse — confirmed, same harness:
[auth.example]
method = "api_key"
display_name = "Example account"
fields = [{ handle = "example_runtime_token", label = "API token", secret = true }]FIXED TOOL EXAMPLE: PARSED OK
Since this is the primary tool-authoring guide, the example needs that block (or an oauth2_code equivalent) or it sends every reader into a rejected manifest.
2. docs/hub/installing.mdx contradicts docs/capabilities/skills.mdx in this same PR
skills.mdx correctly replaces the old tool-ceiling story with activation-based trust. I traced that to confirm it, rather than trusting the doc comments:
builtin.skill_activate → skill_activation_capability.rs:81 → activate_skills_for_run → select_named_skill_activations → .filter(|c| c.loaded.trust == SkillTrust::Trusted) (activation.rs:1394).
The message-driven path (select_skill_activations) has no trust filter, so explicit $name mentions and keyword selection do still reach Installed skills. Both halves of the rewrite are right.
But the new installing.mdx reintroduces the claim that was just removed:
Packages installed from IronHub are attenuated — they have reduced tool access
| IronHub install | Installed | Read-only — no shell, no file write, no HTTP |
No such mechanism exists on main. I checked what skill trust actually governs rather than grepping for the word "attenuation": every non-test consumer of SkillTrust/SkillTrustLevel, whose contract is stated at crates/ironclaw_loop_contracts/src/skill_context.rs:112-119 — Installed = description only, no prompt content; Trusted = description plus prompt body once loaded. Trust gates how much content the model receives and skill_activate eligibility. It does not gate tool access. This table should match the one in skills.mdx.
3. ~/.ironclaw/reborn → ~/.ironclaw is a regression — docs/quickstart.mdx
Two places changed ("Everything lives under…" and cat ~/.ironclaw/webui-token). With no IRONCLAW_REBORN_HOME set, home.rs resolves to $HOME/.ironclaw/reborn, and that file is byte-identical on v1 and main — so this is wrong regardless of base.
It's stronger than a typo: validate_not_v1_state_root (home.rs:182-209) treats $HOME/.ironclaw as the v1 state root and returns RebornConfigError::V1StateRoot if the Reborn home overlaps it. The docs would be pointing readers at a path the code explicitly refuses.
(The skills paths are a different root and are correct as written — ~/.ironclaw/skills/ and ~/.ironclaw/installed_skills/ genuinely have no reborn segment.)
Should fix
--acknowledge-unverified is never documented. installing.mdx describes the gate ("Community entries (provenance New) require explicit acknowledgement") but never names the flag that satisfies it. The gate is catalog.rs:121 — if provenance.is_community_unverified() && !options.acknowledge_unverified — and the flag is declared at ironhub.rs:75. As written, a reader hits a wall with no way through.
Provenance table is missing Private. IronHubProvenance (ironhub/model.rs:41-50) has five variants: Official, Trusted, Verified, Private, New. hub/overview.mdx lists four. Private and its --private-manifest-url-file flag arrived with the org-scoped manifest work (#6780); both are undocumented.
output_schema_ref / prompt_doc_ref are optional in v3. building-a-tool.md lists both under "Required per model-visible tool capability in v3", but RawToolV3 (v3.rs:151-155) has input_schema_ref: String required and both of those as #[serde(default)] Option<String>. If they're required by project convention rather than by the parser, worth saying so, since the surrounding list otherwise describes parser-enforced rules.
Verified correct — no change needed
Checked against code rather than waved through:
- Channel manifest example — parses clean (
CHANNEL EXAMPLE: PARSED OK, same harness as above).kind = "shared_secret_header"withsecret_handle+headermatchesSharedSecretHeaderRecipe(recipe.rs:705-708), and the[[channel.egress]]keys matchChannelEgressDescriptor. Both structs aredeny_unknown_fields, so getting this right mattered. - Crate path rewrites —
ironclaw_extension_host/src/{available_extensions,mcp}.rsandironclaw_product/src/adapter_registry.rsall exist on main. Note the pre-PR text was wrong too (ironclaw_reborn_composition/src/available_extensions.rs, missing theextension_host/segment), so this is a genuine fix, not churn. - v3 field names —
handle,vendor,scopes,audience,injection,effects,default_permission,visibilityall matchRawToolV3/RawToolCredentialV3. channel_host::http_request(…, None)— the 5th arg is real;wit/channel.wit:98-104declarestimeout-ms: option<u32>.auto_activate,setup_marker,requires.bins/.env,regex_activation_enabled— all real.
One correction to a criticism I'd have made: dropping SKILLS_MAX_TOKENS / SKILLS_AUTO_DISCOVER / SKILLS_REGEX_ACTIVATION_ENABLED is right, but these weren't invented. At the v1 tag they were read by src/config/skills.rs — the legacy ironclaw-legacy binary, which is a separate target from the shipped Reborn ironclaw. On main, zero .rs files reference them and they're gone from .env.example. So they were accurate documentation that went stale when Reborn became the product, and removing them is correct for both bases.
Housekeeping
- The PR is currently
CONFLICTINGwith main and needs a rebase. .gitignoreadds/app/with the comment "for a local typescript app, but don't want to push with main repo" — that reads like a personal working-directory entry rather than something the shared repo needs. Probably belongs in.git/info/exclude.- The three new
hub/pages have nozh/translations; the PR body already flags this as deferred, which seems fine.
Manifest claims were verified by parsing the doc examples verbatim through ExtensionManifestRecord::from_toml in a scratch test against this branch's main; the test was removed afterward. Version claims are git grep against ironclaw-v1.0.0 restricted to *.rs/*.toml.
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (1)
docs/channels/building-a-channel.mdx (1)
28-38: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winArtifact filename still mismatched.
Line 36 says
my-channel.wasm. Cargo emitsmy_channel.wasmfor amy-channelcrate, and lines 254, 303, 318-320 all usemy_channel.wasm. Fix the first layout.📝 Proposed fix
├── wasm/ -│ └── my-channel.wasm # built artifact +│ └── my_channel.wasm # built artifact └── manifest.toml🤖 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/channels/building-a-channel.mdx` around lines 28 - 38, Update the initial crate layout’s wasm artifact entry to use my_channel.wasm, matching Cargo’s emitted filename and the references elsewhere in the documentation.
🤖 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`:
- Around line 220-223: Update the Rust examples using
channel_host::http_request, including the examples around the Telegram request
and the other referenced call sites, to annotate the fifth None argument as the
optional HTTP client timeout in milliseconds. Keep the argument value and
request behavior unchanged while adding a concise explanatory comment or named
placeholder.
- Line 323: Update the extension installation guidance to remove or replace the
stale `crates/ironclaw_first_party_extensions/assets/<channel>/` path with the
documented host-bundled asset path, retain registration in
`crates/ironclaw_extension_host/src/available_extensions.rs`, and change the
local development location to
`$IRONCLAW_REBORN_HOME/local-dev/system/extensions/<channel>/`.
- Around line 313-321: Replace the manual wasm-tools conversion and
error-swallowing fallback in the channel build instructions with the
repository-standard cargo component build flow: use cargo component build in
release mode targeting wasm32-wasip2, then copy the generated component to the
documented wasm output using a manifest-relative path. Keep the resulting
command sequence current and actionable.
In `@docs/extensions/building-a-tool.md`:
- Around line 193-220: Add a minimal matching [auth.example] recipe to the v3
manifest example, positioned in the manifest’s authentication section after the
credential declaration or at the documented auth location. Ensure it corresponds
to the existing credentials handle and satisfies the guide’s required
authentication contract.
- Line 524: Align the hosted HTTP MCP credential guidance in the section
beginning “For host-bundled hosted HTTP MCP, composition:” with the documented
version: either mark the section as v2-only to match its runtime_credentials
projection, or update the example to use v3 inline credentials instead of
[[tools.credentials]].
- Around line 17-18: Update the extension package paths throughout the building
guide, including the references around the composition section and the locations
identified in the comment, to use the canonical
crates/extensions/packages/<extension>/ root. Replace old
crates/ironclaw_first_party_extensions/assets/<id>/ references consistently with
the existing github and notion-mcp package layout, while preserving the
surrounding authentication and OAuth wiring instructions.
---
Duplicate comments:
In `@docs/channels/building-a-channel.mdx`:
- Around line 28-38: Update the initial crate layout’s wasm artifact entry to
use my_channel.wasm, matching Cargo’s emitted filename and the references
elsewhere in the documentation.
🪄 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: fef43533-ea32-4885-b33d-1cfe9c7a011d
⛔ Files ignored due to path filters (2)
docs/zh/capabilities/skills.mdxis excluded by!docs/zh/**docs/zh/index.mdxis excluded by!docs/zh/**
📒 Files selected for processing (10)
.gitignoredocs/capabilities/skills.mdxdocs/channels/building-a-channel.mdxdocs/docs.jsondocs/extensions/building-a-tool.mddocs/hub/contributing.mdxdocs/hub/installing.mdxdocs/hub/overview.mdxdocs/index.mdxdocs/quickstart.mdx
| ```rust | ||
| // The host replaces {TELEGRAM_BOT_TOKEN} with the actual token | ||
| let url = "https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"; | ||
| channel_host::http_request("POST", url, &headers_json, Some(&body)); | ||
| channel_host::http_request("POST", url, &headers_json, Some(&body), None); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd 'channel.wit' | xargs -r -I{} sh -c 'echo "== {} =="; cat -n {}'
rg -n -C3 'fn http_request' --type=rust | head -60Repository: nearai/ironclaw
Length of output: 20642
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== docs/channels/building-a-channel.mdx relevant lines =="
sed -n '214,236p' docs/channels/building-a-channel.mdx | cat -n
sed -n '334,346p' docs/channels/building-a-channel.mdx | cat -n
echo
echo "== current document calls to channel_host::http_request =="
rg -n -C2 'channel_host::http_request|http_request\(' docs/channels/building-a-channel.mdxRepository: nearai/ironclaw
Length of output: 2671
Name the fifth http_request argument in the examples.
crates/ironclaw_wasm/wit/channel.wit defines http_request(..., timeout-ms: option<u32>), but the examples at lines 223, 233, and 341 only show a bare None. Add a short comment or named placeholder noting that the value controls the HTTP client timeout in milliseconds.
🤖 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/channels/building-a-channel.mdx` around lines 220 - 223, Update the Rust
examples using channel_host::http_request, including the examples around the
Telegram request and the other referenced call sites, to annotate the fifth None
argument as the optional HTTP client timeout in milliseconds. Keep the argument
value and request behavior unchanged while adding a concise explanatory comment
or named placeholder.
| ```bash | ||
| cd my-channel | ||
| cargo build --release --target wasm32-wasip2 | ||
|
|
||
| # Convert the raw wasm module into a component and strip it | ||
| wasm-tools component new target/wasm32-wasip2/release/my_channel.wasm -o my-channel.wasm \ | ||
| 2>/dev/null || cp target/wasm32-wasip2/release/my_channel.wasm my-channel.wasm | ||
| wasm-tools strip my-channel.wasm -o my-channel.wasm | ||
|
|
||
| mkdir -p ~/.ironclaw/channels | ||
| cp my-channel.wasm ~/.ironclaw/channels/my-channel.wasm | ||
| cp my-channel.capabilities.json ~/.ironclaw/channels/ | ||
| ``` | ||
|
|
||
| <Note> | ||
| Current first-party channels are shipped as packaged artifacts. For repository-maintained Reborn channels, use `crates/extensions/packages/<channel>/manifest.toml` plus checked-in schemas/prompts and CI-built WASM artifacts rather than adding a new legacy source tree. | ||
| </Note> | ||
|
|
||
| ### Packaged channel artifact example | ||
|
|
||
| ```bash | ||
| mkdir -p ~/.ironclaw/channels | ||
| cp my-channel.wasm my-channel.capabilities.json ~/.ironclaw/channels/ | ||
| wasm-tools component new target/wasm32-wasip2/release/my_channel.wasm -o wasm/my_channel.wasm \ | ||
| 2>/dev/null || cp target/wasm32-wasip2/release/my_channel.wasm wasm/my_channel.wasm | ||
| wasm-tools strip wasm/my_channel.wasm -o wasm/my_channel.wasm | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# How do first-party channel/extension packages actually build their wasm artifacts?
fd -t f -i 'build*.sh' -x echo {}
rg -n --iglob '!docs/**' -C4 'wasm-tools (component new|strip)|wasm32-wasip2' | head -100Repository: nearai/ironclaw
Length of output: 235
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== relevant doc section =="
sed -n '290,330p' docs/channels/building-a-channel.mdx || true
echo
echo "== files with wasm/strip/component references =="
rg -n --iglob '!docs/**' -C3 'wasm-tools\s+(component new|strip)|wasm32-wasip2|wasm/my_channel|target/wasm32-wasip2|\.component\.(wasm|wasmf|bytes)?' .
echo
echo "== repo top-level files likely containing channel packages =="
git ls-files | rg '(^|/)(package|packages|channel|channels|ext|extension|crates?|wasm|wit|component)' | head -200Repository: nearai/ironclaw
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== build-wasm-extensions shim/implementation =="
sed -n '1,110p' scripts/build-wasm-extensions.sh || true
sed -n '200,245p' scripts/build-wasm-extensions.sh || true
echo
echo "== tool-related build scripts =="
sed -n '1,95p' scripts/build-test-tools.sh || true
echo
echo "== candidate first-party channel build references (strict) =="
rg -n --iglob 'scripts/**/*.sh' --iglob 'build-wasm*.sh' --iglob 'channel*/*.{sh,bash,rs,md,mdx}' --iglob '!test-tools/**' \
-C2 '^((bash|sh|zsh|tcsh|rc)\s+#?--[[:space:]]*)?$|wasm-tools|cargo.*build.*wasm32-wasip2|cargo.*component.*|target\.strip|strip' \
|| true
echo
echo "== changed lines context =="
sed -n '305,324p' docs/channels/building-a-channel.mdx || trueRepository: nearai/ironclaw
Length of output: 9585
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== exact matching build-wasm-extensions references =="
rg -n --iglob 'scripts/build-wasm-extensions.sh' --iglob 'scripts/**.sh' --iglob '!test-tools/scripts/**' \
-C2 'wasm-tools (component new|strip)|cargo_component_build|target\.strip|strip wasm/my_channel|wasm/my_channel\.wasm' . || true
echo
echo "== precise occurrences in build scripts under scripts (except test-tools) =="
rg -n --iglob 'scripts/**' -C2 'wasm-tools|cargo component build|cargo build --release --target wasm32-wasip2|strip \|' . || true
echo
echo "== docs section =="
sed -n '308,322p' docs/channels/building-a-channel.mdx || trueRepository: nearai/ironclaw
Length of output: 4833
🌐 Web query:
wasm-tools strip same input output file behavior
💡 Result:
The behavior regarding input and output files differs between wasm-tools strip (part of the Bytecode Alliance wasm-tools suite) and wasm-strip (part of the WebAssembly Binary Toolkit, WABT) [1][2][3]. For wasm-tools strip: - It follows the standard pattern of the wasm-tools CLI suite [1][4]. - If no output is specified via the -o or --output flag, the tool defaults to sending the output to stdout [1][4]. - It does not automatically modify the input file in place if you provide it as an argument; instead, you must explicitly redirect the output to a file (e.g., wasm-tools strip input.wasm -o input.wasm or using shell redirection) [1][4]. For wasm-strip (WABT): - By default, it modifies the input file in place if no output file is specified [3]. - You can use the -o or --output flag to specify a different output file, which will prevent the original file from being overwritten [2][3]. To avoid confusion, verify which tool you are invoking, as they are separate projects with different CLI conventions [4][5][3]. Top results: [1] https://github.com/bytecodealliance/wasm-tools/blob/main/README.md [2] https://webassembly.github.io/wabt/doc/wasm-strip.1.html [3] https://linuxcommandlibrary.com/man/wasm-strip
Citations:
- 1: https://github.com/bytecodealliance/wasm-tools/blob/main/README.md
- 2: https://webassembly.github.io/wabt/doc/wasm-strip.1.html
- 3: https://linuxcommandlibrary.com/man/wasm-strip
- 4: https://docs.rs/crate/wasm-tools/1.251.0
- 5: https://github.com/WebAssembly/wabt/blob/master/src/tools/wasm-strip.cc
🌐 Web query:
wasm-tools component new input output same file default behavior
💡 Result:
When using the wasm-tools component new command, it is recommended and standard practice to specify an output file using the -o or --output option [1][2][3]. The command does not have a defined default behavior that automatically overwrites the input file if no output is provided [1][3]. In many CLI environments, running the command without the -o flag may either result in an error or output the generated binary to standard output (stdout), depending on the specific shell and environment configuration, but it is not designed to safely perform an in-place transformation by overwriting the source input file [1]. To convert a core WebAssembly module into a component, the explicit usage pattern is: wasm-tools component new input.wasm -o output.component.wasm Attempting to use the same file for both input and output (e.g., wasm-tools component new input.wasm -o input.wasm) is generally discouraged as it can lead to file corruption or truncated files because the tool attempts to read and write to the same path simultaneously. Always use distinct paths for input and output.
Citations:
- 1: https://github.com/bytecodealliance/wasm-tools/blob/main/src/bin/wasm-tools/component.rs
- 2: https://docs.rs/crate/wit-component/^0.235
- 3: https://github.com/bytecodealliance/wasm-tools/
Avoid the unsafe build snippet in docs/channels/building-a-channel.mdx:318-321.
This violates the channel docs invariant that build instructions must be current and actionable; the repo already uses cargo component build with wasm32-wasip2, not manual wasm-tools component new + strip. If this step is kept, use a separate strip output path and do not swallow the component build error, or replace it with cargo component build --release --target wasm32-wasip2 plus a manifest-relative copy.
🤖 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/channels/building-a-channel.mdx` around lines 313 - 321, Replace the
manual wasm-tools conversion and error-swallowing fallback in the channel build
instructions with the repository-standard cargo component build flow: use cargo
component build in release mode targeting wasm32-wasip2, then copy the generated
component to the documented wasm output using a manifest-relative path. Keep the
resulting command sequence current and actionable.
| <Danger> | ||
| If you are contributing a channel to the public repository, **do not commit compiled WASM binaries.** They are a supply chain risk — the binary in a PR may not match the source. IronClaw builds channels from source. | ||
| </Danger> | ||
| The extension is installed through the IronClaw extension lifecycle. For host-bundled channels, add the manifest and WASM to `crates/ironclaw_first_party_extensions/assets/<channel>/` and register it in `crates/ironclaw_extension_host/src/available_extensions.rs`. For local development, place the extension directory under `<reborn-home>/local-dev/system/extensions/<channel>/`. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -t d 'ironclaw_first_party_extensions|ironclaw_extension_host' crates -d 2 || true
fd 'available_extensions.rs' crates || true
fd -t d 'assets' crates -d 3 || true
rg -n --iglob '!docs/**' 'local-dev/system/extensions|system/extensions' | head -40Repository: nearai/ironclaw
Length of output: 244
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "repo files around documents and crates:"
git ls-files | rg '(^docs/channels/building-a-channel\.mdx$|^crates/(ironclaw_first_party_extensions|ironclaw_extension_host)|CLAUDE\.md$|^\.claude/)' | sed -n '1,120p'
echo
echo "manifest.toml / local-dev references excluding docs:"
rg -n --iglob '!docs/**' 'manifest\.toml|/system/extensions|local-dev/system/extensions|reborn-home' . | sed -n '1,160p'
echo
echo "IronClaw directory listing:"
find crates -maxdepth 4 \( -path '*/ironclaw_first_party_extensions/*' -o -path '*/ironclaw_extension_host/*' \) -print | sort | sed -n '1,220p'Repository: nearai/ironclaw
Length of output: 31201
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import subprocess, pathlib, re
files = subprocess.check_output(['git','ls-files'], text=True).splitlines()
patterns = [
r'crates/ironclaw_first_party_extensions/assets/.*',
r'crates/ironclaw_extension_host/src/available_extensions\.rs|crates/ironclaw_first_party_extensions/assets/.*/manifest\.toml',
r'\.claude/|CLAUDE\.md$|AGENTS\.md$',
]
for pat in patterns:
m = re.compile(pat)
hits = [p for p in files if m.search(p)]
print(f"\nPattern {pat}: {len(hits)}")
for h in hits[:50]:
print(h)
if not hits:
print("NONE")
PYRepository: nearai/ironclaw
Length of output: 2365
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import subprocess, pathlib, re
files = subprocess.check_output(['git','ls-files'], text=True).splitlines()
patterns = {
'available_extensions': r'crates/ironclaw_extension_host/src/available_extensions\.rs',
'first_party_assets_dir': r'crates/ironclaw_first_party_extensions/assets/(?:[^/]+/){1,2}manifest\.toml|crates/ironclaw_first_party_extensions/assets/',
'local_dev_home_prefix': r'\$IRONCLAW_REBORN_HOME/local-dev/system/extensions|IRONCLAW_REBORN_HOME.*local-dev/system/extensions|<reborn-home>/local-dev/system/extensions',
'homeless_local_dev_prefix': r'\$IRONCLAW_REBORN_HOME/system/extensions|IRONCLAW_REBORN_HOME.*system/extensions',
'system_extensions_manifest': r'/system/extensions/.*/manifest\.toml|/system/\w+/.*manifest\.toml',
}
for name, pat in patterns.items():
rx = re.compile(pat)
hits = [p for p in files if rx.search(p)]
print(f"\n{name}: {len(hits)}")
for h in hits[:40]:
print(h)
PY
echo
echo 'CLAUDE stale-path references:'
rg -n 'stale|stale-path|path.*stale|after moving|renamed|moved|directories|assets/\*/manifest|local-dev/system/extensions|system/extensions' CLAUDE.md .claude crates/AGENTS.md docs/reborn/contracts 2>/dev/null | sed -n '1,120p'
echo
echo 'Inspect docs snippet and key nearby references:'
sed -n '300,340p' docs/channels/building-a-channel.mdx
sed -n '190,220p' .env.example
sed -n '180,200p' openwiki/development/setup.md
rg -n 'IRONCLAW_REBORN_HOME/local-dev/system/extensions|local-dev/system/extensions|/system/extensions' scripts .env.example openwiki/development/openwiki/development/workflows.md crates/ironclaw_architecture crates/ironclaw_loop_contracts | sed -n '1,200p'Repository: nearai/ironclaw
Length of output: 20755
Fix two stale install paths in this rule.
crates/ironclaw_first_party_extensions/assets/<channel>/ is not a repo-persisted first-party path; use the documented asset path for host-bundled extensions or remove that install instruction. <reborn-home>/local-dev/system/extensions/<channel>/ is invalid for reborn-home placement; the local development path is $IRONCLAW_REBORN_HOME/local-dev/system/extensions/<channel>/. crates/ironclaw_extension_host/src/available_extensions.rs is valid.
🤖 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/channels/building-a-channel.mdx` at line 323, Update the extension
installation guidance to remove or replace the stale
`crates/ironclaw_first_party_extensions/assets/<channel>/` path with the
documented host-bundled asset path, retain registration in
`crates/ironclaw_extension_host/src/available_extensions.rs`, and change the
local development location to
`$IRONCLAW_REBORN_HOME/local-dev/system/extensions/<channel>/`.
Sources: Coding guidelines, Learnings
| `crates/ironclaw_first_party_extensions/assets/notion-mcp/`, with product | ||
| auth / OAuth DCR wiring in composition. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^docs/extensions/building-a-tool\.md$|CLAUDE\.md$|^AGENTS\.md$|\.claude/)' || true
echo "== target doc sizes =="
wc -l docs/extensions/building-a-tool.md
echo "== path occurrences in target =="
rg -n 'crates/ironclaw_first_party_extensions/assets|crates/extensions/packages|assets/[^<|`]*extension|notion-mcp|extension package|package root|manifest|packages' docs/extensions/building-a-tool.md
echo "== guideline files relevant =="
for f in CLAUDE.md AGENTS.md .claude/rules docs/reborn/contracts/ crates/AGENTS.md; do
if [ -f "$f" ]; then
echo "--- $f"
sed -n '1,220p' "$f"
elif [ -d "$f" ]; then
echo "--- dir $f"
fd . "$f" -t f | sed -n '1,80p'
fi
done
echo "== extensions discovery references =="
rg -n 'ironclaw_first_party_extensions|extensions/packages|assets/|packages/.*/manifest|manifest\.json|notion-mcp|reborn\.extension_manifest' *.rs crates docs README.md 2>/dev/null | sed -n '1,240p' || trueRepository: nearai/ironclaw
Length of output: 50374
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== doc ranges =="
sed -n '1,220p' docs/extensions/building-a-tool.md
echo "---720-730---"
sed -n '720,730p' docs/extensions/building-a-tool.md
echo "== target exact paths =="
for p in \
crates/extensions/packages/github \
crates/extensions/packages/notion-mcp \
crates/ironclaw_first_party_extensions/assets/github \
crates/ironclaw_first_party_extensions/assets/notion-mcp \
crates/ironclaw_extension_support/ \
extensions/packages/github \
extensions/packages/notion-mcp \
extensions/ironclaw_extension_support/
do
if [ -e "$p" ]; then
echo "EXISTS $p"
else
echo "MISSING $p"
fi
done
echo "== build script packages/wasm refs =="
fd -a 'build-wasm-extensions\.sh|check-wasm-artifact-freshness\.py|available_extensions\.rs|extension_host' . | sed -n '1,80p'
rg -n 'packages/|first_party_extensions|extension_support|include_bytes|manifest\.toml|wasm.*freshness|wasm-src|notion-mcp|github/' scripts crates docs/reborn/target-architecture/families/extensions.md crates/AGENTS.md docs/extensions/building-a-tool.md 2>/dev/null | sed -n '1,260p'Repository: nearai/ironclaw
Length of output: 50373
Use the canonical crates/extensions/packages/ extension package root.
The old crates/ironclaw_first_party_extensions/assets/<id>/ root is not present, while crates/extensions/packages/github/ and crates/extensions/packages/notion-mcp/ are. Update lines 13-18, 74, 90-94, and 143 to the current crates/extensions/packages/<extension>/ path so the guide matches the repo package invariant in docs/reborn/target-architecture/families/extensions.md.
🤖 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 17 - 18, Update the
extension package paths throughout the building guide, including the references
around the composition section and the locations identified in the comment, to
use the canonical crates/extensions/packages/<extension>/ root. Replace old
crates/ironclaw_first_party_extensions/assets/<id>/ references consistently with
the existing github and notion-mcp package layout, while preserving the
surrounding authentication and OAuth wiring instructions.
| ```toml | ||
| schema_version = "reborn.extension_manifest.v2" | ||
| schema_version = "reborn.extension_manifest.v3" | ||
| id = "example" | ||
| name = "Example" | ||
| version = "0.1.0" | ||
| description = "Example tools for Reborn." | ||
| description = "Example tools for IronClaw." | ||
| trust = "third_party" | ||
|
|
||
| [runtime] | ||
| kind = "wasm" | ||
| module = "wasm/example_tool.wasm" | ||
|
|
||
| [[tools]] | ||
| id = "example.search" | ||
| description = "Search Example records." | ||
| effects = ["network", "use_secret"] | ||
| default_permission = "ask" | ||
| visibility = "model" | ||
| input_schema_ref = "schemas/example/search.input.v1.json" | ||
| output_schema_ref = "schemas/example/search.output.v1.json" | ||
| prompt_doc_ref = "prompts/example/search.md" | ||
|
|
||
| [[tools.credentials]] | ||
| handle = "example_runtime_token" | ||
| vendor = "example" | ||
| audience = { scheme = "https", host = "api.example.com" } | ||
| injection = { type = "header", name = "authorization", prefix = "Bearer " } | ||
| ``` |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Make the v3 manifest example valid.
The example sets vendor = "example" in Line 217. The guide later requires a matching [auth.<vendor>] recipe in Line 399. No [auth.example] recipe appears in the example. A developer who copies this manifest can fail the documented authentication contract. Add a minimal auth recipe, or state that the auth block is intentionally omitted and show where it belongs.
🤖 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 193 - 220, Add a minimal
matching [auth.example] recipe to the v3 manifest example, positioned in the
manifest’s authentication section after the credential declaration or at the
documented auth location. Ensure it corresponds to the existing credentials
handle and satisfies the guide’s required authentication contract.
| ``` | ||
|
|
||
| For host-bundled hosted HTTP MCP, Reborn composition: | ||
| For host-bundled hosted HTTP MCP, composition: |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
fd -a 'building-a-tool\.md$' . || true
echo "== surrounding sections =="
file="$(fd 'building-a-tool\.md$' docs | head -n1 || true)"
if [ -n "${file:-}" ]; then
echo "FILE=$file"
wc -l "$file"
echo "--- lines 250-310 ---"
sed -n '250,310p' "$file" | nl -ba -v250
echo "--- lines 370-410 ---"
sed -n '370,410p' "$file" | nl -ba -v370
echo "--- lines 508-545 ---"
sed -n '508,545p' "$file" | nl -ba -v508
fi
echo "== credential syntax occurrences =="
if [ -n "${file:-}" ]; then
rg -n "runtime_credentials|\\[\\[tools\\.credentials\\]\\]|version|credentials" "$file" | sed -n '1,220p'
fi
echo "== repo files mentioning runtime_credentials / tools.credentials =="
rg -n "runtime_credentials|\\[\\[tools\\.credentials\\]\\]" . --glob '!node_modules' --glob '!target' --glob '!dist' --glob '!build' | sed -n '1,220p'Repository: nearai/ironclaw
Length of output: 451
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="docs/extensions/building-a-tool.md"
echo "FILE=$file"
wc -l "$file"
echo "--- lines 250-310 ---"
sed -n '250,310p' "$file"
echo "--- lines 370-410 ---"
sed -n '370,410p' "$file"
echo "--- lines 508-545 ---"
sed -n '508,545p' "$file"
echo "== credential syntax occurrences in docs extensions =="
rg -n "runtime_credentials|\\[\\[tools\\.credentials\\]\\]|version|credentials" docs/extensions/building-a-tool.md docs/zh/extensions/building-a-tool.md 2>/dev/null | sed -n '1,220p'
echo "== repo files mentioning runtime_credentials / tools.credentials =="
rg -n "runtime_credentials|\\[\\[tools\\.credentials\\]\\]" . --glob '!node_modules' --glob '!target' --glob '!dist' --glob '!build' 2>/dev/null | sed -n '1,220p'Repository: nearai/ironclaw
Length of output: 50374
Version the hosted MCP credential guidance.
docs/extensions/building-a-tool.md states [[tools.credentials]] as v3 while line 530 still projects runtime_credentials, which document as v2. Mark the hosted MCP section v2-only or convert it to v3 inline credentials.
🤖 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` at line 524, Align the hosted HTTP MCP
credential guidance in the section beginning “For host-bundled hosted HTTP MCP,
composition:” with the documented version: either mark the section as v2-only to
match its runtime_credentials projection, or update the example to use v3 inline
credentials instead of [[tools.credentials]].
* init gitignore * ironhub docs * upgrade docs for v1 * resolve comments
Summary
While working on #6766, I noticed the rest of docs were out of sync with current code base. So some other clean up:
capabilities.jsonchannel format with v3manifest.tomlin building-a-channel.mdx, fixed deployment path andhttp_requestsignaturehttps://<instance-id>.agents.near.ai), local installation as separate section\~/.ironclaw/reborn→\~/.ironclawpaths, removed duplicate "Get started" card and outdated warnings from index.mdxChange Type
Linked Issue
None
Validation
cargo fmt --all -- --checkcargo clippy --all --benches --tests --examples --all-features -- -D warningscargo buildcargo test --features integrationif database-backed or integration behavior changedmint dev, verified all hub pages render, nav structure correct, links resolvereview-prorpr-shepherd --fixwas run before requesting reviewTest Strategy
User behavior:
Risk areas:
Tests added or updated:
What the tests prove:
Commands run:
mint dev,mint validateSecurity Impact
None — docs-only change, no code or configuration behavior modified.
Reborn Trust-Boundary Checklist
N/A — docs-only change.
Database Impact
None
Blast Radius
Docs site only (
docs.ironclaw.com). Affected pages: index, quickstart, hub/*, extensions/building-a-tool, channels/building-a-channel, capabilities/skills, zh/capabilities/skills, zh/index. Navigation structure modified indocs.json. No code, runtime, or backend changes.Rollback Plan
Revert the commit. No migration or state rollback needed.
Review Follow-Through
zh/) translations for the three new hub pages are deferred to a follow-upReview track: A