condukt
v0.7.174v0.7.165 (integrated; branch-local label was v0.7.161): autonomy becomes ONE switch that condukt, ctxrot and autoflow all read DIRECTLY (harness_core::autonomy) instead of three per-crate signals that could not agree. `state autonomy-set on|off` writes a durable `<$HARNESS_AUTONOMY_DIR or ~/.harness/autonomy>/<project-key>.json` atomically, keyed by the repo's MAIN worktree root (projkey::main_worktree_root) so a switch set in the main tree is visible from every linked worktree -- a switch a worker under CLAUDE.md section 8 cannot see is not a switch. `Config::load` layers that file BETWEEN config.toml and the env, so `CONDUKT_AUTONOMOUS=0` still beats a switch left on. Fail-closed and NOT silent (sections 1/3): an ABSENT file is a determinate 'never set' (off, source `default`, stderr silent), while a file that EXISTS but cannot be read/parsed is Undetermined -- off, source `undetermined-switch-file`, and a stderr warning naming the path, so broken and never-set are never byte-identical. Plain `state autonomy-check` stdout is untouched (`{"autonomous":<bool>}`, exit 0/1; the frozen oracle autonomy_invariant.rs stays 16/16 green and byte-unmodified); the deciding layer is reported only by the new `--explain` flag and by `state autonomy-path`. v0.7.151 integrates this line with the remote's. From this line: `enforce_edit_gate` no longer resolves a malformed verdict to `Allow` — the `required` / `fallback` / `broken` fields are read three-valued and any one of them being unreadable is 判定不能, which resolves to `Reject` (CLAUDE.md 3); and `worktree reconcile`'s DEATH rule third clause moved off the cwd-dependent transcript slug onto the session registry. v0.7.144 integrates this machine's line. `worktree::remove` no longer force-discards uncommitted work: both `Known(true)` and `Undetermined` now bail and leave the directory on disk, and the test that had pinned the permissive behaviour as correct (`worktree_remove_force_removes_dirty_worktree`, asserting verbatim that a "dirty worktree should be force-removed") was replaced rather than kept green. A disinterested agent observed the RED first and a third agent's mutation killed 3/3. v0.7.143: v0.7.141 のスケジューラ側並列上限 (schedule のバッチ幅分割 / Config::load の clamp / consensus / adversarial) を revert し、強制を parallelguard (PreToolUse で in-flight を数えて deny) へ移した。あわせて origin/main を統合し、3rd taintguard trigger を撤去した v0.7.140 を取り込む — `condukt lessons record-retrieval` は `taintguard::state::mark` を呼ばず、`taintguard` path 依存も無い (crates/condukt/src/main.rs:2174 に理由のコメントだけが残る)。これは封じ込めの REMOVAL であって移設ではない: cross-project lesson injection は untrusted provenance として追跡されず、その後に write 系ツールを downgrade する gate も無い。`tests/lessons_taint_trigger.rs` は固定していた挙動ごと削除済み。 v0.7.141: 1 セッションの同時実行を 3 に上限化。max_parallel は doc 上「advisory」で実際には誰も強制しておらず、schedule はバッチ幅を切らないまま 5 タスクを 1 バッチ 5 並列にしていた。schedule_capped がバッチを cap で分割し (切るだけでタスクは落とさない partition)、Config::load が harness_core::parallel::cap_fanout で clamp するので config.toml も CONDUKT_MAX_PARALLEL も下げられるが上げられない。consensus samples と adversarial panel の上限 5 も同じ cap に従う (floor 2 は維持 = 1 サンプルの合議は測っていない同意を報告する fail-open なので cap より優先)。 v0.7.117: wires the 3rd taintguard trigger — "this turn consumed cross-project lessons" — into `condukt lessons record-retrieval`. On the same non-empty-hit condition the existing retrieval-ledger `hit` flag already uses, the handler now calls `taintguard::state::mark(&cwd, &run, "lessons")` (new `taintguard` path dependency, mirroring the existing `blastguard`/`overwatch` deps; taintguard itself is unchanged), tainting the session so taintguard's PreToolUse `gate` downgrades write-class tools for the rest of the turn — mirroring the existing web/external-read triggers. A zero-hit search stays a no-op (preserves the empty `lessons_context: []` contract); a failed `mark` is `eprintln!`'d and does not fail the command. New `tests/lessons_taint_trigger.rs` confirms RED (no taint) with the mark call disabled and GREEN once wired, plus an anti-vacuity zero-hit case and a regression on the unchanged retrieval-ledger/lessons_context shape. v0.7.113: PROGRESS-not-liveness gate on the cross-session claim reap (mirrors backlog's lock-reap fix) — `claim::reap` no longer evicts a heartbeat-stale claim on heartbeat-age alone (the fail-open that force-steals a live-but-quiet run: fresh commits / growing transcript / advancing tasks, heartbeat merely lapsed). A stale claim is now reaped ONLY when its owning run's PROGRESS is confirmed `Known(Stalled)` by the reusable `harness_core::progress` engine — git HEAD + the owning session's transcript + the run's max task `updated_at` frozen across the multi-sample window (default 90s, `HARNESS_PROGRESS_WINDOW_SECS`). Progressing OR Undetermined (unreadable signal / no prior sample / window not elapsed) NEVER reap (fail-closed). The run-progress signal is deliberately max(task.updated_at), NOT the run-state file mtime (heartbeats rewrite that file = liveness, not progress). All five reap call sites (claim_files/claim_tasks/heartbeat/active_claims/write_execution_state) thread the same progress probe. New `condukt state probe --run RID [--json]` reports, per RUNNING task, the durable signals, `last_progress_age_secs`, and the three-valued verdict — the observability twin sampling the same engine. Tests: the two stale-reap unit tests now encode the tighter contract (reap requires a forced `Known(Stalled)` via a `#[cfg(test)]` thread-local seam, compiled out of production); new protective tests pin the fail-closed half (Progressing / Undetermined ⇒ NOT reaped) observed RED against the old ungated reap; docstrings updated in the same commit. v0.7.109: closed an F→P oracle fail-open (backlog 22b69f6a) — `oracle::check_oracle`'s top-of-function exemption used to fire on `!requires_oracle || reproduction_tests.is_none()`, so a fix/feature task (`requires_oracle:true`) that simply did not DECLARE `reproduction_tests` was exempted from the Fail→Pass gate even when real tdd RED→GREEN proofs existed for it. Narrowed the guard to `!requires_oracle` alone: a fix/feature task is now ALWAYS consulted against `tdd` regardless of whether it declared `reproduction_tests` (missing declarations degrade to the tdd `unknown`/spawn-Err paths, never a free pass). The `reproduction_tests` param is retained for call-site signature stability (renamed `_reproduction_tests`) but is no longer a gate switch; the doc comment and the exempt `reason` string (`"not a fix/feature task"`, no longer `"or no reproduction_tests"`) were updated in the same commit to match. The tdd-spawn and spawn-Err (`"a missing checker is not a passing checker"`) branches are unchanged. v0.7.108: added a must-ask-human / untestable clamp to the graded-autonomy policy (backlog 903a0d28) — new `policy::decide_untestable(risk, reversibility, confidence)` mirrors `decide_conflict_resolution`: it calls `decide` and clamps an `Auto` verdict up to `Escalate`, passing `Escalate`/`Block` through unchanged (pure, total, no opt-in path back to Auto), so CLAUDE.md §2's "if a thing cannot be meaningfully tested, ask the human" gate can never be auto-self-answered. Wired a `--untestable` bool flag into both `policy decide` and `policy answer` (mirrors `--conflict`); when set, the verdict is computed by `decide_untestable`, so an otherwise-`auto` untestable decision falls through to a real AskUserQuestion (exit 2, `{"answered":false,"policy":"escalate"}`, never journaled). `--untestable` takes precedence over `--conflict` (both clamp Auto→Escalate identically). Everything downstream (exit codes, escalate/auto JSON, journal) is unchanged. v0.7.107: the GHA removal landed across two commits (the second re-touched condukt src, so the bump-on-change gate required a second micro bump); functionally identical to v0.7.106. v0.7.106: removed the GitHub-Actions-CI-status-consuming code (GHA is banned repo-wide, CLAUDE.md; its workflow files are already gone) — deleted `src/ci.rs` entirely (the `gh pr checks`/`gh run list --json` output parser plus `CiConclusion`/`CiVerdict` state machine that existed solely to consume GHA CI conclusions) and removed the `condukt pr poll` subcommand from `main.rs` (its `PrAction::Poll` variant, handler, and the merge-only-when-CI-green flow), since that subcommand's entire purpose was gated on GHA CI state. Kept `src/pr.rs` and `condukt pr create` (`gh pr create` with no CI-conclusion gating — general PR creation, independent of GHA). Also gutted `scripts/test_prepush_hook.py`'s now-stale chronic-red-CI test suite (the check it tested was already removed from `.githooks/pre-push`) and replaced it with coverage for the hook's surviving checks (gate-bypass block, rollout advisory). v0.7.104: `record_runs` now emits a SECOND fugu-router episode with `role=verifier` alongside the existing worker episode, whenever a task carried `state set --verifier-model` (reusing the same title/files/class/done_criteria/status; resolving cost/tokens via `--verifier-agent-id` through the same `resolve_agent_cost`/`resolve_agent_tokens` exact-match path the worker episode already used). Builds on the just-merged verifier_model/verifier_cost_usd/verifier_agent_id fields on TaskState/RecordSpec/`state set` (v0.7.103) toward hypothesis f5f9522a. `fugu-router record --role` and `Episode.role` already existed and needed no change. New e2e test `record_run_emits_worker_and_verifier_episodes_when_verifier_model_set` asserts exactly 2 episodes (worker+verifier) for a task with a verifier model and exactly 1 (worker only) for a task without one. v0.7.101: `.githooks/pre-merge-commit` resolved its own dir with `$(dirname "$0")`; a git hook's PATH is whatever invoked git, and on macos-14 CI that dir carries no coreutils, so `dirname` was not found, the substitution collapsed to empty, and the hook exec'd "/pre-commit" (nonexistent) — dying 126 and BLOCKING the very §8 integration merges it must permit (observed: build-binaries smoke macos-14 FAIL on `a_clean_no_ff_merge_completes_in_the_primary_tree_with_a_peer_live`; ubuntu-latest + local passed only because their git dir happens to also carry coreutils). Replaced with POSIX parameter expansion (`${0%/*}` behind a `*/*` case guard), a shell builtin needing nothing on PATH. New host-independent regression `the_merge_hook_reaches_pre_commit_with_no_coreutils_on_path` runs the real hook under a PATH of one empty dir (no coreutils on ANY host) — observed RED on the old hook, GREEN on the new, closing the host-dependent-oracle gap that let a macos-only break pass ubuntu+local CI. v0.7.100: fixed a PATH-env test race (backlog b0db2bff) — `oracle.rs` had its own module-local `ORACLE_PATH_ENV_LOCK` serializing only its own PATH-mutating tests; `main.rs`'s `flag_supplied_but_probe_unusable_falls_back` mutated PATH without taking any lock, and tests that spawn real `git` (e.g. `repo_commit::tests::first_unstaged_modification_is_not_misread_as_staged`, via `worktree::git`) took no lock at all, so a concurrent PATH mutation could transiently break their git spawn. Reproduced empirically: 3/15 full-suite runs under 16 test threads flaked before the fix (2 distinct real failures). New shared `env_lock::PATH_ENV_LOCK` (`RwLock<()>`, not a `Mutex`) — PATH mutators (oracle.rs, main.rs) take the write side; `worktree::run_git_bounded_with` (the single git-spawn choke point used by every git-shelling test in the crate) takes the read side, so concurrent git spawns don't serialize against each other but always exclude a mutation window. 20/20 repeats of the same repro loop green after the fix; full `cargo test -p condukt` suite green x3; fmt/clippy clean. v0.7.99: fixed `state::all_runs`/`active_worktree_for_path` misparsing non-RunState sidecars in the per-project state dir as corrupt run states (backlog 1af91627). Only `<run_id>.decomposition.json` was excluded; `<run_id>.checkpoints.json` (checkpoint history) and the bare `claims.json` (cross-run claim registry) were fed to `serde_json::from_str::<RunState>` and logged as "unparseable run state" — reproduced live via `condukt state record-run --all` (8 `.checkpoints.json` + 1 `claims.json` = 9 spurious warnings). Grepped the file for every other bare-filename sidecar sharing the same directory (`precedents.json`, `escalations.json`, `execution-state.json`) and excluded those too via a new shared `is_run_state_sidecar()` helper used by both functions, rather than patching just the 2 observed symptoms. New regression test `all_runs_skips_all_known_sidecars_without_warning` fixtures one valid RunState plus all 6 known sidecar shapes and asserts `all_runs` returns exactly the one valid run. v0.7.98: internal-only refactor — `verify::checks_verdict`'s computation now routes through `harness_core::verdict::{Determination, Verdict}` (an empty results slice becomes `Determination::Undetermined`, a non-empty slice becomes `Determination::Known` with per-index failure reasons, adjudicated via `Verdict::adjudicate`), then translates back to `ChecksVerdict` at the return boundary. `ChecksVerdict`/`CheckReport`'s public shape and `Serialize`/`Deserialize` derives are unchanged (a `Verdict` can never derive `Deserialize` — see harness-core's `Evidence` witness — so `ChecksVerdict` stays its own serializable shadow type). All pre-existing checks-verdict tests pass unmodified. Skipped the optional per-check-failure-reason threading (naming which check failed): `checks_verdict` is directly tested with bare `&[bool]` literals, so giving it access to `check.cmd` would mean either breaking that tested signature or duplicating logic between it and `run_checks` — both out of scope for an internal-only refactor. v0.7.96: `adversarial.rs`'s local `GATE_CRATES` const is now `pub use harness_core::fleet::GATE_CRATES;`, removing a duplicate hand-written copy that had independently drifted (lost `overwatch`) in the past; type changes from `[&str; 6]` to `&[&str]` but the sole call site (`.iter().any(...)`) is unaffected. v0.7.95: fixed a real fail-closed-refusal bug in `repo commit` found live while committing an unrelated blastguard fix — `worktree::git`'s shared output formatter used to `.trim()` the WHOLE stdout blob of every git invocation, not just its trailing newline. `git status --porcelain`'s first line for an unstaged modification is ` M path` (a leading space that is the semantically meaningful 'not staged' status column, not incidental whitespace); because that space sat at byte 0 of the whole blob, the blanket `.trim()` ate it, corrupting only the FIRST line. `repo_commit::staged_paths` then read the corrupted line's first byte as the file-status char (neither `' '` nor `'?'`) and wrongly reported an ordinary unstaged edit as already-staged foreign content, and its `path[3..]` slice (meant to skip the 2-char status + 1 space) then cut one byte too many off the path itself (observed live as `.claude-plugin/marketplace.json` reported as `claude-plugin/marketplace.json`, missing its leading dot). This made `condukt repo commit` refuse to commit ANY task whose first `git status --porcelain` entry happened to be a plain unstaged modification — a correct implementation blocking legitimate commits, not a fail-open. Fixed by changing the shared formatter to `.trim_end()` (strips only the trailing newline git always appends; every other git-output consumer in this crate already re-trims per-line or never depended on leading whitespace). New regression test `repo_commit::tests::first_unstaged_modification_is_not_misread_as_staged` reproduces the exact incident shape (a real temp repo, a dotfile path, an unstaged edit as the first entry), confirmed RED before the fix and GREEN after; full `cargo test -p condukt` suite (721 tests) still green. v0.7.87: cargo fmt --all reformatting only (fixes the 'build & commit plugin binaries' smoke workflow's `cargo fmt --all --check` gate, chronically red on main since 2026-07-21 per scripts/check-ci-red.py); no behavior change. v0.7.75: fix the runtime-conflict cleanup gap (design 625aa170 finding #1) — a task's branch landing now marks its `ActualChangeset` merged via a new `worktree::finalize_landed_branch` (calling overwatch's branch-keyed `store::mark_branch_merged`, the only key the merge path has) wired into BOTH `merge()`'s clean-merge path AND `resolve_merge()`'s reconciled outcomes, so a cleanly-landed task no longer leaves `merged=false` within the lease TTL and spuriously HOLDS the next sequential task that touches a common file; the same cleanup clears any stale `RuntimeOverlap` hold recorded against the landed branch name (defensive against a reused `condukt/<id>` branch) and opportunistically prunes the cross-run changeset registry so it stays bounded. Also fixes the broken `run_pr` Poll remediation hint (`condukt worktree resolve-merge --branch <b>` → the correct `--id <id>` form that `ResolveMerge` actually accepts). New regression tests pin the pre-merge hold gate (an open RuntimeOverlap HOLDs the merge) and the landed-peer cleanup (a merged peer is excluded from detection, so no spurious hold). v0.7.71: `schedule()` now warns (does not reject) when a task's `touched_files` entry looks like an absolute path (`/`-rooted or a Windows drive letter) or contains a `..` traversal component — such entries silently defeat the string-based conflict-detection heuristics documented as `normalize_entry`'s deliberate repo-relative-only scope, so two tasks that actually touch the same file via a non-conventional path could previously be scheduled in parallel with no warning at all. Warn (not reject) was chosen because `schedule()` is the decomposition-wide deterministic gate and a hard error there would stop the whole run over what is usually a false-positive-prone heuristic, not a certain conflict. Also adds a real end-to-end capstone test (`schedule_conflict_capstone_e2e.rs`) driving `schedule()` itself with a genuinely-overlapping pair, a pair that only collides after `normalize_entry`'s `./`/`//` normalization (v0.7.69's fix), and a genuinely-independent pair — asserting the first two are forced serial and the third is left parallel, plus a simulated concurrent-write check that no pair loses data. Also adds `fugu_router_record_e2e.rs`, confirming the v0.7.66 `suggested_model`/`route_basis`/`tokens_input`/`tokens_output` wiring (already implemented in code) actually lands those fields in a real `episodes.jsonl` end-to-end — the 0/537-tokens gap seen in production data traced to the live deployed condukt binary lagging behind source, not a code defect. v0.7.70: `schedule::entries_conflict` now normalizes each touched-file entry (strip a leading `./`, collapse repeated `/`) before comparing, closing a false-negative gap where two different spellings of the identical path (e.g. `./src/a.rs` vs `src/a.rs`, or `src//a.rs` vs `src/a.rs`) went undetected as a conflict and could schedule two workers onto the same file in parallel. Audited for false positives too: confirmed (and pinned with a regression test) that disjoint globs sharing only a parent directory (`src/foo/*.rs` vs `src/bar/*.rs`) do NOT over-serialize, and that the literal-prefix-nesting heuristic's known conservative-but-safe over-approximation (e.g. `src/*.rs` vs `src/sub/*.rs`) is unchanged and intentional per this module's own "conservative: false conflict only serializes work (safe)" principle. v0.7.68: `orphans()` (worktree.rs) no longer misreports another repo's live worktree as condukt debris when `worktree_base` is shared across multiple, unrelated git repositories on the same machine — a candidate directory is now only flagged as an orphan if its `.git` (file pointer for a linked worktree, or dir for a plain clone) actually resolves under `repo`'s own `.git` common dir AND isn't in `repo`'s registered worktree list; a directory owned by a different repo is silently skipped, while a directory with no `.git` at all is still conservatively treated as orphan (unchanged). New regression tests `orphans_ignores_other_repos_worktree` and `orphans_detects_stale_worktree_of_own_repo` cover the new behavior and the real-world stale-worktree case this fix must not regress. v0.7.67: `record_runs` now checks the actual exit status of the `fugu-router record` subprocess instead of only catching a spawn `Err`, so a non-zero exit (e.g. a stale PATH-shadowed `fugu-router` binary rejecting a flag) is no longer silently counted as a successful record; also resolves `fugu-router`'s binary path via `~/.claude/plugins/installed_plugins.json`'s plugin-cache `installPath` first, falling back to the bare command name only if resolution fails, so a stale `~/.cargo/bin/fugu-router` can no longer shadow the correct plugin-installed version. v0.7.66: `TaskState`/`state set` gain measurement-only `route_basis`/`route_confidence`/`route_rationale` (the routing `Decision`'s provenance from `route.json`) and `lines_added`/`lines_removed` (measured `git diff --stat` insertions/deletions), plus a new `state::resolve_agent_tokens` (mirrors `resolve_agent_cost`, exact agent-id match against `gauge subagents --json`'s new `tokens_input`/`tokens_output`); `record_runs` threads all of these through to `fugu-router record`'s matching new flags so routing decisions and task cost/size can be retrospectively correlated against actual pass/fail outcomes. None of it is consulted by condukt's own scheduling/routing — purely additive, backward-compatible (`#[serde(default, skip_serializing_if)]`). v0.7.63: opt-in **shadow-run** mode — a new `shadow-run enable|disable|status` flag (default: disabled) plus `exec`/`finish` subcommands run the SAME task under a second model in an independent worktree (reusing the existing `worktree create`/`discard` machinery) purely to produce a clean pass/fail/cost/duration comparison point for `fugu-router record --class shadow-run`; the shadow worktree is ALWAYS discarded (force-remove + force-delete branch), never merged. Manual-trigger only by design — no API/hook input exposes remaining rate-limit-window time, so automatic firing is not implemented; pairs with gauge's new `config set-window`/`config show` for a human-registered window approximation. v0.7.62: task-duration measurement — `TaskState` gains `started_at` (set when a task transitions to `running`); `records_for_run` computes `duration_secs` from `(started_at, updated_at)` and `record_runs()` passes it to `fugu-router record --duration`, populating the new measurement-only `Episode.duration_secs` field (routing/scoring logic in fugu-router's `policy.rs` is unchanged). v0.7.61: `verify::mechanical_cmd` now tokenizes command strings (both the interpreter-declared `mechanical_check` hint and the backtick-extracted done_criteria command) via a new quote/escape-aware `parse_argv` (shlex-backed) instead of `split_whitespace`, so a quoted argument containing spaces (e.g. a path) survives as one argv token instead of being split in two; falls back to `split_whitespace` on unparseable (unterminated-quote) input rather than dropping the mechanical check. v0.7.60: `verify::run_check` now gates each declared check command through blastguard's pure detector (same `detect("Bash", ...)` call already used by `launch_and_reflux`) before spawning `sh -c`; a flagged command is refused fail-closed and reported as a non-passing `CheckResult` (exit -1) instead of being executed. New test `run_check_blocks_destructive_command_via_blastguard` proves a `rm -rf /` check never reaches the shell. v0.7.58: audited `lessons.rs`'s `harvest()` (production JSON-facts path) for raw `.unwrap()`/`.expect()` — the production path was already fail-soft (`.ok()`/`.and_then()`/`.unwrap_or()`/`.unwrap_or_default()` throughout, no panics); the flagged `as_str().unwrap()` calls live inside `#[cfg(test)] mod tests` only. Fixed a real (unrelated) flake found while confirming `cargo test -p condukt` green under parallel test execution: `lessons::tests::harvest_facts_drive_idempotent_append_that_search_retrieves` mutates the process-global `LESSONS_STORE_DIR` env var without serializing against `replan.rs`'s tests doing the same, so it now takes its own `ENV_LOCK` mutex around the env-var-mutating critical section (mirrors the existing `replan::tests::ENV_LOCK` precedent). v0.7.57: `worktree.rs`'s git subprocess calls (`git()`/`git_try()`) are now bounded by a 45s timeout (wait_timeout + process-group kill, mirroring propguard::git/autoflow::compass) instead of a plain unbounded `Command::output()`, so a hung `git` (lock contention, stuck credential prompt, network-mounted repo) can no longer wedge a condukt run indefinitely; `create()`'s "worktree must be outside the repo" check now canonicalizes the candidate worktree path (falling back to the nearest existing ancestor when the leaf doesn't exist yet) before comparing against the canonical repo root, closing a TOCTOU-adjacent bypass where a non-canonical `worktree_base` (symlink hop, WSL/DrvFs mount) could look like it resolved outside the repo when it actually didn't. v0.7.56: `verify::tests::skip_eligible_without_command_fails_soft` no longer relies on a `panic!` inside the invariant-violating runner closure to prove it is unreachable — it now records the invocation via a `Cell<bool>` flag, logs via `eprintln!`, and asserts the flag stays false, so an unattended run never aborts on this code path even in a hypothetical regression (production `mechanical_skip_verdict` behavior unchanged: it already refused to invoke the runner and returned a fail-soft `skip_verifier: false` verdict). v0.7.55: docs-only — SKILL.md Phase 7 now documents the `state reconcile` exit 2 (duplicate_completion) escalation branch (specguard spec-audit 2026-07-13 finding); no code/behavior change. v0.7.54: `gate_exec`'s escalate-finding call site follows overwatch's new `ReviewFinding.rationale`/`record_finding` signature (passes `None` — no behavior change, just keeps the call site compiling against the extended API). Deterministic orchestration engine for Claude Code: interpreter/researcher/worker/verifier skill pipeline plus a Rust binary that schedules tasks into parallel/serial batches by file-conflict analysis, manages the git-worktree lifecycle, tracks run state, and gates completion. v0.3: run resume across sessions (state resume-context + Phase 0-alt), stale-run reconcile (state reconcile auto-promotes merged branches to verified), benchmark stats (state stats), baseline test capture (Phase 4.5), pipeline verifier launch (no batch-wait), verifier-skip for mechanical done_criteria, auto-resume when 1 open run. v0.3.1: pause/resume (state pause/resume), paused-run indicator in state list, paused runs excluded from SessionStart notifications. v0.4.0: deterministic fugu-router outcome recording — a Stop hook fires `state record-run --all` (idempotent via per-run recorded_at; soft no-op without fugu-router), and `state set` accepts --model/--cost so recorded outcomes reflect the actual (escalated) model and gauge cost. v0.4.1: fix Phase 6 cost capture — read the session id from CLAUDE_CODE_SESSION_ID (the repo-standard var; CLAUDE_SESSION_ID never existed) and omit --session when unset so gauge falls back to the latest session instead of returning null; requires gauge >= 0.2.0 for `session --json`. v0.4.2: record true per-task cost — Phase 5 tags each worker's Task description with its task id, and Phase 6 reads per-sub-agent cost via `gauge subagents` (>= 0.3.0) matched by that description, instead of a lumped session total that would break fugu-router's cost-per-pass routing. v0.5.0: harden the verifier stage against two shared-blind-spot failures — `state verifier-model` deterministically resolves a verifier model that can never equal the worker model (no more worker==verifier==sonnet when fugu-router is absent), and `state check-criteria` now classifies done_criteria as behavioral vs purely mechanical and emits `skip_verifier`, so only purely mechanical criteria may bypass the LLM verifier; behavioral criteria always run it and a passing test is only evidence, never a substitute. v0.6.0: multi-sample self-consistency voting — a new `consensus` subcommand (`plan` gates an opt-in fan-out via config `[consensus] enabled`/`CONDUKT_CONSENSUS`/per-task `--risk high`; `vote` tallies N verifier verdicts for one task into a deterministic majority winner + agreement rate, escalating to opus on all-fail, a tie, or agreement below threshold). OPT-IN cost guard: OFF by default, small default N=3 clamped to a ceiling of 5. SKILL Phase 5.5 wires the fan-out (N candidate worktrees → verify each → `consensus vote` → winner, else opus redo) without adding any new stop point. v0.7.0: cross-session file-claim registry (PDO collision guard) — `state claim/release/heartbeat/claims` maintain a project-scoped `claims.json` that turns `conflict-check`'s one-time advisory snapshot into a live, enforcing file-level lease, so two condukt sessions on the same machine never process the same work. Enforcement is automatic: `state set --status running` auto-claims the task's touched_files and HARD-SKIPS (exits 1 with a skip JSON naming the live holder) when another live run owns any of them; terminal transitions auto-release; heartbeats keep a busy session's claims alive; stale claims (heartbeat older than the stuck-TTL) are reaped. Liveness is anchored to the heartbeat, not the ephemeral CLI pid. v0.7.1/0.7.2: task-claim lockstep bump / docker-isolated exec backend for verify launch (--docker, fail-soft). v0.7.3: deterministic RUN-POLICY gate — `run-policy decide` maps a cheap-verify result + production-divergence + change-risk to the next verify→docker→ship stage (verify_only|escalate_docker|escalate_ship|ask_human), fail-soft parsing to the safest value on unrecognized input; `run-policy stats` aggregates the decision log. SKILL Phase 6 wires the verdict into the docker-escalation decision for runtime/health done_criteria. v0.7.4: opt-in worker sandboxing — a `sandbox run` subcommand routes a worker's build/test through the docker exec backend with filesystem + resource isolation (`--network=none` reused, plus optional `--memory`/`--cpus`/`--pids-limit`/`--read-only`), gated by config `[worker] sandbox_enabled` / `CONDUKT_WORKER_SANDBOX`; OFF by default (worker keeps host-direct execution), and docker-absent degrades to the existing `docker_unavailable` fail-soft without host fallback. v0.7.7: deterministic in-code RUN-POLICY gate — `verify launch --run-policy` fuses decision and action with no LLM step between them: `verify::run_policy_gate` calls `decide_run_policy` and invokes the container launch ONLY on the `escalate_docker` verdict (other verdicts never launch), recording the chosen verdict to the run-policy JSONL when `--run` is given. Purely additive (existing `verify launch --docker`/`--health-url`/host paths unchanged); docker-absent keeps the `docker_unavailable` fail-soft with no host fallback. SKILL Phase 6 documents it as the canonical way the run→docker escalation is gated LLM-free. v0.7.21: activate `expected_trajectory` — Task gains an optional passthrough `expected_trajectory` field (`{mode, steps:[{tool}]}`), documented in the interpreter schema and SKILL.md Phase 1, and Phase 6 now derives `$EXPECTED_TRAJ`/`$WORKER_TRANSCRIPT` from the task JSON and the worker sub-agent transcript (via the same `gauge subagents` description correlation Phase 6 cost capture uses) so `trajectoryeval extract` → `check` actually fires when a task declares a trajectory. v0.7.24: deterministic replan/escalate decision — `replan::classify_failure` gains an authoritative `scope_mismatch: Option<bool>` signal (threaded from `replan handoff`'s JSON input, sourced from the verifier's typed verdict) that decides Replan-vs-EscalateModel independent of `reason` prose when present, falling back to the pre-existing prose heuristic only when absent (backward-compatible); `RuntimeDigest` stderr/stdout tails embedded into the runtime reflux verdict are now boundary-fenced via `verify::fence_worker_output` as observational-only untrusted output, never a control-flow input. v0.7.25: deterministic verifier skip/mechanical-check — Task gains optional structured `is_behavioral: Option<bool>` and `mechanical_check: Option<MechanicalCheck>` fields; `verify::classify_criteria` takes both as authoritative hints (overriding the prose `BEHAVIORAL_MARKERS` scan and regex/keyword `mechanical_cmd` extraction respectively) when present, falling back to the existing prose heuristics unchanged when absent — removes a wording-drift / done_criteria-injection surface from the verifier-skip decision. v0.7.26: fix model-tier matching — `verify::canonical` and `replan::canonical_tier` now recognise a tier only via a token/word-boundary match (split on non-alphanumeric chars, exact token equality) instead of a raw substring `.contains()`, so names like `xopusy`/`opuscule`/`supersonic`/`isonnet` no longer spuriously collapse to `opus`/`sonnet`. v0.7.28: schema-precheck LLM JSON at the parse boundary — a new `schemaguard` library dependency validates fresh decomposition JSON (`state init`) and consensus verdicts against declared schemas in-process, before `serde_json` deserialize, bailing with a structured, enumerable violation list (a re-ask contract) instead of a cryptic serde error; unknown schema/unparseable JSON is left to the existing serde path (fail-soft, additive only — valid input is unchanged). v0.7.35: wire blastguard's `classify_change` sensitive-path signal into the gate — both `schedule::schedule`'s force-gate and `gate_exec::gather_assessment` now classify with `touched_files` (empty diff, since neither call site has a diff pre-execution), so a task touching an auth/payment/PII glob is force-gated even when tagged `parallel`, same as a mislabelled deploy; the public-symbol-diff signal remains out of scope here (no diff available). v0.7.36: replan handoff surfaces a relevant past lesson — `build_replan_handoff` retrieves the best-matching lesson from `harness_core::lessons` (lexical search over reason+task_summary+done_criteria) and, only above a 0.4 score threshold, appends it to the handoff instruction wrapped in an explicit UNTRUSTED-PRIOR-LESSON boundary marker (reference-only, never overrides done_criteria/scope); below-threshold, no-hit, empty, or unreadable stores fail-soft to an unchanged handoff. v0.7.37: cross-task learning MEASUREMENT — a new `learning-signal` subcommand deterministically aggregates the retrieval ledger (`harness_core::retrieval`, hit/miss per run_id) against per-run replan totals (`state::load_replan_records`) into `mean_replan_reduction_ratio` (mean replan count for lesson-hit runs vs miss runs), guarding divide-by-zero/empty-group edge cases to `null` rather than panicking; purely additive read-only aggregation, no change to existing replan/retrieval/lessons write paths. v0.7.38: docs-only — README/README.ja document the `learning-signal` subcommand and the cross-task lessons lifecycle (stuckguard escalation write → lexical retrieval → UNTRUSTED-bounded replan-handoff injection); no code/behavior change. v0.7.41: gate-check Escalate verdicts now auto-enqueue to a durable human queue — `gate_exec::run_gate_check`'s Escalate branch records an overwatch review-finding via library call (finding_id `gate-exec:{run}:{task}` so re-checks dedup to one row; severity from risk), populating the risk-ranked review-queue ai-finding stream so needs-human/gated verdicts reach a human automatically under codegen flood; purely additive and fail-soft (a finding-write error never changes the existing stdout/journal/exit behavior), AutoExec records nothing. v0.7.42: new `review-brief` subcommand emits a deterministic per-item reviewer digest (markdown/JSON) for a run/task from STATIC persisted signals only (no LLM/API) — intent (goal+title+done_criteria+kind), declared touched files/symbols, sensitive-path + tripped-invariant risk drivers (overwatch violations keyed to this run/task), and an ordered look-here-first list; honestly scoped to declared files + persisted signals (hunk-level enclosing-function and live-diff recompute out of scope). Subscription-native (skill + agents + hook, no API key). v0.7.44: `escalate add` gains content-dedup backpressure — a re-enqueue with an identical (run, task, question) that is still OPEN returns the existing record instead of appending a duplicate, so repeated re-asks under codegen flood collapse onto one durable record; a RESOLVED match does not dedup, so a re-ask after an answer still creates a fresh open record. v0.7.45: novelty/precedent detection (Google LSC "reviewed-once-applied-broadly") — a new `precedent` subcommand (`ratify`/`list`/`check`) records a ratified change's declared shape (touched files + target symbols) as a structural fingerprint (order-independent FNV-1a hash) in a fail-soft project-scoped store; `review-brief` now loads the store and, ONLY for a routine change (no sensitive path, no tripped invariant), downgrades `risk_tier` to `low` when the declared shape exact-matches a precedent's fingerprint or clears an 0.8 Jaccard-similarity tolerance on both files and symbols, surfacing the match as `precedented` (additive JSON field, absent when unset). SAFETY INVARIANT: a sensitive-path or tripped-invariant High is NEVER downgraded by a precedent match. Backward-compatible: an empty precedent store renders a byte-identical brief to today. v0.7.46: new `review-worthiness` subcommand — a deterministic review-WORTHINESS (review-COST) score, distinct from blastguard/diffrisk's blast-radius, summing four bounded penalty terms (size scaled by total changed lines, net-deletion, missing-rationale, absent-task-link) into a `score` + human-readable `drivers`; primary flag mode is hermetic (no git), an optional fail-soft `--from-git` convenience mode gathers numstat/log signals from a live repo. Kept fully separate from `review-brief`'s no-live-diff purity contract; feeds a future review-budget allocator. v0.7.47: new `review-order` subcommand — a deterministic review-ORDER pass that reorders a diff's hunks so a human reviews top-to-bottom: a fresh unified-diff hunk parser plus a pure edge-builder/orderer clusters logically-connected hunks (union-find weakly-connected components) and topologically sorts each cluster (Kahn's algorithm, deterministic min-key tiebreak/cycle-break) so definitions come before the hunks that reference them, reusing blastguard's caller-enumeration and harness-core's symbol extraction as the reference/definition source; `--diff-file` is the hermetic tested contract, `--from-git` a fail-soft convenience.
By yukineko0 GitHub starsUpdated yesterday
Directory evidence
- Runtimes
- Claude Code
- Parsed components
- 2 skill or MCP entries
- Source updated
- Sep 23, 2026
- Manifest status
- Canonical path parsed
The directory validates manifest shape and source location. It does not execute the plugin or provide a security endorsement. Review the indexing methodology →
Install condukt for Claude Code
claude plugin marketplace add IchenDEV/agent-plugin-mkt
claude plugin marketplace update agent-plugin-marketplace
claude plugin install condukt@agent-plugin-marketplacePaste and run these commands in a terminal with Claude Code. They add and refresh the PluginsMP catalog, then install this plugin.
The installer fetches third-party code from the source repository shown on this page. This directory validates manifest structure and source location, but does not perform a security audit; review the manifest, components, and source before installing.
Get the source manually
git clone https://github.com/yukineko/claude-harnessesClone the source repository, then follow its setup instructions to add the plugin to a compatible client. The plugin root is crates/condukt/.
Plugin files
├── .claude-plugin/plugin.json├── skills/condukt/SKILL.md└── skills/condukt-loop/SKILL.md
Included Skills2
課題を解釈→タスク分割→合意→並列/直列スケジュール(決定論)→worktree並列実装→検証→完了ゲートまで回す合意駆動オーケストレーター。複数ステップ・複数ファイルにまたがる大きめの課題に使う。分割の衝突解析・worktree・状態管理・ゲートは condukt バイナリが決定論的に担い、LLM は解釈・実装・検証に集中する。
test→fix→test ループを自動で回すスキル。server/client/e2e の3サイクルに対応し、差分0件 (failure_count 不変) またはテスト全件パスで自動停止する。
Plugin manifests1
{
"name": "condukt",
"version": "0.7.174",
"description": "v0.7.165 (integrated; branch-local label was v0.7.161): autonomy becomes ONE switch that condukt, ctxrot and autoflow all read DIRECTLY (harness_core::autonomy) instead of three per-crate signals that could not agree. `state autonomy-set on|off` writes a durable `<$HARNESS_AUTONOMY_DIR or ~/.harness/autonomy>/<project-key>.json` atomically, keyed by the repo's MAIN worktree root (projkey::main_worktree_root) so a switch set in the main tree is visible from every linked worktree -- a switch a worker under CLAUDE.md section 8 cannot see is not a switch. `Config::load` layers that file BETWEEN config.toml and the env, so `CONDUKT_AUTONOMOUS=0` still beats a switch left on. Fail-closed and NOT silent (sections 1/3): an ABSENT file is a determinate 'never set' (off, source `default`, stderr silent), while a file that EXISTS but cannot be read/parsed is Undetermined -- off, source `undetermined-switch-file`, and a stderr warning naming the path, so broken and never-set are never byte-identical. Plain `state autonomy-check` stdout is untouched (`{\"autonomous\":<bool>}`, exit 0/1; the frozen oracle autonomy_invariant.rs stays 16/16 green and byte-unmodified); the deciding layer is reported only by the new `--explain` flag and by `state autonomy-path`. v0.7.151 integrates this line with the remote's. From this line: `enforce_edit_gate` no longer resolves a malformed verdict to `Allow` — the `required` / `fallback` / `broken` fields are read three-valued and any one of them being unreadable is 判定不能, which resolves to `Reject` (CLAUDE.md 3); and `worktree reconcile`'s DEATH rule third clause moved off the cwd-dependent transcript slug onto the session registry. v0.7.144 integrates this machine's line. `worktree::remove` no longer force-discards uncommitted work: both `Known(true)` and `Undetermined` now bail and leave the directory on disk, and the test that had pinned the permissive behaviour as correct (`worktree_remove_force_removes_dirty_worktree`, asserting verbatim that a \"dirty worktree should be force-removed\") was replaced rather than kept green. A disinterested agent observed the RED first and a third agent's mutation killed 3/3. v0.7.143: v0.7.141 のスケジューラ側並列上限 (schedule のバッチ幅分割 / Config::load の clamp / consensus / adversarial) を revert し、強制を parallelguard (PreToolUse で in-flight を数えて deny) へ移した。あわせて origin/main を統合し、3rd taintguard trigger を撤去した v0.7.140 を取り込む — `condukt lessons record-retrieval` は `taintguard::state::mark` を呼ばず、`taintguard` path 依存も無い (crates/condukt/src/main.rs:2174 に理由のコメントだけが残る)。これは封じ込めの REMOVAL であって移設ではない: cross-project lesson injection は untrusted provenance として追跡されず、その後に write 系ツールを downgrade する gate も無い。`tests/lessons_taint_trigger.rs` は固定していた挙動ごと削除済み。 v0.7.141: 1 セッションの同時実行を 3 に上限化。max_parallel は doc 上「advisory」で実際には誰も強制しておらず、schedule はバッチ幅を切らないまま 5 タスクを 1 バッチ 5 並列にしていた。schedule_capped がバッチを cap で分割し (切るだけでタスクは落とさない partition)、Config::load が harness_core::parallel::cap_fanout で clamp するので config.toml も CONDUKT_MAX_PARALLEL も下げられるが上げられない。consensus samples と adversarial panel の上限 5 も同じ cap に従う (floor 2 は維持 = 1 サンプルの合議は測っていない同意を報告する fail-open なので cap より優先)。 v0.7.117: wires the 3rd taintguard trigger — \"this turn consumed cross-project lessons\" — into `condukt lessons record-retrieval`. On the same non-empty-hit condition the existing retrieval-ledger `hit` flag already uses, the handler now calls `taintguard::state::mark(&cwd, &run, \"lessons\")` (new `taintguard` path dependency, mirroring the existing `blastguard`/`overwatch` deps; taintguard itself is unchanged), tainting the session so taintguard's PreToolUse `gate` downgrades write-class tools for the rest of the turn — mirroring the existing web/external-read triggers. A zero-hit search stays a no-op (preserves the empty `lessons_context: []` contract); a failed `mark` is `eprintln!`'d and does not fail the command. New `tests/lessons_taint_trigger.rs` confirms RED (no taint) with the mark call disabled and GREEN once wired, plus an anti-vacuity zero-hit case and a regression on the unchanged retrieval-ledger/lessons_context shape. v0.7.113: PROGRESS-not-liveness gate on the cross-session claim reap (mirrors backlog's lock-reap fix) — `claim::reap` no longer evicts a heartbeat-stale claim on heartbeat-age alone (the fail-open that force-steals a live-but-quiet run: fresh commits / growing transcript / advancing tasks, heartbeat merely lapsed). A stale claim is now reaped ONLY when its owning run's PROGRESS is confirmed `Known(Stalled)` by the reusable `harness_core::progress` engine — git HEAD + the owning session's transcript + the run's max task `updated_at` frozen across the multi-sample window (default 90s, `HARNESS_PROGRESS_WINDOW_SECS`). Progressing OR Undetermined (unreadable signal / no prior sample / window not elapsed) NEVER reap (fail-closed). The run-progress signal is deliberately max(task.updated_at), NOT the run-state file mtime (heartbeats rewrite that file = liveness, not progress). All five reap call sites (claim_files/claim_tasks/heartbeat/active_claims/write_execution_state) thread the same progress probe. New `condukt state probe --run RID [--json]` reports, per RUNNING task, the durable signals, `last_progress_age_secs`, and the three-valued verdict — the observability twin sampling the same engine. Tests: the two stale-reap unit tests now encode the tighter contract (reap requires a forced `Known(Stalled)` via a `#[cfg(test)]` thread-local seam, compiled out of production); new protective tests pin the fail-closed half (Progressing / Undetermined ⇒ NOT reaped) observed RED against the old ungated reap; docstrings updated in the same commit. v0.7.109: closed an F→P oracle fail-open (backlog 22b69f6a) — `oracle::check_oracle`'s top-of-function exemption used to fire on `!requires_oracle || reproduction_tests.is_none()`, so a fix/feature task (`requires_oracle:true`) that simply did not DECLARE `reproduction_tests` was exempted from the Fail→Pass gate even when real tdd RED→GREEN proofs existed for it. Narrowed the guard to `!requires_oracle` alone: a fix/feature task is now ALWAYS consulted against `tdd` regardless of whether it declared `reproduction_tests` (missing declarations degrade to the tdd `unknown`/spawn-Err paths, never a free pass). The `reproduction_tests` param is retained for call-site signature stability (renamed `_reproduction_tests`) but is no longer a gate switch; the doc comment and the exempt `reason` string (`\"not a fix/feature task\"`, no longer `\"or no reproduction_tests\"`) were updated in the same commit to match. The tdd-spawn and spawn-Err (`\"a missing checker is not a passing checker\"`) branches are unchanged. v0.7.108: added a must-ask-human / untestable clamp to the graded-autonomy policy (backlog 903a0d28) — new `policy::decide_untestable(risk, reversibility, confidence)` mirrors `decide_conflict_resolution`: it calls `decide` and clamps an `Auto` verdict up to `Escalate`, passing `Escalate`/`Block` through unchanged (pure, total, no opt-in path back to Auto), so CLAUDE.md §2's \"if a thing cannot be meaningfully tested, ask the human\" gate can never be auto-self-answered. Wired a `--untestable` bool flag into both `policy decide` and `policy answer` (mirrors `--conflict`); when set, the verdict is computed by `decide_untestable`, so an otherwise-`auto` untestable decision falls through to a real AskUserQuestion (exit 2, `{\"answered\":false,\"policy\":\"escalate\"}`, never journaled). `--untestable` takes precedence over `--conflict` (both clamp Auto→Escalate identically). Everything downstream (exit codes, escalate/auto JSON, journal) is unchanged. v0.7.107: the GHA removal landed across two commits (the second re-touched condukt src, so the bump-on-change gate required a second micro bump); functionally identical to v0.7.106. v0.7.106: removed the GitHub-Actions-CI-status-consuming code (GHA is banned repo-wide, CLAUDE.md; its workflow files are already gone) — deleted `src/ci.rs` entirely (the `gh pr checks`/`gh run list --json` output parser plus `CiConclusion`/`CiVerdict` state machine that existed solely to consume GHA CI conclusions) and removed the `condukt pr poll` subcommand from `main.rs` (its `PrAction::Poll` variant, handler, and the merge-only-when-CI-green flow), since that subcommand's entire purpose was gated on GHA CI state. Kept `src/pr.rs` and `condukt pr create` (`gh pr create` with no CI-conclusion gating — general PR creation, independent of GHA). Also gutted `scripts/test_prepush_hook.py`'s now-stale chronic-red-CI test suite (the check it tested was already removed from `.githooks/pre-push`) and replaced it with coverage for the hook's surviving checks (gate-bypass block, rollout advisory). v0.7.104: `record_runs` now emits a SECOND fugu-router episode with `role=verifier` alongside the existing worker episode, whenever a task carried `state set --verifier-model` (reusing the same title/files/class/done_criteria/status; resolving cost/tokens via `--verifier-agent-id` through the same `resolve_agent_cost`/`resolve_agent_tokens` exact-match path the worker episode already used). Builds on the just-merged verifier_model/verifier_cost_usd/verifier_agent_id fields on TaskState/RecordSpec/`state set` (v0.7.103) toward hypothesis f5f9522a. `fugu-router record --role` and `Episode.role` already existed and needed no change. New e2e test `record_run_emits_worker_and_verifier_episodes_when_verifier_model_set` asserts exactly 2 episodes (worker+verifier) for a task with a verifier model and exactly 1 (worker only) for a task without one. v0.7.101: `.githooks/pre-merge-commit` resolved its own dir with `$(dirname \"$0\")`; a git hook's PATH is whatever invoked git, and on macos-14 CI that dir carries no coreutils, so `dirname` was not found, the substitution collapsed to empty, and the hook exec'd \"/pre-commit\" (nonexistent) — dying 126 and BLOCKING the very §8 integration merges it must permit (observed: build-binaries smoke macos-14 FAIL on `a_clean_no_ff_merge_completes_in_the_primary_tree_with_a_peer_live`; ubuntu-latest + local passed only because their git dir happens to also carry coreutils). Replaced with POSIX parameter expansion (`${0%/*}` behind a `*/*` case guard), a shell builtin needing nothing on PATH. New host-independent regression `the_merge_hook_reaches_pre_commit_with_no_coreutils_on_path` runs the real hook under a PATH of one empty dir (no coreutils on ANY host) — observed RED on the old hook, GREEN on the new, closing the host-dependent-oracle gap that let a macos-only break pass ubuntu+local CI. v0.7.100: fixed a PATH-env test race (backlog b0db2bff) — `oracle.rs` had its own module-local `ORACLE_PATH_ENV_LOCK` serializing only its own PATH-mutating tests; `main.rs`'s `flag_supplied_but_probe_unusable_falls_back` mutated PATH without taking any lock, and tests that spawn real `git` (e.g. `repo_commit::tests::first_unstaged_modification_is_not_misread_as_staged`, via `worktree::git`) took no lock at all, so a concurrent PATH mutation could transiently break their git spawn. Reproduced empirically: 3/15 full-suite runs under 16 test threads flaked before the fix (2 distinct real failures). New shared `env_lock::PATH_ENV_LOCK` (`RwLock<()>`, not a `Mutex`) — PATH mutators (oracle.rs, main.rs) take the write side; `worktree::run_git_bounded_with` (the single git-spawn choke point used by every git-shelling test in the crate) takes the read side, so concurrent git spawns don't serialize against each other but always exclude a mutation window. 20/20 repeats of the same repro loop green after the fix; full `cargo test -p condukt` suite green x3; fmt/clippy clean. v0.7.99: fixed `state::all_runs`/`active_worktree_for_path` misparsing non-RunState sidecars in the per-project state dir as corrupt run states (backlog 1af91627). Only `<run_id>.decomposition.json` was excluded; `<run_id>.checkpoints.json` (checkpoint history) and the bare `claims.json` (cross-run claim registry) were fed to `serde_json::from_str::<RunState>` and logged as \"unparseable run state\" — reproduced live via `condukt state record-run --all` (8 `.checkpoints.json` + 1 `claims.json` = 9 spurious warnings). Grepped the file for every other bare-filename sidecar sharing the same directory (`precedents.json`, `escalations.json`, `execution-state.json`) and excluded those too via a new shared `is_run_state_sidecar()` helper used by both functions, rather than patching just the 2 observed symptoms. New regression test `all_runs_skips_all_known_sidecars_without_warning` fixtures one valid RunState plus all 6 known sidecar shapes and asserts `all_runs` returns exactly the one valid run. v0.7.98: internal-only refactor — `verify::checks_verdict`'s computation now routes through `harness_core::verdict::{Determination, Verdict}` (an empty results slice becomes `Determination::Undetermined`, a non-empty slice becomes `Determination::Known` with per-index failure reasons, adjudicated via `Verdict::adjudicate`), then translates back to `ChecksVerdict` at the return boundary. `ChecksVerdict`/`CheckReport`'s public shape and `Serialize`/`Deserialize` derives are unchanged (a `Verdict` can never derive `Deserialize` — see harness-core's `Evidence` witness — so `ChecksVerdict` stays its own serializable shadow type). All pre-existing checks-verdict tests pass unmodified. Skipped the optional per-check-failure-reason threading (naming which check failed): `checks_verdict` is directly tested with bare `&[bool]` literals, so giving it access to `check.cmd` would mean either breaking that tested signature or duplicating logic between it and `run_checks` — both out of scope for an internal-only refactor. v0.7.96: `adversarial.rs`'s local `GATE_CRATES` const is now `pub use harness_core::fleet::GATE_CRATES;`, removing a duplicate hand-written copy that had independently drifted (lost `overwatch`) in the past; type changes from `[&str; 6]` to `&[&str]` but the sole call site (`.iter().any(...)`) is unaffected. v0.7.95: fixed a real fail-closed-refusal bug in `repo commit` found live while committing an unrelated blastguard fix — `worktree::git`'s shared output formatter used to `.trim()` the WHOLE stdout blob of every git invocation, not just its trailing newline. `git status --porcelain`'s first line for an unstaged modification is ` M path` (a leading space that is the semantically meaningful 'not staged' status column, not incidental whitespace); because that space sat at byte 0 of the whole blob, the blanket `.trim()` ate it, corrupting only the FIRST line. `repo_commit::staged_paths` then read the corrupted line's first byte as the file-status char (neither `' '` nor `'?'`) and wrongly reported an ordinary unstaged edit as already-staged foreign content, and its `path[3..]` slice (meant to skip the 2-char status + 1 space) then cut one byte too many off the path itself (observed live as `.claude-plugin/marketplace.json` reported as `claude-plugin/marketplace.json`, missing its leading dot). This made `condukt repo commit` refuse to commit ANY task whose first `git status --porcelain` entry happened to be a plain unstaged modification — a correct implementation blocking legitimate commits, not a fail-open. Fixed by changing the shared formatter to `.trim_end()` (strips only the trailing newline git always appends; every other git-output consumer in this crate already re-trims per-line or never depended on leading whitespace). New regression test `repo_commit::tests::first_unstaged_modification_is_not_misread_as_staged` reproduces the exact incident shape (a real temp repo, a dotfile path, an unstaged edit as the first entry), confirmed RED before the fix and GREEN after; full `cargo test -p condukt` suite (721 tests) still green. v0.7.87: cargo fmt --all reformatting only (fixes the 'build & commit plugin binaries' smoke workflow's `cargo fmt --all --check` gate, chronically red on main since 2026-07-21 per scripts/check-ci-red.py); no behavior change. v0.7.75: fix the runtime-conflict cleanup gap (design 625aa170 finding #1) — a task's branch landing now marks its `ActualChangeset` merged via a new `worktree::finalize_landed_branch` (calling overwatch's branch-keyed `store::mark_branch_merged`, the only key the merge path has) wired into BOTH `merge()`'s clean-merge path AND `resolve_merge()`'s reconciled outcomes, so a cleanly-landed task no longer leaves `merged=false` within the lease TTL and spuriously HOLDS the next sequential task that touches a common file; the same cleanup clears any stale `RuntimeOverlap` hold recorded against the landed branch name (defensive against a reused `condukt/<id>` branch) and opportunistically prunes the cross-run changeset registry so it stays bounded. Also fixes the broken `run_pr` Poll remediation hint (`condukt worktree resolve-merge --branch <b>` → the correct `--id <id>` form that `ResolveMerge` actually accepts). New regression tests pin the pre-merge hold gate (an open RuntimeOverlap HOLDs the merge) and the landed-peer cleanup (a merged peer is excluded from detection, so no spurious hold). v0.7.71: `schedule()` now warns (does not reject) when a task's `touched_files` entry looks like an absolute path (`/`-rooted or a Windows drive letter) or contains a `..` traversal component — such entries silently defeat the string-based conflict-detection heuristics documented as `normalize_entry`'s deliberate repo-relative-only scope, so two tasks that actually touch the same file via a non-conventional path could previously be scheduled in parallel with no warning at all. Warn (not reject) was chosen because `schedule()` is the decomposition-wide deterministic gate and a hard error there would stop the whole run over what is usually a false-positive-prone heuristic, not a certain conflict. Also adds a real end-to-end capstone test (`schedule_conflict_capstone_e2e.rs`) driving `schedule()` itself with a genuinely-overlapping pair, a pair that only collides after `normalize_entry`'s `./`/`//` normalization (v0.7.69's fix), and a genuinely-independent pair — asserting the first two are forced serial and the third is left parallel, plus a simulated concurrent-write check that no pair loses data. Also adds `fugu_router_record_e2e.rs`, confirming the v0.7.66 `suggested_model`/`route_basis`/`tokens_input`/`tokens_output` wiring (already implemented in code) actually lands those fields in a real `episodes.jsonl` end-to-end — the 0/537-tokens gap seen in production data traced to the live deployed condukt binary lagging behind source, not a code defect. v0.7.70: `schedule::entries_conflict` now normalizes each touched-file entry (strip a leading `./`, collapse repeated `/`) before comparing, closing a false-negative gap where two different spellings of the identical path (e.g. `./src/a.rs` vs `src/a.rs`, or `src//a.rs` vs `src/a.rs`) went undetected as a conflict and could schedule two workers onto the same file in parallel. Audited for false positives too: confirmed (and pinned with a regression test) that disjoint globs sharing only a parent directory (`src/foo/*.rs` vs `src/bar/*.rs`) do NOT over-serialize, and that the literal-prefix-nesting heuristic's known conservative-but-safe over-approximation (e.g. `src/*.rs` vs `src/sub/*.rs`) is unchanged and intentional per this module's own \"conservative: false conflict only serializes work (safe)\" principle. v0.7.68: `orphans()` (worktree.rs) no longer misreports another repo's live worktree as condukt debris when `worktree_base` is shared across multiple, unrelated git repositories on the same machine — a candidate directory is now only flagged as an orphan if its `.git` (file pointer for a linked worktree, or dir for a plain clone) actually resolves under `repo`'s own `.git` common dir AND isn't in `repo`'s registered worktree list; a directory owned by a different repo is silently skipped, while a directory with no `.git` at all is still conservatively treated as orphan (unchanged). New regression tests `orphans_ignores_other_repos_worktree` and `orphans_detects_stale_worktree_of_own_repo` cover the new behavior and the real-world stale-worktree case this fix must not regress. v0.7.67: `record_runs` now checks the actual exit status of the `fugu-router record` subprocess instead of only catching a spawn `Err`, so a non-zero exit (e.g. a stale PATH-shadowed `fugu-router` binary rejecting a flag) is no longer silently counted as a successful record; also resolves `fugu-router`'s binary path via `~/.claude/plugins/installed_plugins.json`'s plugin-cache `installPath` first, falling back to the bare command name only if resolution fails, so a stale `~/.cargo/bin/fugu-router` can no longer shadow the correct plugin-installed version. v0.7.66: `TaskState`/`state set` gain measurement-only `route_basis`/`route_confidence`/`route_rationale` (the routing `Decision`'s provenance from `route.json`) and `lines_added`/`lines_removed` (measured `git diff --stat` insertions/deletions), plus a new `state::resolve_agent_tokens` (mirrors `resolve_agent_cost`, exact agent-id match against `gauge subagents --json`'s new `tokens_input`/`tokens_output`); `record_runs` threads all of these through to `fugu-router record`'s matching new flags so routing decisions and task cost/size can be retrospectively correlated against actual pass/fail outcomes. None of it is consulted by condukt's own scheduling/routing — purely additive, backward-compatible (`#[serde(default, skip_serializing_if)]`). v0.7.63: opt-in **shadow-run** mode — a new `shadow-run enable|disable|status` flag (default: disabled) plus `exec`/`finish` subcommands run the SAME task under a second model in an independent worktree (reusing the existing `worktree create`/`discard` machinery) purely to produce a clean pass/fail/cost/duration comparison point for `fugu-router record --class shadow-run`; the shadow worktree is ALWAYS discarded (force-remove + force-delete branch), never merged. Manual-trigger only by design — no API/hook input exposes remaining rate-limit-window time, so automatic firing is not implemented; pairs with gauge's new `config set-window`/`config show` for a human-registered window approximation. v0.7.62: task-duration measurement — `TaskState` gains `started_at` (set when a task transitions to `running`); `records_for_run` computes `duration_secs` from `(started_at, updated_at)` and `record_runs()` passes it to `fugu-router record --duration`, populating the new measurement-only `Episode.duration_secs` field (routing/scoring logic in fugu-router's `policy.rs` is unchanged). v0.7.61: `verify::mechanical_cmd` now tokenizes command strings (both the interpreter-declared `mechanical_check` hint and the backtick-extracted done_criteria command) via a new quote/escape-aware `parse_argv` (shlex-backed) instead of `split_whitespace`, so a quoted argument containing spaces (e.g. a path) survives as one argv token instead of being split in two; falls back to `split_whitespace` on unparseable (unterminated-quote) input rather than dropping the mechanical check. v0.7.60: `verify::run_check` now gates each declared check command through blastguard's pure detector (same `detect(\"Bash\", ...)` call already used by `launch_and_reflux`) before spawning `sh -c`; a flagged command is refused fail-closed and reported as a non-passing `CheckResult` (exit -1) instead of being executed. New test `run_check_blocks_destructive_command_via_blastguard` proves a `rm -rf /` check never reaches the shell. v0.7.58: audited `lessons.rs`'s `harvest()` (production JSON-facts path) for raw `.unwrap()`/`.expect()` — the production path was already fail-soft (`.ok()`/`.and_then()`/`.unwrap_or()`/`.unwrap_or_default()` throughout, no panics); the flagged `as_str().unwrap()` calls live inside `#[cfg(test)] mod tests` only. Fixed a real (unrelated) flake found while confirming `cargo test -p condukt` green under parallel test execution: `lessons::tests::harvest_facts_drive_idempotent_append_that_search_retrieves` mutates the process-global `LESSONS_STORE_DIR` env var without serializing against `replan.rs`'s tests doing the same, so it now takes its own `ENV_LOCK` mutex around the env-var-mutating critical section (mirrors the existing `replan::tests::ENV_LOCK` precedent). v0.7.57: `worktree.rs`'s git subprocess calls (`git()`/`git_try()`) are now bounded by a 45s timeout (wait_timeout + process-group kill, mirroring propguard::git/autoflow::compass) instead of a plain unbounded `Command::output()`, so a hung `git` (lock contention, stuck credential prompt, network-mounted repo) can no longer wedge a condukt run indefinitely; `create()`'s \"worktree must be outside the repo\" check now canonicalizes the candidate worktree path (falling back to the nearest existing ancestor when the leaf doesn't exist yet) before comparing against the canonical repo root, closing a TOCTOU-adjacent bypass where a non-canonical `worktree_base` (symlink hop, WSL/DrvFs mount) could look like it resolved outside the repo when it actually didn't. v0.7.56: `verify::tests::skip_eligible_without_command_fails_soft` no longer relies on a `panic!` inside the invariant-violating runner closure to prove it is unreachable — it now records the invocation via a `Cell<bool>` flag, logs via `eprintln!`, and asserts the flag stays false, so an unattended run never aborts on this code path even in a hypothetical regression (production `mechanical_skip_verdict` behavior unchanged: it already refused to invoke the runner and returned a fail-soft `skip_verifier: false` verdict). v0.7.55: docs-only — SKILL.md Phase 7 now documents the `state reconcile` exit 2 (duplicate_completion) escalation branch (specguard spec-audit 2026-07-13 finding); no code/behavior change. v0.7.54: `gate_exec`'s escalate-finding call site follows overwatch's new `ReviewFinding.rationale`/`record_finding` signature (passes `None` — no behavior change, just keeps the call site compiling against the extended API). Deterministic orchestration engine for Claude Code: interpreter/researcher/worker/verifier skill pipeline plus a Rust binary that schedules tasks into parallel/serial batches by file-conflict analysis, manages the git-worktree lifecycle, tracks run state, and gates completion. v0.3: run resume across sessions (state resume-context + Phase 0-alt), stale-run reconcile (state reconcile auto-promotes merged branches to verified), benchmark stats (state stats), baseline test capture (Phase 4.5), pipeline verifier launch (no batch-wait), verifier-skip for mechanical done_criteria, auto-resume when 1 open run. v0.3.1: pause/resume (state pause/resume), paused-run indicator in state list, paused runs excluded from SessionStart notifications. v0.4.0: deterministic fugu-router outcome recording — a Stop hook fires `state record-run --all` (idempotent via per-run recorded_at; soft no-op without fugu-router), and `state set` accepts --model/--cost so recorded outcomes reflect the actual (escalated) model and gauge cost. v0.4.1: fix Phase 6 cost capture — read the session id from CLAUDE_CODE_SESSION_ID (the repo-standard var; CLAUDE_SESSION_ID never existed) and omit --session when unset so gauge falls back to the latest session instead of returning null; requires gauge >= 0.2.0 for `session --json`. v0.4.2: record true per-task cost — Phase 5 tags each worker's Task description with its task id, and Phase 6 reads per-sub-agent cost via `gauge subagents` (>= 0.3.0) matched by that description, instead of a lumped session total that would break fugu-router's cost-per-pass routing. v0.5.0: harden the verifier stage against two shared-blind-spot failures — `state verifier-model` deterministically resolves a verifier model that can never equal the worker model (no more worker==verifier==sonnet when fugu-router is absent), and `state check-criteria` now classifies done_criteria as behavioral vs purely mechanical and emits `skip_verifier`, so only purely mechanical criteria may bypass the LLM verifier; behavioral criteria always run it and a passing test is only evidence, never a substitute. v0.6.0: multi-sample self-consistency voting — a new `consensus` subcommand (`plan` gates an opt-in fan-out via config `[consensus] enabled`/`CONDUKT_CONSENSUS`/per-task `--risk high`; `vote` tallies N verifier verdicts for one task into a deterministic majority winner + agreement rate, escalating to opus on all-fail, a tie, or agreement below threshold). OPT-IN cost guard: OFF by default, small default N=3 clamped to a ceiling of 5. SKILL Phase 5.5 wires the fan-out (N candidate worktrees → verify each → `consensus vote` → winner, else opus redo) without adding any new stop point. v0.7.0: cross-session file-claim registry (PDO collision guard) — `state claim/release/heartbeat/claims` maintain a project-scoped `claims.json` that turns `conflict-check`'s one-time advisory snapshot into a live, enforcing file-level lease, so two condukt sessions on the same machine never process the same work. Enforcement is automatic: `state set --status running` auto-claims the task's touched_files and HARD-SKIPS (exits 1 with a skip JSON naming the live holder) when another live run owns any of them; terminal transitions auto-release; heartbeats keep a busy session's claims alive; stale claims (heartbeat older than the stuck-TTL) are reaped. Liveness is anchored to the heartbeat, not the ephemeral CLI pid. v0.7.1/0.7.2: task-claim lockstep bump / docker-isolated exec backend for verify launch (--docker, fail-soft). v0.7.3: deterministic RUN-POLICY gate — `run-policy decide` maps a cheap-verify result + production-divergence + change-risk to the next verify→docker→ship stage (verify_only|escalate_docker|escalate_ship|ask_human), fail-soft parsing to the safest value on unrecognized input; `run-policy stats` aggregates the decision log. SKILL Phase 6 wires the verdict into the docker-escalation decision for runtime/health done_criteria. v0.7.4: opt-in worker sandboxing — a `sandbox run` subcommand routes a worker's build/test through the docker exec backend with filesystem + resource isolation (`--network=none` reused, plus optional `--memory`/`--cpus`/`--pids-limit`/`--read-only`), gated by config `[worker] sandbox_enabled` / `CONDUKT_WORKER_SANDBOX`; OFF by default (worker keeps host-direct execution), and docker-absent degrades to the existing `docker_unavailable` fail-soft without host fallback. v0.7.7: deterministic in-code RUN-POLICY gate — `verify launch --run-policy` fuses decision and action with no LLM step between them: `verify::run_policy_gate` calls `decide_run_policy` and invokes the container launch ONLY on the `escalate_docker` verdict (other verdicts never launch), recording the chosen verdict to the run-policy JSONL when `--run` is given. Purely additive (existing `verify launch --docker`/`--health-url`/host paths unchanged); docker-absent keeps the `docker_unavailable` fail-soft with no host fallback. SKILL Phase 6 documents it as the canonical way the run→docker escalation is gated LLM-free. v0.7.21: activate `expected_trajectory` — Task gains an optional passthrough `expected_trajectory` field (`{mode, steps:[{tool}]}`), documented in the interpreter schema and SKILL.md Phase 1, and Phase 6 now derives `$EXPECTED_TRAJ`/`$WORKER_TRANSCRIPT` from the task JSON and the worker sub-agent transcript (via the same `gauge subagents` description correlation Phase 6 cost capture uses) so `trajectoryeval extract` → `check` actually fires when a task declares a trajectory. v0.7.24: deterministic replan/escalate decision — `replan::classify_failure` gains an authoritative `scope_mismatch: Option<bool>` signal (threaded from `replan handoff`'s JSON input, sourced from the verifier's typed verdict) that decides Replan-vs-EscalateModel independent of `reason` prose when present, falling back to the pre-existing prose heuristic only when absent (backward-compatible); `RuntimeDigest` stderr/stdout tails embedded into the runtime reflux verdict are now boundary-fenced via `verify::fence_worker_output` as observational-only untrusted output, never a control-flow input. v0.7.25: deterministic verifier skip/mechanical-check — Task gains optional structured `is_behavioral: Option<bool>` and `mechanical_check: Option<MechanicalCheck>` fields; `verify::classify_criteria` takes both as authoritative hints (overriding the prose `BEHAVIORAL_MARKERS` scan and regex/keyword `mechanical_cmd` extraction respectively) when present, falling back to the existing prose heuristics unchanged when absent — removes a wording-drift / done_criteria-injection surface from the verifier-skip decision. v0.7.26: fix model-tier matching — `verify::canonical` and `replan::canonical_tier` now recognise a tier only via a token/word-boundary match (split on non-alphanumeric chars, exact token equality) instead of a raw substring `.contains()`, so names like `xopusy`/`opuscule`/`supersonic`/`isonnet` no longer spuriously collapse to `opus`/`sonnet`. v0.7.28: schema-precheck LLM JSON at the parse boundary — a new `schemaguard` library dependency validates fresh decomposition JSON (`state init`) and consensus verdicts against declared schemas in-process, before `serde_json` deserialize, bailing with a structured, enumerable violation list (a re-ask contract) instead of a cryptic serde error; unknown schema/unparseable JSON is left to the existing serde path (fail-soft, additive only — valid input is unchanged). v0.7.35: wire blastguard's `classify_change` sensitive-path signal into the gate — both `schedule::schedule`'s force-gate and `gate_exec::gather_assessment` now classify with `touched_files` (empty diff, since neither call site has a diff pre-execution), so a task touching an auth/payment/PII glob is force-gated even when tagged `parallel`, same as a mislabelled deploy; the public-symbol-diff signal remains out of scope here (no diff available). v0.7.36: replan handoff surfaces a relevant past lesson — `build_replan_handoff` retrieves the best-matching lesson from `harness_core::lessons` (lexical search over reason+task_summary+done_criteria) and, only above a 0.4 score threshold, appends it to the handoff instruction wrapped in an explicit UNTRUSTED-PRIOR-LESSON boundary marker (reference-only, never overrides done_criteria/scope); below-threshold, no-hit, empty, or unreadable stores fail-soft to an unchanged handoff. v0.7.37: cross-task learning MEASUREMENT — a new `learning-signal` subcommand deterministically aggregates the retrieval ledger (`harness_core::retrieval`, hit/miss per run_id) against per-run replan totals (`state::load_replan_records`) into `mean_replan_reduction_ratio` (mean replan count for lesson-hit runs vs miss runs), guarding divide-by-zero/empty-group edge cases to `null` rather than panicking; purely additive read-only aggregation, no change to existing replan/retrieval/lessons write paths. v0.7.38: docs-only — README/README.ja document the `learning-signal` subcommand and the cross-task lessons lifecycle (stuckguard escalation write → lexical retrieval → UNTRUSTED-bounded replan-handoff injection); no code/behavior change. v0.7.41: gate-check Escalate verdicts now auto-enqueue to a durable human queue — `gate_exec::run_gate_check`'s Escalate branch records an overwatch review-finding via library call (finding_id `gate-exec:{run}:{task}` so re-checks dedup to one row; severity from risk), populating the risk-ranked review-queue ai-finding stream so needs-human/gated verdicts reach a human automatically under codegen flood; purely additive and fail-soft (a finding-write error never changes the existing stdout/journal/exit behavior), AutoExec records nothing. v0.7.42: new `review-brief` subcommand emits a deterministic per-item reviewer digest (markdown/JSON) for a run/task from STATIC persisted signals only (no LLM/API) — intent (goal+title+done_criteria+kind), declared touched files/symbols, sensitive-path + tripped-invariant risk drivers (overwatch violations keyed to this run/task), and an ordered look-here-first list; honestly scoped to declared files + persisted signals (hunk-level enclosing-function and live-diff recompute out of scope). Subscription-native (skill + agents + hook, no API key). v0.7.44: `escalate add` gains content-dedup backpressure — a re-enqueue with an identical (run, task, question) that is still OPEN returns the existing record instead of appending a duplicate, so repeated re-asks under codegen flood collapse onto one durable record; a RESOLVED match does not dedup, so a re-ask after an answer still creates a fresh open record. v0.7.45: novelty/precedent detection (Google LSC \"reviewed-once-applied-broadly\") — a new `precedent` subcommand (`ratify`/`list`/`check`) records a ratified change's declared shape (touched files + target symbols) as a structural fingerprint (order-independent FNV-1a hash) in a fail-soft project-scoped store; `review-brief` now loads the store and, ONLY for a routine change (no sensitive path, no tripped invariant), downgrades `risk_tier` to `low` when the declared shape exact-matches a precedent's fingerprint or clears an 0.8 Jaccard-similarity tolerance on both files and symbols, surfacing the match as `precedented` (additive JSON field, absent when unset). SAFETY INVARIANT: a sensitive-path or tripped-invariant High is NEVER downgraded by a precedent match. Backward-compatible: an empty precedent store renders a byte-identical brief to today. v0.7.46: new `review-worthiness` subcommand — a deterministic review-WORTHINESS (review-COST) score, distinct from blastguard/diffrisk's blast-radius, summing four bounded penalty terms (size scaled by total changed lines, net-deletion, missing-rationale, absent-task-link) into a `score` + human-readable `drivers`; primary flag mode is hermetic (no git), an optional fail-soft `--from-git` convenience mode gathers numstat/log signals from a live repo. Kept fully separate from `review-brief`'s no-live-diff purity contract; feeds a future review-budget allocator. v0.7.47: new `review-order` subcommand — a deterministic review-ORDER pass that reorders a diff's hunks so a human reviews top-to-bottom: a fresh unified-diff hunk parser plus a pure edge-builder/orderer clusters logically-connected hunks (union-find weakly-connected components) and topologically sorts each cluster (Kahn's algorithm, deterministic min-key tiebreak/cycle-break) so definitions come before the hunks that reference them, reusing blastguard's caller-enumeration and harness-core's symbol extraction as the reference/definition source; `--diff-file` is the hermetic tested contract, `--from-git` a fail-soft convenience.",
"author": {
"name": "yukineko"
},
"keywords": [
"orchestration",
"worktree",
"parallel",
"hooks",
"subagent",
"rust",
"tdd",
"research",
"websearch"
]
}For maintainers
If you maintain this plugin, link to this source-backed listing from your README so users can review its manifest and indexed components.
[condukt on Agent Plugins Marketplace](https://pluginsmp.com/plugins/condukt)