Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .claude/skills/map-efficient/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ BOUNDED_MAP_CONTEXT=$(python3 .map/scripts/map_step_runner.py build_context_bloc

Then substitute `$BOUNDED_MAP_CONTEXT` into the Actor prompt below.

**Worktree isolation (opt-in, `worktree.isolation: true`):** when enabled, create the subtask's isolated git worktree before this dispatch and run the Actor inside it (dispatched WITHOUT harness-native isolation); the default disabled path is unchanged. Full recipe — commands, guard handling, Actor path instruction — in [efficient-reference.md](efficient-reference.md#worktree-isolation).

```text
Task(
subagent_type="actor",
Expand Down Expand Up @@ -370,6 +372,11 @@ Return JSON with valid, summary, issues, files_changed, tests_run, and escalatio
Full recipe + "when NOT to commit" cases live in
[efficient-reference.md](efficient-reference.md). Never `--no-verify`,
never amend a published commit.
- **Worktree isolation (`worktree.isolation: true`):** accept via
`merge_subtask_worktree "$SUBTASK_ID"` instead of `git commit` (pre-merge
verify + squash ONE commit; use its `merged_sha` for `--commit-sha`). On its
`status:"error"` (treat the `kind` as a Monitor-class failure → discard +
retry) or `no_changes:true`, follow [efficient-reference.md](efficient-reference.md#worktree-isolation); do not record the subtask.
- **Record the subtask result (REQUIRED on clean pass):**
```bash
python3 .map/scripts/map_orchestrator.py record_subtask_result "$SUBTASK_ID" valid \
Expand All @@ -389,7 +396,7 @@ Return JSON with valid, summary, issues, files_changed, tests_run, and escalatio
`refresh_blueprint_affected_files "$BRANCH" "$SUBTASK_ID"`; default mode
merges observed files into the approved surface. Use `--replace` only for
intentional contract rewrite; see [efficient-reference.md](efficient-reference.md).
- If `valid=false`, write `code-review-N.md`, run `python3 .map/scripts/map_orchestrator.py monitor_failed --feedback "<feedback>"`, inspect `retry_isolation`, and invoke Predictor only when stuck/high-risk escalation rules apply. **If `monitor_failed` returns `status:"max_retries"` (budget exhausted), do NOT retry — run `python3 .map/scripts/map_step_runner.py build_escalation_outcome "$SUBTASK_ID" max_retries --retry-count <retry_count> --max-retries <max_retries>` and STOP with its `outcome` (surface the blocker to the user).**
- If `valid=false`, write `code-review-N.md`, run `python3 .map/scripts/map_orchestrator.py monitor_failed --feedback "<feedback>"`, inspect `retry_isolation`, and invoke Predictor only when stuck/high-risk escalation rules apply. **Worktree isolation:** if enabled, run `discard_subtask_worktree "$SUBTASK_ID"` BEFORE retrying (atomic reject — a failed attempt is never merged; retry starts from a clean worktree). Recipe: [efficient-reference.md](efficient-reference.md#worktree-isolation). **If `monitor_failed` returns `status:"max_retries"` (budget exhausted), do NOT retry — run `python3 .map/scripts/map_step_runner.py build_escalation_outcome "$SUBTASK_ID" max_retries --retry-count <retry_count> --max-retries <max_retries>` and STOP with its `outcome` (surface the blocker to the user).**
- **Intra-run failure memory + bounded-effort escalation (MANDATORY on every `valid=false`):** record the rejection with `python3 .map/scripts/map_step_runner.py record_failure_signature "<monitor feedback>" "$SUBTASK_ID"`. If `armed:true`, prepend the block from `build_anti_repeat_constraint "$SUBTASK_ID"` (add `--quarantine-active` when CLEAN_RETRY is set) to the TOP of the next Actor prompt. If `escalation_recommended:true` (#255), the 3rd identical failure means the bounded recovery act did not work — do NOT retry and do NOT run the legacy retry-3 Stuck-Recovery for this identical loop; run `python3 .map/scripts/map_step_runner.py build_escalation_outcome "$SUBTASK_ID" repeated_failure` (add `--quarantine-active` on a CLEAN_RETRY iteration) and STOP with its `outcome:"BLOCKED"`. A `status:"not_escalated"` means the latest failure was a NEW signature (the Actor moved off the dead end) — resume normal retries. Full recipe: [efficient-reference.md](efficient-reference.md).
- If `retry_isolation=clean_retry_required`, validate `.map/<branch>/retry_quarantine.json` before CLEAN_RETRY. If a test/check fails inconsistently, collect repeated evidence with `run_flaky_test_triage ...` (or manually with `record_flaky_test_triage ...` if already collected), validate `.map/<branch>/flaky_test_triage.json`, then close via `python3 .map/scripts/map_orchestrator.py defer_flaky_subtask "$SUBTASK_ID" --check-id "<check-id>"`; this is not a passing gate and must not weaken/skip/delete the check. Full recipe: [efficient-reference.md](efficient-reference.md).
- Treat test failures after Monitor approval as Monitor failure. **Cross-subtask regression gate (MANDATORY):** before the test gate, run `python3 .map/scripts/map_step_runner.py detect_cross_subtask_regression_risk "$BRANCH" "$SUBTASK_ID"`; if `recommended_gate == "full_suite"` you MUST run the FULL suite (never a `-k` subset) before commit / `record_subtask_result` — per-subtask Monitor is blind to regressions on prior subtasks' code. Recipe: [efficient-reference.md](efficient-reference.md).
Expand Down
59 changes: 59 additions & 0 deletions .claude/skills/map-efficient/efficient-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,65 @@ When to call:
commit section above — covers reality lock for the just-completed
subtask).

## Worktree isolation

Per-subtask git worktree isolation (#284) is **opt-in, off by default**. Enable
with `worktree.isolation: true` in `.map/config.yaml` (`worktree.max_deletions: N`
caps the bulk-deletion guard, 0 = off). When enabled, each subtask's Actor runs
in a dedicated throwaway git worktree (stored out of the working tree under the
repo's `.git` common dir); the result is squash-merged back into the working
branch ONLY after the configured `verification_checks` pass IN the worktree
(pre-merge gate), and a rejected attempt is discarded so the working branch is
never touched. The step runner owns the lifecycle + every safety guard
(council-reviewed). Dispatch the Actor Task WITHOUT `isolation="worktree"` — the
runner owns isolation; the two mechanisms must never both be active.

**Before ACTOR — create the worktree (no-ops when disabled):**

```bash
WT_JSON=$(python3 .map/scripts/map_step_runner.py create_subtask_worktree "$SUBTASK_ID")
WT_STATUS=$(printf '%s' "$WT_JSON" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("status",""))')
WT_PATH=""
if [ "$WT_STATUS" = "success" ]; then
WT_PATH=$(printf '%s' "$WT_JSON" | python3 -c 'import sys,json; print(json.load(sys.stdin).get("worktree_path",""))')
fi
```

`status:"disabled"` (exit 0) → flag off, proceed normally. `status:"error"` →
STOP and surface the structured `kind`/`message` (`DIRTY_MAIN`, `PROTECTED_REF`,
`NESTED_WORKTREE`, `ACTIVE_GIT_OP`, `INVALID_SUBTASK_ID`, …); fix the cause, do
NOT silently fall back to the shared tree. When `WT_PATH` is non-empty, append to
the Actor task prompt: *"All edits and test runs for this subtask MUST happen
inside the git worktree at `$WT_PATH` — never edit the main checkout, and never
run git fetch/pull/push from the worktree."*

**Accept (after a clean Monitor + Evaluator pass)** — replaces the per-subtask
`git commit`:

```bash
python3 .map/scripts/map_step_runner.py merge_subtask_worktree "$SUBTASK_ID"
```

It commits the Actor's worktree work, runs `verification_checks` in the worktree
(pre-merge gate), then `git merge --squash` + one runner-authored commit (never
`--no-ff`; the squash commit IS this subtask's commit — pass its `merged_sha` to
`record_subtask_result --commit-sha`) and removes the worktree. Guard failures
return `status:"error"` with a `kind` and leave the working branch untouched:
`VERIFY_FAILED`, `MERGE_CONFLICT`, `BULK_DELETION`, `RUNTIME_STATE_IN_DIFF`,
`BASE_DIVERGED`, `SUBMODULE_CHANGED`, `WORKTREE_HEAD_MOVED` → discard + retry. A
`no_changes:true` success means the Actor edited the main checkout instead of the
worktree — surface it and do NOT record the subtask.

**Reject (Monitor `valid=false` / Evaluator fail)** — atomic discard before retry:

```bash
python3 .map/scripts/map_step_runner.py discard_subtask_worktree "$SUBTASK_ID" --save-patch
```

`--save-patch` keeps the rejected diff under `.map/<branch>/worktree_attempts/`.
The retry creates a fresh worktree off the current HEAD. Inspect state any time
with `worktree_isolation_status`.

## Troubleshooting

- Blueprint validation fails: fix the decomposer output before Actor starts.
Expand Down
Loading
Loading