mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-02 23:56:24 +08:00
* test(architecture): drop the dead ironclaw_storage row and arm the substrate list
Gate-audit finding (open-and-shut): SUBSTRATE_CRATES in
reborn_composition_boundaries.rs carried three rows of rot, all invisible
because the loop's `let Some(..) else { continue }` silently skipped any
entry that resolves to no workspace package:
- "ironclaw_storage": no such package exists (verified against
`cargo metadata --no-deps`; the only MISSING name of the 29 listed).
- "ironclaw_approvals" and "ironclaw_assistant" were each listed twice.
The silent skip is replaced with a panic naming the stale entry, so the
list can no longer rot invisibly. Verified by sabotage: adding a bogus
"ironclaw_zzz_probe" row now fails the test with
"is listed in SUBSTRATE_CRATES but is not a workspace package"; the
clean list passes (23/23).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): prune the dead sanctioned path from the specificity gate
Gate-audit finding (open-and-shut): SANCTIONED_PATHS in
reborn_extension_specificity.rs still exempted
`extension_host/extension_installation_store.rs` — a file deleted by
#6430. No scanned path matches the fragment (verified with rg across
crates/), so the entry exempted nothing; it is also the one exclusion
surface in this gate with no staleness check, which is how it outlived
its file. Full specificity suite green after removal (8/8).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): drop the v1 ironclaw_gateway/static exclusions from the telegram gates
Gate-audit finding (open-and-shut): both cross-tree scans in
telegram_extension_gates.rs still carved out `ironclaw_gateway/static`
— the v1 monolith's embedded UI, whose crate was deleted with the src/
monolith (no crates/*/ironclaw_gateway directory exists). The exclusions
matched nothing; scans now cover the whole tree with no dead carve-outs.
Suite green after removal (12/12).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): make the dto-collapse gate's header describe the gate that exists
Gate-audit finding (open-and-shut doc rot): the module doc still
described the pre-#6447 freeze design — a dangling doc-link to
FROZEN_COLLAPSE_DTOS (renamed RETIRED_COLLAPSE_DTOS in #6447), a
promised delete-without-trimming failure and an empty-allowlist
assertion that do not exist in the file, and a named owner for a
collapse that completed. The mechanism itself is armed and untouched;
the header now describes the permanent zero-gate it became, and records
the two originally-frozen names that deliberately left governance
(CapabilityOutcome via #6299 deletion, CapabilityDispatchRequest blessed
as the canonical port type). Suite green (2/2).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): repoint the manifest-reparse allowlist note at the colocated asset
Gate-audit finding (open-and-shut doc rot): the BundledAsset allowlist
entry's justification still cited include_str! of
assets/memory_native/manifest.toml — a path retired when WS2 (#7037)
colocated packages; the live include in memory_native_extension.rs
reaches crates/extensions/packages/memory-native/manifest.toml. Comment
only; the gate's mechanism and counts are untouched. Suite green (2/2).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): give the memory-vocabulary gate the partial-tree floor its twin has
Gate-audit finding: reborn_memory_retired_vocabulary.rs had no
MIN_SCANNED_FILES floor, unlike its explicit twin
reborn_retired_taxonomy.rs — so a partially-moved tree (the CHECKLIST
WS0 / #6963 'green while measuring nothing' shape) would scan a
fraction of the files and still report the vocabulary clean. The gate
was in fact born with an already-dead sanctioned path (its own header
records this), so the rot class is not hypothetical for this file.
Adds the same 500-file floor (real count ~4000), asserts it in the main
gate, and pins the premise on a fixture: a 10-file partial tree scans
clean and is rejected by the floor. Suite green (4/4); clippy clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): close the transport gate's nested-use-group fail-open
Gate-audit finding (sabotage-verified): product_symbols_in's braced-group
branch closed at the FIRST '}' (group.find('}')), so a nested group —
use ironclaw_assistant::{m::{X}}; — truncated mid-element and recorded
zero symbols. Probed live before the fix: appending
use ironclaw_assistant::{zzz_audit::{ZzzProbe}}; to webui's lib.rs left
transports_name_only_the_frozen_residue_of_product_symbols GREEN, while
the plain-path spelling of the same import correctly failed. The same
truncation dropped qualified elements inside flat groups
({qualified_module::X} recorded nothing).
The group branch now does a balanced-brace walk, splits elements at
depth-0 commas only, and records a qualified/nested element's leading
path segment — the same key the single-path branch records for
ironclaw_assistant::module::X. Flat-element semantics are byte-for-byte
unchanged, so the frozen 100-row webui inventory is untouched (suite
green 6/6 on the live tree). Regression fixtures added to
import_scanner_reads_symbols_out_of_real_use_shapes; the original
sabotage now fails with the gate's own message (re-verified).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci: delete check-e2e-matrix-files.sh — a gate for a workflow that no longer exists
Gate-audit finding (provably inert): the script's default target is
.github/workflows/e2e.yml, deleted when the v1 e2e suites were retired
(git log --diff-filter=D shows the removing commit); no workflow, script,
hook, doc, or guidance file references check-e2e-matrix-files.sh
(verified with rg across the repo including .github and .githooks).
A checker nothing runs, pointed at a file nothing provides, is dead
weight that reads as coverage.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci: delete the measured-broken check-boundaries.sh and its guidance references
Gate-audit finding (provably inert, previously measured): crates/AGENTS.md
recorded on 2026-08-05 that the script fails on a clean tree (check 5
false-positives on live test files) and that checks 1/2/3/6 target the
deleted v1 src/ tree, passing vacuously. No workflow or hook runs it; its
only callers were guidance files, two of which claimed it 'enforces'
root-tests feature gating — an enforcement claim the skill-maintainer
rules forbid for a check nothing executes.
Removed the script and every live reference: the crates/AGENTS.md warning
row becomes a tombstone note; the testing skill + exemplar reference drop
the false enforcement parenthetical; the architecture-review skill's
Verify line drops the dead command; deslop-reborn's allowed-tools drops
the permission; .coderabbit.yaml's driver-leak instruction now points at
the live enforcement (reborn_persistence_driver_boundary). Two dated
docs/internal/ plan snapshots keep their historical mentions.
Verified: python3 scripts/ci/check-guidance.py OK (2084 path references)
and its self-test OK.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs(product): stop hardcoding charter sub-owner counts in the family map
Gate-audit finding (stale prose): crates/product/AGENTS.md said
'19-sub-owner reborn_services charter map' — the enforced map has had 20
sub-owners since #7235 added the inspector row (counted from the live
table). Rather than chase the number, drop both inline counts: the
owning maps and their gates are authoritative, and the re-verify
commands are already inline (skill-maintainer rule: no counts without a
regeneration recipe). check-guidance.py OK.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): correct the scanner-fixture file's name-filter claim
Gate-audit finding (doc rot with a false coverage claim): the header
said naming the FILE reborn_* makes code_style.yml's
'cargo test -p ironclaw_architecture_tests reborn' see it — but that
argument is a test-NAME filter (the measurement is documented in
reborn_contracts_vendor_census.rs), and none of this file's test fns
contains the substring, so that smoke lane runs 0 of them (11 collected
by the full plan). Comment-only; the note now records the real semantics
so file names are not trusted for lane coverage. Suite green (11/11).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs(internal): gate & ratchet audit report + proposed preflight gauntlet
The audit the owner asked for after PR #7157 went red six times across
four gates: every architecture-test gate, module charter, CI script, and
committed baseline inventoried with a verdict and evidence; the handful
worth acting on ranked by friction x weakness; the CI-ergonomics analysis
(why failures surface one per ~1h round-trip: no --no-fail-fast anywhere
in CI, cancel-in-progress on push, sequential fast-checks steps —
measured: two broken gates report 1 failure in 18s under the CI shape vs
both in 211s with --no-fail-fast); and the sabotage log for every probe.
scripts/preflight-gates.sh is the concrete pre-push proposal: the
deterministic-gate classes only (script gates ~10s + architecture suite
--no-fail-fast + changed-crate charter tests), covering all four #7157
gate classes locally in one command. Unwired — nothing invokes it.
Validated end-to-end on this branch: exit 0, 'every deterministic gate
green', 402.8s including gate-binary recompiles.
Placement verified: python3 scripts/ci/docs_publication_boundary.py OK.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(planner): classify preflight-gates.sh and the deleted check-boundaries.sh
The gate audit's own PR hit the planner's fail-closed arm — 'unmapped
test or CI path: scripts/check-boundaries.sh' — exactly the class the
arm exists to force a decision on (and the audit's report documents).
Per the PR_STATIC_CONTROL_PATHS membership rule (no Reborn test lane
exercises either file):
- scripts/preflight-gates.sh — the audit's proposed local pre-push
gauntlet; referenced by no workflow.
- scripts/check-boundaries.sh — deleted by the audit; the entry lets the
deletion diff (and any revert) classify instead of failing every
downstream Reborn lane.
Verified: the planner now produces mode=selected with the
architecture-misc bucket for this branch's diff, and
python3 scripts/ci/test_reborn_pr_test_plan.py is OK.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs(internal): add the fold-tripped asymmetric-tolerance exhibit to the audit
The strongest single exhibit for shortlist item 2, contributed by the
#7157 branch steward after this audit's cutoff and verified against the
gate's code: TOLERANCE = 400 is consulted in exactly one direction (the
banked-slack check, ceiling.saturating_sub(lines) > TOLERANCE); the
growth check is a bare lines > ceiling. With the in-file 'set to
current, not padded' instruction, every ceiling is a hard cap at the
observed count — so one line landing on main in any contracts crate
reds every open branch at its next fold until someone re-captures.
Measured recurrence on #7157: loop_contracts re-captured four times,
~once per fold (14,479 -> 13,850 -> 13,949 -> 13,115 -> 13,181), the
last tripped by main's #7361/#7363 adding 66 lines to
instruction_bundle.rs — nothing the branch wrote. All four deltas were
<= 105 lines: either repair shape in §3.2 (one-line upward tolerance
using the existing constant, or mid-window pinning) would have absorbed
every one with zero red builds. This audit's own sabotage already
proved the jaws (+1 line host_api red / -1 line common red); the fold
history shows the operational cost. The repair stays a recommendation —
adding growth headroom to a ratchet is the owner's call, not this PR's.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test(architecture): give the contracts size ceiling upward working slack
Owner-directed repair of the audit's sharpest finding (report §3.2): the
gate's TOLERANCE = 400 was consulted in exactly one direction — the
banked-slack check — while the growth check was a bare lines > ceiling.
Combined with 'set to current, not padded' pins, every ceiling was a hard
cap at the exact observed count, so one line landing on main in any
contracts crate redded every open branch at its next fold until someone
re-captured. Measured on #7157: four loop_contracts re-captures, roughly
once per fold, every delta <= 105 lines — the gate generating its own
busywork.
The growth check now allows GROWTH_TOLERANCE = 150 of working slack
above each pin (sized to composition-budget precedent; the reviewed
raises this gate has caught were +1,069 and +1,214 lines, far above it),
and all six ceilings are re-pinned to the counts the test itself
reported with every ceiling at 0 — which also removes the +400 seed
padding on common/loop_contracts/prompt_envelope that contradicted the
capture rule and put those crates one deleted line from the banked jaw.
Sabotage-verified both ways: +1 line in host_api and -1 line in common —
both red before this change — now pass; a +151-line probe still fails
with the effective-ceiling arithmetic in the message. Full
reborn_dependency_boundaries binary green (41/41); clippy clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* ci(budget): re-equalize composition pins to observed — restore the working window
Owner-directed companion to the contracts-ceiling repair (same annoying
class, other mass gate): merged main-side growth since the 2026-08-05
equalization had drifted +101 LOC and +5 Arc<dyn> sites through the
tolerance windows, leaving 49 LOC / 10 sites of live headroom — the next
routine composition PR would have gone red on wiring alone (the gate
audit measured this the same day it was pinned).
Per the TOML's own maintenance instructions: loc_ceiling/loc_observed
40423 -> 40524 and arc_dyn 814 -> 819, measured with the gate's --print,
set to current not padded, dated notes appended (not overwritten), and
the arch-test record (COMPOSITION_ABSOLUTE_SRC_LOC) moved in the same
commit as its file requires. ceiling_bp stays 658 — the WS0 floor is
deliberately not re-set.
Verified: check-composition-budget.sh OK; its 76-case self-test green;
reborn_restructure_baselines green; probe +100 LOC now passes (was red
at 49 headroom), probe +160 LOC still fails.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs(internal): record the landed zero-slack repairs in the audit report
The §3.2 repair moved from recommendation to landed at owner direction;
the report's answer, inventory rows, and §7 ledger now say so, with the
counting-rule fix promoted to the top remaining recommendation.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* gates: pin the ceiling-window arithmetic; fail preflight discovery closed
Two review-round hardenings (the open CodeRabbit Majors):
- reborn_dependency_boundaries.rs: extract the size-ceiling comparison into
contracts_ceiling_verdict() and pin its four window edges with a committed
regression test (contracts_size_ceiling_window_edges_hold) — accept at
ceiling+GROWTH_TOLERANCE, reject one line past, accept at
ceiling-TOLERANCE, reject one banked line further, and a zero-measure scan
reads Banked, never a silent pass. The pre-repair asymmetry (tolerance
consulted only downward) can no longer return silently. Live-gate behavior
re-probed unchanged after the rewiring: +1 line to host_api passes, +151
fails with the same effective-ceiling message.
- preflight-gates.sh: setup and changed-file discovery now fail closed — a
missing repo root exits 2, and a failed merge-base/diff widens the charter
run to all five crates instead of silently skipping them (the same
fallback the missing-base branch already used). A broken setup may cost
compile time, never a silent skip.
Full boundary binary 42/42 green; clippy clean; preflight-gates.sh
end-to-end green on this tree.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
267 lines
15 KiB
YAML
267 lines
15 KiB
YAML
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
|
|
#
|
|
# CodeRabbit configuration for nearai/ironclaw.
|
|
#
|
|
# Context: CodeRabbit is being trialed as the primary AI reviewer, a candidate
|
|
# replacement for Gemini Code Assist, the ruleset-enforced Copilot review, Codex,
|
|
# and the on-demand `@claude review` workflow. During the trial all reviewers run
|
|
# side by side for comparison.
|
|
#
|
|
# Deterministic CI remains authoritative for everything it gates (cargo fmt,
|
|
# clippy -D warnings, cargo-deny, scripts/check_no_panics.py,
|
|
# scripts/check_gateway_boundaries.py, regression-test-check) — CodeRabbit is
|
|
# configured NOT to repeat those findings.
|
|
#
|
|
# On-demand deep review: comment `@coderabbitai full review` (replaces
|
|
# `@claude review`). Other commands: `@coderabbitai review` (incremental),
|
|
# `pause` / `resume`, and `@coderabbitai ignore` in the PR description to opt out.
|
|
#
|
|
# NOTE: this file is inert until the CodeRabbit GitHub App is installed on the
|
|
# nearai org and authorized for this repository (dashboard action, not code).
|
|
language: en-US
|
|
tone_instructions: "Terse, evidence-first senior Rust review. Cite the repo invariant violated (CLAUDE.md/AGENTS.md/.claude/rules). Skip what clippy, rustfmt, cargo-deny and check_no_panics already gate. Sandbox, trust, secrets, egress and migration issues first."
|
|
|
|
reviews:
|
|
profile: assertive # full strength for the head-to-head trial against the other AI reviewers
|
|
request_changes_workflow: false # advisory only; merge gating stays with the ruleset's required checks
|
|
high_level_summary_in_walkthrough: true # keep PR descriptions owner-authored; put generated summaries in the walkthrough comment
|
|
|
|
# Review everything except generated / vendored / fixture / binary content.
|
|
path_filters:
|
|
- "!**/Cargo.lock"
|
|
- "!CHANGELOG.md" # maintained by release-plz
|
|
- "!ironclaw.bash" # clap_complete-generated completions
|
|
- "!ironclaw.fish"
|
|
- "!ironclaw.zsh"
|
|
- "!README.ja.md" # translations; review the English source
|
|
- "!README.ko.md"
|
|
- "!README.ru.md"
|
|
- "!README.zh-CN.md"
|
|
- "!docs/zh/**"
|
|
- "!docs/images/**"
|
|
- "!docs/internal/architecture-video/package-lock.json"
|
|
- "!tests/test-pages/**" # saved web pages (linguist-generated)
|
|
- "!tests/fixtures/**" # recorded LLM/gateway traces
|
|
- "!tests/snapshots/**" # insta snapshots — the replay gate owns these
|
|
- "!src/cli/snapshots/**"
|
|
- "!tests/e2e/ironclaw_e2e.egg-info/**"
|
|
- "!tests/e2e/**/*.png"
|
|
- "!fuzz/corpus/**"
|
|
- "!crates/substrates/ironclaw_safety/fuzz/corpus/**"
|
|
- "!**/*.wasm" # compiled artifacts; new binaries surface via registry/ and manifest review
|
|
- "!crates/ironclaw_webui_v2_static/static/assets/**" # binary icons; static/js IS hand-written and reviewed
|
|
- "!wix/**" # cargo-dist/WiX installer boilerplate
|
|
- "!ironclaw.png"
|
|
|
|
path_instructions:
|
|
- path: "**/*.rs"
|
|
instructions: |
|
|
Review against the repo's named invariants and cite them:
|
|
- "Everything Goes Through Tools": gateway handlers, CLI commands, routine engine,
|
|
WASM channels and other non-agent callers route actions through
|
|
ToolDispatcher::dispatch(), never directly via state.store / workspace /
|
|
extension_manager / skill_registry / session_manager (exceptions need
|
|
"// dispatch-exempt: <reason>").
|
|
- Trusted-ingress seal: product adapters, product workflow, first-party capabilities
|
|
and host-runtime handlers consume untrusted inbound requests; they must not mint
|
|
TrustedInboundTurnRequest or call trusted trigger-submitter factories; never add a
|
|
second agent loop.
|
|
- Fail loud: flag silent-failure patterns — .unwrap_or_default() on a Result, .ok()?
|
|
dropping errors, let-else returning None to swallow failures, warn-and-continue that
|
|
poisons state. Errors propagate with ? into thiserror types with context.
|
|
- "LLM data is never deleted": no stripping/truncating/deleting LLM output, context,
|
|
reasoning or tool calls from the database; cleanup means cache eviction, never row
|
|
deletion.
|
|
- Prompt templates live in files (crates/ironclaw_engine/prompts/*.md via
|
|
include_str!), never inline Rust string constants.
|
|
- REPL/TUI logging: info!/warn! corrupt the terminal UI — internal diagnostics use
|
|
debug!; background tasks never use info!.
|
|
- Test through the caller: when a helper gates a side effect, require a test driving
|
|
the real call site (handler/factory/manager), not only the helper.
|
|
- Imports: crate:: for cross-module paths (super:: only in tests); no pub use
|
|
re-exports unless for downstream consumers; import extracted-crate types from
|
|
ironclaw_safety / ironclaw_skills / ironclaw_llm directly, not via crate:: shims.
|
|
- Module specs win ties (root CLAUDE.md "Module Specs" table) — flag diffs that
|
|
contradict their module spec without updating it.
|
|
- New `unsafe` outside #[cfg(test)] env-var manipulation is exceptional and needs a
|
|
SAFETY comment; many reborn/product crates declare #![forbid(unsafe_code)].
|
|
Do NOT flag: .unwrap()/.expect()/assert! in production (scripts/check_no_panics.py is
|
|
a blocking CI gate), rustfmt/clippy-level style, dependency licenses/advisories
|
|
(cargo-deny), or pre-existing issues the PR does not touch.
|
|
- path: "migrations/**"
|
|
instructions: |
|
|
Refinery PostgreSQL migrations. Released migrations are IMMUTABLE: any edit to an
|
|
existing V*.sql or to a pinned hash in migrations/checksums.lock is a hard error (the
|
|
released_migrations_are_immutable test enforces SipHasher13 checksums). New
|
|
migrations: next sequential V{n}__snake_case.sql, up-only, PostgreSQL dialect.
|
|
Dual-backend mandate: schema changes generally need a matching hand-translated update
|
|
in src/db/libsql_migrations.rs (UUID→TEXT, TIMESTAMPTZ→ISO-8601 TEXT, JSONB→TEXT,
|
|
BYTEA→BLOB, VECTOR→F32_BLOB) — flag a new V*.sql without a libSQL twin change unless
|
|
justified. Ported schema must include indexes and seed data, with semantic
|
|
differences documented. Destructive DDL is review track C: 2 approvals + documented
|
|
rollback plan (CONTRIBUTING.md).
|
|
- path: "src/db/**"
|
|
instructions: |
|
|
Dual-backend persistence: every new persistence feature supports BOTH PostgreSQL and
|
|
libSQL — extend the shared Database trait first, then both backends (Reborn stores
|
|
keep ironclaw_hooks_postgres / ironclaw_hooks_libsql in parity via hooks_parity).
|
|
Multi-step DB operations must be wrapped in a transaction. Driver types
|
|
(tokio_postgres::, libsql::) must not leak outside the allowed modules
|
|
(enforced by reborn_persistence_driver_boundary in
|
|
crates/app/ironclaw_architecture_tests).
|
|
- path: "**/*.wit"
|
|
instructions: |
|
|
Hand-written WIT contracts define the trusted/untrusted WASM ABI. Interface changes
|
|
must stay in sync with the host bindgen sites (src/tools/wasm/wrapper.rs,
|
|
src/channels/wasm/wrapper.rs, crates/ironclaw_wasm/src/bindings.rs,
|
|
crates/ironclaw_wasm_product_adapters/src/bindings.rs) and the ~20 guest crates under
|
|
tools-src/ and channels-src/. WIT or extension-source changes require version bumps
|
|
(scripts/check-version-bumps.sh; escape token [skip-version-check]). Host capability
|
|
functions are security-gated: secrets must never cross into WASM guests; guest
|
|
outputs are scanned for leaks — flag anything that widens host capabilities or
|
|
bypasses capability checks.
|
|
- path: "**/*.capabilities.json"
|
|
instructions: |
|
|
Capability manifests grant authority to sandboxed WASM guests. Every new or broadened
|
|
grant (network hosts, workspace paths, secrets, tool-invoke) is a security decision:
|
|
require justification, prefer the narrowest scope, flag wildcard or broad-domain
|
|
grants.
|
|
- path: "registry/**"
|
|
instructions: |
|
|
Registry manifests are embedded into the binary and drive extension installation.
|
|
Verify URLs point at expected upstreams, artifact references carry checksums, and no
|
|
un-audited prebuilt WASM is introduced (root build.rs documents committed WASM as a
|
|
supply-chain risk).
|
|
- path: "{src/sandbox/**,src/secrets/**,src/safety/**,src/gate/**,src/pairing/**,src/auth/**,crates/substrates/ironclaw_safety/**,crates/substrates/ironclaw_secrets/**,crates/substrates/ironclaw_network/**,crates/kernel/ironclaw_trust/**,crates/kernel/ironclaw_authorization/**,crates/kernel/ironclaw_capabilities/**,crates/ironclaw_process_sandbox/**,crates/contracts/ironclaw_prompt_envelope/**,crates/product/ironclaw_webui/**}"
|
|
instructions: |
|
|
Kernel/safety boundary — review track C (2 approvals + rollback plan). Hold the line
|
|
on: no weakening of bearer/webhook auth, CORS/origin checks, body/rate limits or
|
|
egress allowlists; egress goes through host-mediated policy with private-IP /
|
|
DNS-rebinding rejection (ironclaw_network policy/resolver); never expose raw secret
|
|
material via metadata, errors, debug output, audit records, events or dispatch
|
|
results (ironclaw_secrets); privileged EffectiveTrustClass variants (FirstParty,
|
|
System) are constructible only inside ironclaw_trust; sandbox lanes accept typed
|
|
plans only (SandboxProcessPlan) — no raw Docker flags, raw host paths or blanket env
|
|
inheritance; events/audit records are redacted by contract. Treat containers and
|
|
external services as untrusted.
|
|
- path: ".github/workflows/**"
|
|
instructions: |
|
|
GitHub Actions hygiene. Privileged triggers exist (pull_request_target in
|
|
pr-label-*.yml; issue_comment dispatchers in claude-review.yml and nearai-bench.yml):
|
|
flag privileged workflows that check out or execute PR-controlled code,
|
|
`permissions:` expansions, unpinned third-party actions (pin full SHAs), and
|
|
interpolation of untrusted ${{ github.event.* }} strings into run: scripts. The
|
|
roll-up job names "Run Tests" and "Code Style (fmt + clippy)" are required checks in
|
|
the main ruleset — renaming them silently un-gates merges.
|
|
- path: "{scripts/**,.github/scripts/**}"
|
|
instructions: |
|
|
CI and dev tooling. Expect set -euo pipefail and quoted expansions; these scripts
|
|
gate merges (check_no_panics.py, check_gateway_boundaries.py, pr-labeler.sh), so
|
|
behavior changes need matching workflow updates.
|
|
- path: "tests/e2e/**"
|
|
instructions: |
|
|
Python/Playwright e2e harness (see tests/e2e/CLAUDE.md). Scenarios use the mock LLM /
|
|
fake APIs, never live providers; credentials come from env, never hardcoded.
|
|
- path: "{Dockerfile*,docker/**,deploy/**,infra/**,crates/Dockerfile.sandbox}"
|
|
instructions: |
|
|
Sandbox and deployment images are security boundaries running untrusted workloads.
|
|
Flag privilege escalation (root user, added capabilities, docker.sock mounts),
|
|
weakened entrypoint isolation, secrets baked into layers, and unpinned base images.
|
|
- path: "{crates/ironclaw_gateway/static/**,crates/ironclaw_webui_v2_static/static/js/**,src/channels/web/static/**}"
|
|
instructions: |
|
|
Hand-written no-build frontends embedded into the binary. Watch XSS sinks
|
|
(innerHTML / htm interpolation), CSP-nonce handling
|
|
(ironclaw_webui_v2_static/src/router.rs), origin/CSRF checks, and token handling in
|
|
client JS.
|
|
|
|
auto_review:
|
|
enabled: true
|
|
drafts: false # matches the Copilot ruleset behavior; review starts at ready-for-review
|
|
auto_pause_after_reviewed_commits: 0 # never silently pause mid-PR during the trial
|
|
base_branches: # main is always reviewed; these are the long-lived extras
|
|
- "staging"
|
|
- "reborn-integration"
|
|
|
|
suggested_labels: false # label suggestions are owned by .github/scripts/pr-labeler.sh + actions/labeler
|
|
auto_apply_labels: false # labels are owned by .github/scripts/pr-labeler.sh + actions/labeler
|
|
|
|
tools:
|
|
clippy:
|
|
enabled: false # CI gates `cargo clippy --all-features -- -D warnings`; re-reporting is noise
|
|
github-checks:
|
|
enabled: true
|
|
timeout_ms: 300000 # required roll-ups aggregate ~15 conditional jobs; default 90s is too short
|
|
gitleaks:
|
|
enabled: true # no secret scanning in CI — unique fill
|
|
trufflehog:
|
|
enabled: true
|
|
actionlint:
|
|
enabled: true # 21 workflows incl. privileged triggers, unlinted today
|
|
zizmor:
|
|
enabled: true
|
|
shellcheck:
|
|
enabled: true # scripts/** has no shell linting in CI
|
|
hadolint:
|
|
enabled: true # 6 hand-written Dockerfiles, unlinted
|
|
sqlfluff:
|
|
enabled: true # 31 refinery migrations, unlinted
|
|
osvScanner:
|
|
enabled: false # cargo-deny (PR-time) + Dependabot own dependency advisories
|
|
trivy:
|
|
enabled: false
|
|
markdownlint:
|
|
enabled: false # docs are Mintlify-managed; no repo markdownlint config — style nags only
|
|
yamllint:
|
|
enabled: false # no repo yamllint config; actionlint covers workflow correctness
|
|
languagetool:
|
|
enabled: false # prose grammar comments are noise here
|
|
|
|
pre_merge_checks: # advisory (warning) — request_changes_workflow stays false
|
|
docstrings:
|
|
mode: "off" # quoted deliberately: bare `off` is YAML boolean false
|
|
title:
|
|
mode: warning
|
|
requirements: "Prefer Conventional Commits style (type(scope): summary) — squash-merge makes the PR title the permanent main-branch subject."
|
|
description:
|
|
mode: warning
|
|
issue_assessment:
|
|
mode: warning # CONTRIBUTING.md requires an approved issue for new features
|
|
# custom_checks are Pro+ — uncomment after confirming the plan tier in the dashboard:
|
|
# custom_checks:
|
|
# - name: "FEATURE_PARITY same-branch update"
|
|
# mode: warning
|
|
# instructions: "If the PR changes the implementation status of any capability tracked in FEATURE_PARITY.md (❌/🚧/✅, notes, priorities), FEATURE_PARITY.md must be updated in this same PR (AGENTS.md / CONTRIBUTING.md 'Feature Parity Requirement')."
|
|
# - name: "Released migrations are immutable"
|
|
# mode: warning
|
|
# instructions: "Fail if the PR edits an existing migrations/V*.sql or rewrites a pinned hash in migrations/checksums.lock; released refinery migrations must never be modified."
|
|
|
|
finishing_touches:
|
|
docstrings:
|
|
enabled: false
|
|
unit_tests:
|
|
enabled: false # Pro+; regression-test-check.yml + the codecov patch target own test pressure
|
|
simplify:
|
|
enabled: false
|
|
|
|
knowledge_base:
|
|
web_search:
|
|
enabled: true
|
|
learnings:
|
|
scope: local # public repo — keep learnings repo-scoped
|
|
code_guidelines:
|
|
enabled: true
|
|
# Defaults already ingest **/AGENTS.md and **/CLAUDE.md (root + the nested crate files).
|
|
# Add the review-shaped docs the defaults miss:
|
|
filePatterns:
|
|
- ".claude/rules/*.md" # error-handling, review-discipline, testing, safety-and-sandbox — the most review-shaped rules in the repo
|
|
- "CONTRIBUTING.md" # review tracks A/B/C, issue-first policy, FEATURE_PARITY requirement
|
|
- files: "src/tools/README.md" # declared module specs (root CLAUDE.md table) hidden from the defaults by README naming
|
|
applyTo: "src/tools/**"
|
|
- files: "src/setup/README.md"
|
|
applyTo: "src/setup/**"
|
|
- files: "src/workspace/README.md"
|
|
applyTo: "src/workspace/**"
|
|
|
|
chat:
|
|
auto_reply: true
|