Repository navigation
[pull] main from nearai:main - #38
Merged
Merged
Conversation
…, framework disentanglement, single-run coverage (#5633) * test(reborn): move roadmap integration suite to tests/integration/ (skeleton + renames) Commit 1/8 of the integration-suite restructure. Byte-pure moves: tests/support/reborn/ -> tests/integration/support/, 27 reborn_integration_*.rs bins -> tests/integration/<name>.rs, 7 reborn_group_* dirs -> tests/integration/group_<name>/. Cargo [[test]] names stay identical; only paths move (27 entries added, 7 retargeted). Only content edits: the #[path] mount lines each move forces (flat bins, group mains, 33 parity/QA bins) — wiring folded into this commit so every commit builds green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reborn): split harness.rs into harness/{mod,recorder,options,assembly} + doubles/, extract binary-E2E family to tests/support/reborn_parity_qa/ Commit 2/8. Symbol-preserving split of the 5530-line harness.rs at its final home: recorder.rs (capability recorder), options.rs (HostRuntimeHarnessOptions, verbatim), assembly.rs (local_dev_* runtime/filesystem/policy/mount helpers), doubles/ (14 files, one per substituted production port, rustdoc header names the production seam), residual core in harness/mod.rs with pub(crate) use re-exports preserving every surviving reborn_support::harness::<Name> path. RebornBinaryE2EHarness + SubmittedTurn + RebornHarnessSharedStorage + HarnessLoopExitEvidencePort + assert_milestone_order + trace_tool_call_response and model_replay.rs leave to tests/support/reborn_parity_qa/ (their consumers are exclusively parity/QA); the 33 parity/QA bins mount the new parity_qa_support tree and repoint only those imports. Only content changes beyond the moves: use/mod lines, visibility bumps the new module boundaries force, and per-file dead_code allows replacing the old blanket allow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reborn): collapse harness tools-constructor table into ToolsProfile + harness/profiles/ domains Commit 3/8 — the design commit. HostRuntimeHarnessOptions gains Default; new ToolsProfile value type (options.rs) captures the shared new_with_options seven-arg shape plus the four observed post-construct steps (network-policy override, provider-trust override, asset copy, auto-approve default), applied in the constructors' existing order by the one shared ToolsProfile::build() path. Every tools constructor leaves harness/mod.rs for a per-domain profiles/<domain>.rs file (16 domains): ToolsProfile rows become <name>_profile() + a thin build wrapper; bespoke constructors (qa_smoke, core_builtin, github issue trio, mock_mcp, web_access) move verbatim. The 4-deep core_builtin suffix-variant chain folds into one CoreBuiltinOptions; the four variants are deleted. project_tools_with_fault_injection (new since the plan's table) rides in profiles/project.rs. Thick group pairs (live_approvals, live_auth_and_approval, profile_tools, outbound_target_tools) adopt ToolsProfile::build_group_capability_with_base over GroupBaseData with auto-approve disables kept explicit at call sites; capability_backend::install() now selects via the same profile fns, deleting its duplicate constructor-selection table. The six group-builder runtime setters move to group_options.rs (private child module of group.rs, group_constructors precedent). Constructor doc comments carried verbatim. Flip-checked: falsifying the trigger profile's capability set turns reborn_group_triggers red for the right reason. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reborn): finish parity/QA disentanglement — qa/delivery/network support to reborn_parity_qa/, drop dead approval.rs Commit 4/8. git-mv qa_trace.rs, qa_scenarios.rs, delivery.rs, network.rs from tests/integration/support/ to tests/support/reborn_parity_qa/ (their consumers are exclusively parity/QA bins) and rewrite those consumers' imports (qa_recorded_behavior, qa_smoke_scenarios_e2e, qa_doc_grounding, qa_web_fetch, qa_channel_delivery, outbound_reply_target parity, support_unit_tests). Delete approval.rs — zero consumers anywhere (pub use GateRef + an unused alias). classify-test-scope.sh's reborn path arm now matches tests/integration/* and tests/support/reborn_parity_qa/* instead of the removed tests/support/reborn/*; fixture updated. New tests/support/reborn_parity_qa/CLAUDE.md documents the tier split and the one-way import direction (parity/QA imports FROM tests/integration/support/, never the reverse — direction grep clean). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * ci(reborn): single-run integration-tier coverage lanes + suite-boundary guard Commit 6/8. Kills the run-twice shape: the 34 tests/integration/ suites now run ONCE, instrumented, in a 5-lane reborn-integration-coverage matrix (4 modulo partitions of the 27 flat bins + 1 group lane), features unified to libsql. Each lane produces its lcov from one combined 'cargo llvm-cov --workspace --features libsql test --test ...' invocation — the split --no-report + 'report --lcov' shape silently drops all crates/ironclaw_* files because the standalone report subcommand has no --workspace flag (verified empirically). New coverage-report job merges lane lcovs (checked-in Python merger; sums DA per file:line, recomputes LF/LH, filters to crates/ironclaw_*), applies tests/integration/ coverage-exemptions.toml (seeded empty; every entry needs reason + issue link), and renders a per-crate table to the job summary + a sticky PR comment. Informational only — pass/fail gating rides the instrumented lanes; coverage-report failures warn, never red, the roll-up. reborn-coverage.yml (the duplicate compile+run) is deleted. Parity/QA root-partition lanes stay uninstrumented — the harness-only coverage boundary is enforced by job topology. Instrumented lanes use a dedicated reborn-integration-cov cache key. Discovery scripts retarget to tests/integration/ (group and int-tier enumeration; root partitions now match only the parity/QA bins by construction). New scripts/ci/check-test-suite-boundaries.sh (invoked next to classify-test-scope.sh) enforces the one-way support-tree direction, the parity/QA mount rule, and that tests/support/reborn/ never reappears. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(reborn): repoint living docs to tests/integration/ layout Commit 7/8. tests/integration/support/CLAUDE.md moves to tests/integration/CLAUDE.md with surgical fixes for the new reality (harness/ split + profiles/ + doubles/ file map, new mount-line boilerplate for flat bins and group mains, [[test]] naming convention, binary-E2E family pointer to tests/support/reborn_parity_qa/CLAUDE.md). Root CLAUDE.md spec table + testing pointers, the ironclaw-reborn-testing and reborn-feature skills, and the two living docs/reborn/ pages repoint the same way. Historical dated plans/specs under docs/superpowers/ deliberately untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reborn): comment de-bloat across tests/integration/ Commit 8/8. Comment-only pass over all 126 tests/integration/ files (zero code changes — verified by non-comment diff-line scan). Deleted: narration/play-by-play, migration/wave/lane provenance, restated signatures, duplicated profile/wrapper doc blocks, history essays. Kept, compressed to 1-2 lines: why-pins, mutation-verified notes, doubles seam contracts, product decisions — invariant + issue/PR ref; every C-*/E-*/T0-* seam id and DEFERRED/COVERED pointer retained (regex-checked per lane). ~1,800 comment lines removed net. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reborn): apply post-PR review findings — explicit ToolsProfile user_id, const dedup, stale-path sweep + guard Review follow-up (thermo-nuclear + code-review passes on #5633): - ToolsProfile::new now takes user_id explicitly — the service_label-seeded placeholder was a silently-valid wrong value if a profile ever forgot to override it; all 15 profile call sites pass their fixed domain user id. - TEST_CAPABILITY_ID/TEST_CAPABILITY_SURFACE_VERSION deduplicated: binary_e2e now imports the doubles-tree constants instead of carrying drift-prone copies. - Stale tests/support/reborn/ references swept from tests/** and Cargo.toml (snapshot source headers included); check-test-suite-boundaries.sh gains check #4 failing on any reappearance of the retired path under tests/. (Doc-comment stragglers inside crates/ are deliberately left for a separate docs-only PR — production files stay outside this PR's diff surface.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reborn): address #5633 review findings — script hardening, doc repoints, harness re-encapsulation CI scripts: lcov crate regex accepts relative paths ((?:^|/)crates/) in merge+summary; exemption module paths must start with crates/ (suffix match could over-exempt; +A9 regression case); classify-test-scope now marks the coverage/boundary helper scripts as Reborn scope so helper-only PRs can't fast-pass the pipeline they drive (+6 regression cases). Docs/comments: stale pointers to the removed tests/integration/support/ CLAUDE.md now target tests/integration/CLAUDE.md; group-main boilerplate doc shows the real ../support/mod.rs mount; harness/mod.rs header rewritten for HostRuntimeCapabilityHarness (binary-E2E contract moved); doubles headers cite each substituted symbol's actual production file; parity-bin comment and missing #[allow(dead_code)] mount attr fixed. Structure (review-accepted): build_group_capability_with_base moved from ToolsProfile into group_constructors.rs — profile layer no longer imports group::GroupBaseData, and GroupBaseData/canonical_subject_user return to module-private. Capability-port assembly moved into harness-owned create_recording_capability_port; HostRuntimeHarnessCapabilityPortFactory is a thin trait adapter and 13 harness fields + 2 methods narrowed from pub(crate) to module-private. Coverage: live_shell_uses_local_process_port pins the ShellMode::Live caller path — real LocalHostProcessPort output surfaces in the tool result while the inert recording port stays untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Maps every reborn run error to recoverable / run-borking, analyzes PR #4841 coverage, and lays out the path to the two-bucket end state (SecurityStop | Retriable | Explainable). Headline finding: the host_runtime disposition layer intends no capability failure to abort, but the recovery strategy aborts on Dispatcher/InvalidOutput/Unknown — re-bucketing that class makes "model called a nonexistent tool" and malformed-output failures recoverable. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
A genuine single-line final answer that mentions a `__`-bearing tool (e.g. "Tool result from web__fetch: near.ai returned 200 OK") was misclassified as a replayed provider-transcript artifact and rejected, so the real answer vanished. Only treat MULTI-line content as a transcript artifact; a weak model echoing replayed history reproduces multiple lines, which is still caught. Reject tests updated to multi-line; added a single-line accept test. (F1 stalled-turn recovery intentionally NOT included: gating the nudge on any tool call over-fires on pure-failure runs, and the target 3B hang is the runner queue not draining — a separate P0, not a no-reply-at-exit. Doing F1 right needs a successful-tool-call signal that state does not yet track.) cargo test -p ironclaw_agent_loop: 317 passed, 0 failed. Co-authored-by: Abhishek Vaidyanathan <abhishekvaidyanathan@96:11:14:d5:f7:ba.home> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(migration): add v1/engine-v2 → Reborn state migration tool New crate `ironclaw_reborn_migration` (library + `ironclaw-reborn-migration` binary) that converts legacy IronClaw v1 and engine-v2 persisted state into the Reborn state substrate, recording every unconvertible value in a machine-readable manifest so nothing is silently dropped. Reads a v1 database (PostgreSQL or libSQL) via the root `ironclaw` crate — which is also where engine-v2 mission/project state lives, as JSON blobs in `memory_documents` — and writes through Reborn domain stores built directly over a RootFilesystem / triggers DB. Converts: - conversations + messages → session threads (ids/timestamps preserved) - cron routines + cron missions → TriggerRecords; mission threads under ThreadScope.mission_id - memory documents → ironclaw_memory documents - secrets → decrypt via v1 store, re-encrypt via Reborn SecretStore - user/channel identities → adopt_migrated_identity - installed wasm tools/channels → ExtensionInstallation (placeholder manifest) Gaps recorded in the manifest (no Reborn target): event/webhook/manual trigger sources, non-cron mission cadences, routine guardrails/notify/run-history, mission-only fields, jobs, settings, memory versions, heartbeat, extension manifest fidelity + WASM binary, pairing requests. Adds a `migration-support` feature + `extension_installation_store_for_migration` seam to `ironclaw_reborn_composition` (ships zero bytes without the feature), and read-side channel-store re-exports in `src/channels/wasm`. Acceptance test (`tests/migration_roundtrip.rs`, libSQL, Docker-free) seeds a rich v1+engine-v2 fixture, runs the migration, and asserts converted counts, the exact gap set, triggers read back through the public repo, and on-disk durability of thread/secret/extension documents. A dry-run case asserts full reporting with no writes. Follow-up (documented, deferred per scope): wire run_migration into `ironclaw-reborn` startup. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(migration): address PR #5627 review — fail-loud on silent drops, TLS, secret redaction Addresses the CodeRabbit/Copilot/Gemini review on the v1→Reborn migration tool. Core theme: the crate's "nothing is silently dropped" contract was not fully upheld, plus a few security/cleanup gaps. Data integrity (silent drops → recorded losses or propagated errors): - source: `distinct_user_ids_in` now tolerates only a missing table; every other connect/query/row-decode failure propagates instead of being swallowed as "0 users" (would have silently dropped every record keyed to an undiscovered user). Adds an explicit user-id column arg — the `users` table keys on `id`, not `user_id` (the old code silently ate the "no such column" error). - automations: unparseable engine-thread blobs and parseable-but-orphaned threads (referenced by no mission) are recorded; dry-run mission threads now record the same per-message losses as the real write path. - extensions: `tool_credential_bindings` propagates capability read errors and records unconvertible secret names; the synthesized ExtensionInstallationId is scoped by owner so per-user same-named installs no longer overwrite each other. - identities: invalid user id in the OAuth path is recorded (matching the channel path); `read_channel_identities` tolerates only a missing table and records malformed rows. - secrets: the expiry re-read failure is recorded, not dropped via `.ok()`. - bad-user-id is now a per-item loss + skip (not a run abort) in threads, secrets, automations (routines + missions), and memory. Security: - target Postgres now enforces the repo's remote-TLS rule (reject sslmode=disable for remote hosts; rustls via ironclaw::db::tls) instead of always using NoTls — migration traffic carries decrypted secrets. - Postgres URLs are held as SecretString (SourceDb/TargetStore) and the `Cli` struct drops its `Debug` derive so creds/keys can't leak via `{:?}`. Cleanup: - mounts map the system-scope sentinel to `__system__` (mirrors production invocation_mount_view) so system-scoped service ops resolve correctly. - v2_model `now()` → `epoch_fallback()` (it returns the epoch, not "now"). - `V1Source` is now pub(crate); secrets `migrate_one` carries the required arch-exempt annotation; CLAUDE.md example drops the absolute /tmp path. - add a `ironclaw_reborn_migration` BoundaryRule so the v1↔Reborn bridge can't grow direct deps on the serving/runtime/engine layers. Tests: the roundtrip acceptance test now asserts the exact per-domain gap set (summing to the whole report so a newly-dropped domain fails the build), seeds tool capabilities to exercise credential-binding + Enabled activation, and asserts extension/identity idempotency on re-run. Declined (replied on the PR): error `domain` String→enum (field carries freeform context, not a strict domain); redacting LossyItem source_id (operator-only tool needs actionable ids, no secret values exposed); gemini `expose_secret` (false positive — DecryptedSecret::expose exists). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(migration): address CodeRabbit re-review — mission next_run_at, narrower table-missing, shared user-id helper Follow-up to the review round on PR #5627: - automations: a mission with no `next_fire_at` no longer falls back to `created_at` (which can be the `epoch_fallback` synthesized for a drifted blob → a 1970-dated, immediately-due trigger). The trigger's `next_run_at` is now synthesized to the migration time and recorded as a `Degraded` loss (`mission_next_run_at`). - source: `is_missing_table_error` is narrowed to require `relation` alongside `does not exist`, so a PostgreSQL *column*-not-found (`column "…" does not exist`) is no longer downgraded to an empty user set — keeping the exact silent-drop class #21 guards against. - report: add a shared `MigrationReport::valid_user_id` helper and route the six duplicated "validate UserId → record loss → skip" sites (identities x2, secrets, memory, routines, missions) through it so the shape can't drift. - test: assert the serialized `"enabled"` activation token (and absence of `"disabled"`) instead of a loose lowercase substring; bump the exact Mission gap count to 4 (daily-digest now records the synthesized next_fire_at). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )