diff --git a/checkpoint.json b/checkpoint.json new file mode 100644 index 000000000..d3e9b6c32 --- /dev/null +++ b/checkpoint.json @@ -0,0 +1,52 @@ +{ + "timestamp": "2026-03-15T22:54:25.895350Z", + "current_node": "toolchain", + "completed_nodes": [ + "start", + "toolchain" + ], + "node_retries": { + "toolchain": 1, + "start": 1 + }, + "context_values": { + "graph.goal": "# Plan: Add safeguards to asset collection and checkpoint commits\n\n## Context\n\nComparing our snapshot safeguards to Codex's ghost commits revealed gaps:\n- Asset collection has no file count limit — a run matching thousands of small files will collect them all\n- Asset collection excludes fewer directories than Codex (missing Python venvs, build dirs, caches)\n- Checkpoint commits have no built-in exclude defaults — a fresh run with no config runs `git add -A` on everything that isn't gitignored\n\n## Changes\n\n### 1. Add MAX_FILE_COUNT to asset collection\n\n**File:** `lib/crates/fabro-workflows/src/asset_snapshot.rs`\n\nAdd constant:\n```rust\nconst MAX_FILE_COUNT: usize = 100;\n```\n\nIn `select_files_to_collect()` (line 195), add count check alongside existing size budget check:\n```rust\nif selected.len() >= MAX_FILE_COUNT {\n break;\n}\n```\n\nUpdate existing test `select_files_enforces_total_budget` to verify the count limit doesn't interfere, and add a new test `select_files_enforces_count_limit`.\n\n### 2. Expand EXCLUDE_DIRS for asset collection\n\n**File:** `lib/crates/fabro-workflows/src/asset_snapshot.rs`\n\nAdd missing directories from Codex's list. Current:\n```rust\nconst EXCLUDE_DIRS: &[&str] = &[\n \".git\", \"node_modules\", \".pnpm-store\", \".npm\",\n \"target\", \".next\", \"__pycache__\",\n];\n```\n\nNew (adding 7 entries):\n```rust\nconst EXCLUDE_DIRS: &[&str] = &[\n \".git\", \"node_modules\", \".pnpm-store\", \".npm\",\n \"target\", \".next\", \"__pycache__\",\n \".venv\", \"venv\", \".cache\", \".tox\",\n \".pytest_cache\", \".mypy_cache\", \"dist\",\n];\n```\n\nRationale for each addition:\n- `.venv`, `venv` — Python virtual environments (thousands of files)\n- `.cache` — generic cache dir (pip, pre-commit, etc.)\n- `.tox` — Python tox testing tool virtualenvs\n- `.pytest_cache`, `.mypy_cache` — Python tool caches\n- `dist` — JS/TS build output\n\nNot adding `build` or `env`/`.env` from Codex — `build` is too generic (many projects have legitimate `build/` dirs with test outputs), and `env`/`.env` could be dotenv config files.\n\n### 3. Apply built-in excludes to checkpoint commits\n\n**File:** `lib/crates/fabro-workflows/src/asset_snapshot.rs`\n\nExtract `EXCLUDE_DIRS` into a public constant so it can be shared:\n```rust\npub const EXCLUDE_DIRS: &[&str] = &[ ... ];\n```\n\n**File:** `lib/crates/fabro-workflows/src/engine.rs`\n\nIn `git_checkpoint()`, always include `EXCLUDE_DIRS` as pathspec excludes, merged with user-configured `exclude_globs`. Convert each `EXCLUDE_DIRS` entry to `**/dirname/**` glob format for git pathspec compatibility.\n\nChange at line ~550:\n```rust\nlet mut all_excludes: Vec = asset_snapshot::EXCLUDE_DIRS\n .iter()\n .map(|d| format!(\"**/{d}/**\"))\n .collect();\nall_excludes.extend(exclude_globs.iter().cloned());\nall_excludes.sort();\nall_excludes.dedup();\n\nlet add_cmd = if all_excludes.is_empty() {\n format!(\"{GIT_REMOTE} add -A\")\n} else {\n let pathspecs: Vec = all_excludes\n .iter()\n .map(|g| format!(\"':(glob,exclude){g}'\"))\n .collect();\n format!(\"{GIT_REMOTE} add -A -- . {}\", pathspecs.join(\" \"))\n};\n```\n\nThis means checkpoint commits will always exclude the same directories as asset collection, plus any user-configured globs. The `add_cmd` branch for empty excludes becomes unreachable but can stay for clarity.\n\n## Files to modify\n\n1. `lib/crates/fabro-workflows/src/asset_snapshot.rs` — add MAX_FILE_COUNT, expand EXCLUDE_DIRS, make EXCLUDE_DIRS pub\n2. `lib/crates/fabro-workflows/src/engine.rs` — merge built-in excludes into checkpoint git add\n\n## Approach: Red/Green TDD\n\nFor each change, write the failing test first, then make it pass.\n\n### Step 1: MAX_FILE_COUNT (asset collection)\n\n**Red:** Add test `select_files_enforces_count_limit` in `asset_snapshot.rs` — create 150 small, recent files and assert `select_files_to_collect` returns at most 100. Run tests, verify it fails.\n\n**Green:** Add `const MAX_FILE_COUNT: usize = 100;` and the count check in `select_files_to_collect()`. Run tests, verify it passes.\n\n### Step 2: Expanded EXCLUDE_DIRS (asset collection)\n\n**Red:** Add test `build_find_command_excludes_venv` that asserts the find command contains `.venv` in the prune clause. Run tests, verify it fails.\n\n**Green:** Add the 7 new entries to `EXCLUDE_DIRS`. Run tests, verify it passes.\n\n### Step 3: Built-in excludes for checkpoint commits\n\n**Red:** Add test in `engine.rs` (or appropriate test module) that calls `git_checkpoint` with empty `exclude_globs` and asserts the `git add` command includes pathspec excludes for `EXCLUDE_DIRS` entries (e.g. `node_modules`). Run tests, verify it fails.\n\n**Green:** Make `EXCLUDE_DIRS` pub, merge built-in excludes into the git add command in `git_checkpoint()`. Run tests, verify it passes.\n\n### Final verification\n\n1. `cargo test -p fabro-workflows`\n2. `cargo clippy --workspace -- -D warnings`\n3. `cargo fmt --check --all`\n", + "graph.model_stylesheet": "\n * { backend: api; model: claude-opus-4-6;}\n ", + "failure_signature": "", + "command.stderr": "", + "internal.fidelity": "compact", + "internal.run_id": "01KKSVA835XYTBYE18QJ9TWGKX", + "thread.start.current_node": "toolchain", + "internal.node_visit_count": 1, + "outcome": "success", + "graph.rankdir": "LR", + "current.preamble": "Goal: # Plan: Add safeguards to asset collection and checkpoint commits\n\n## Context\n\nComparing our snapshot safeguards to Codex's ghost commits revealed gaps:\n- Asset collection has no file count limit — a run matching thousands of small files will collect them all\n- Asset collection excludes fewer directories than Codex (missing Python venvs, build dirs, caches)\n- Checkpoint commits have no built-in exclude defaults — a fresh run with no config runs `git add -A` on everything that isn't gitignored\n\n## Changes\n\n### 1. Add MAX_FILE_COUNT to asset collection\n\n**File:** `lib/crates/fabro-workflows/src/asset_snapshot.rs`\n\nAdd constant:\n```rust\nconst MAX_FILE_COUNT: usize = 100;\n```\n\nIn `select_files_to_collect()` (line 195), add count check alongside existing size budget check:\n```rust\nif selected.len() >= MAX_FILE_COUNT {\n break;\n}\n```\n\nUpdate existing test `select_files_enforces_total_budget` to verify the count limit doesn't interfere, and add a new test `select_files_enforces_count_limit`.\n\n### 2. Expand EXCLUDE_DIRS for asset collection\n\n**File:** `lib/crates/fabro-workflows/src/asset_snapshot.rs`\n\nAdd missing directories from Codex's list. Current:\n```rust\nconst EXCLUDE_DIRS: &[&str] = &[\n \".git\", \"node_modules\", \".pnpm-store\", \".npm\",\n \"target\", \".next\", \"__pycache__\",\n];\n```\n\nNew (adding 7 entries):\n```rust\nconst EXCLUDE_DIRS: &[&str] = &[\n \".git\", \"node_modules\", \".pnpm-store\", \".npm\",\n \"target\", \".next\", \"__pycache__\",\n \".venv\", \"venv\", \".cache\", \".tox\",\n \".pytest_cache\", \".mypy_cache\", \"dist\",\n];\n```\n\nRationale for each addition:\n- `.venv`, `venv` — Python virtual environments (thousands of files)\n- `.cache` — generic cache dir (pip, pre-commit, etc.)\n- `.tox` — Python tox testing tool virtualenvs\n- `.pytest_cache`, `.mypy_cache` — Python tool caches\n- `dist` — JS/TS build output\n\nNot adding `build` or `env`/`.env` from Codex — `build` is too generic (many projects have legitimate `build/` dirs with test outputs), and `env`/`.env` could be dotenv config files.\n\n### 3. Apply built-in excludes to checkpoint commits\n\n**File:** `lib/crates/fabro-workflows/src/asset_snapshot.rs`\n\nExtract `EXCLUDE_DIRS` into a public constant so it can be shared:\n```rust\npub const EXCLUDE_DIRS: &[&str] = &[ ... ];\n```\n\n**File:** `lib/crates/fabro-workflows/src/engine.rs`\n\nIn `git_checkpoint()`, always include `EXCLUDE_DIRS` as pathspec excludes, merged with user-configured `exclude_globs`. Convert each `EXCLUDE_DIRS` entry to `**/dirname/**` glob format for git pathspec compatibility.\n\nChange at line ~550:\n```rust\nlet mut all_excludes: Vec = asset_snapshot::EXCLUDE_DIRS\n .iter()\n .map(|d| format!(\"**/{d}/**\"))\n .collect();\nall_excludes.extend(exclude_globs.iter().cloned());\nall_excludes.sort();\nall_excludes.dedup();\n\nlet add_cmd = if all_excludes.is_empty() {\n format!(\"{GIT_REMOTE} add -A\")\n} else {\n let pathspecs: Vec = all_excludes\n .iter()\n .map(|g| format!(\"':(glob,exclude){g}'\"))\n .collect();\n format!(\"{GIT_REMOTE} add -A -- . {}\", pathspecs.join(\" \"))\n};\n```\n\nThis means checkpoint commits will always exclude the same directories as asset collection, plus any user-configured globs. The `add_cmd` branch for empty excludes becomes unreachable but can stay for clarity.\n\n## Files to modify\n\n1. `lib/crates/fabro-workflows/src/asset_snapshot.rs` — add MAX_FILE_COUNT, expand EXCLUDE_DIRS, make EXCLUDE_DIRS pub\n2. `lib/crates/fabro-workflows/src/engine.rs` — merge built-in excludes into checkpoint git add\n\n## Approach: Red/Green TDD\n\nFor each change, write the failing test first, then make it pass.\n\n### Step 1: MAX_FILE_COUNT (asset collection)\n\n**Red:** Add test `select_files_enforces_count_limit` in `asset_snapshot.rs` — create 150 small, recent files and assert `select_files_to_collect` returns at most 100. Run tests, verify it fails.\n\n**Green:** Add `const MAX_FILE_COUNT: usize = 100;` and the count check in `select_files_to_collect()`. Run tests, verify it passes.\n\n### Step 2: Expanded EXCLUDE_DIRS (asset collection)\n\n**Red:** Add test `build_find_command_excludes_venv` that asserts the find command contains `.venv` in the prune clause. Run tests, verify it fails.\n\n**Green:** Add the 7 new entries to `EXCLUDE_DIRS`. Run tests, verify it passes.\n\n### Step 3: Built-in excludes for checkpoint commits\n\n**Red:** Add test in `engine.rs` (or appropriate test module) that calls `git_checkpoint` with empty `exclude_globs` and asserts the `git add` command includes pathspec excludes for `EXCLUDE_DIRS` entries (e.g. `node_modules`). Run tests, verify it fails.\n\n**Green:** Make `EXCLUDE_DIRS` pub, merge built-in excludes into the git add command in `git_checkpoint()`. Run tests, verify it passes.\n\n### Final verification\n\n1. `cargo test -p fabro-workflows`\n2. `cargo clippy --workspace -- -D warnings`\n3. `cargo fmt --check --all`\n\n", + "internal.retry_count.toolchain": 1, + "failure_class": "", + "internal.thread_id": "start", + "internal.retry_count.start": 1, + "command.output": "cargo 1.94.0 (85eff7c80 2026-01-15)\n", + "current_node": "toolchain" + }, + "logs": [], + "node_outcomes": { + "start": { + "status": "success", + "duration_ms": 0 + }, + "toolchain": { + "status": "success", + "context_updates": { + "command.output": "cargo 1.94.0 (85eff7c80 2026-01-15)\n", + "command.stderr": "" + }, + "notes": "Script completed: command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", + "duration_ms": 74 + } + }, + "next_node_id": "preflight_compile", + "node_visits": { + "start": 1, + "toolchain": 1 + } +} \ No newline at end of file diff --git a/nodes/start/status.json b/nodes/start/status.json new file mode 100644 index 000000000..35677f372 --- /dev/null +++ b/nodes/start/status.json @@ -0,0 +1,6 @@ +{ + "status": "success", + "notes": null, + "failure_reason": null, + "timestamp": "2026-03-15T22:54:25.810794+00:00" +} \ No newline at end of file diff --git a/nodes/toolchain/script_invocation.json b/nodes/toolchain/script_invocation.json new file mode 100644 index 000000000..d68c414c4 --- /dev/null +++ b/nodes/toolchain/script_invocation.json @@ -0,0 +1,5 @@ +{ + "command": "command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", + "language": "shell", + "timeout_ms": null +} \ No newline at end of file diff --git a/nodes/toolchain/script_timing.json b/nodes/toolchain/script_timing.json new file mode 100644 index 000000000..3aab3a577 --- /dev/null +++ b/nodes/toolchain/script_timing.json @@ -0,0 +1,5 @@ +{ + "duration_ms": 74, + "exit_code": 0, + "timed_out": false +} \ No newline at end of file diff --git a/nodes/toolchain/status.json b/nodes/toolchain/status.json new file mode 100644 index 000000000..bfaa66c9a --- /dev/null +++ b/nodes/toolchain/status.json @@ -0,0 +1,6 @@ +{ + "status": "success", + "notes": "Script completed: command -v cargo >/dev/null || { curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && sudo ln -sf $HOME/.cargo/bin/* /usr/local/bin/; }; cargo --version 2>&1", + "failure_reason": null, + "timestamp": "2026-03-15T22:54:25.895120+00:00" +} \ No newline at end of file