opencode-swarm 7.135.4 → 7.135.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{config-doctor-fgmemknc.js → config-doctor-exj26ryt.js} +2 -2
- package/dist/cli/{curation-policy-frs28q57.js → curation-policy-mbv3b27c.js} +2 -2
- package/dist/cli/{curator-psq8m2j7.js → curator-7ycd6x29.js} +12 -12
- package/dist/cli/{curator-llm-factory-pr59p535.js → curator-llm-factory-4d5pzh47.js} +12 -12
- package/dist/cli/{guardrail-explain-ws45zchy.js → guardrail-explain-2jrqv2zf.js} +13 -13
- package/dist/cli/{guardrail-log-gbzek1pz.js → guardrail-log-c843gxnm.js} +3 -3
- package/dist/cli/{hive-promoter-gdbg4nyd.js → hive-promoter-epnj14q8.js} +12 -12
- package/dist/cli/{index-jsp8r6f9.js → index-09w3ezq2.js} +1 -1
- package/dist/cli/{index-vh39nxpx.js → index-0csbx1wc.js} +1 -1
- package/dist/cli/{index-b34vbxmx.js → index-6yk6ezvj.js} +1 -1
- package/dist/cli/{index-g86vfxnk.js → index-8et4bx6j.js} +3 -3
- package/dist/cli/{index-66w4jjg6.js → index-9s5b8wrs.js} +35 -35
- package/dist/cli/{index-mysdsqtk.js → index-bx10dq60.js} +1 -1
- package/dist/cli/{index-ck9rx6j1.js → index-db52969t.js} +1 -1
- package/dist/cli/{index-cgqekdja.js → index-gvfw2y6v.js} +2 -2
- package/dist/cli/{index-5s1q6xcw.js → index-hw6yt4rs.js} +4 -4
- package/dist/cli/{index-ys04j1np.js → index-jnemjn16.js} +2 -2
- package/dist/cli/{index-cg413zhk.js → index-k8arazbb.js} +1 -1
- package/dist/cli/{index-ajehqzvn.js → index-kjg6vgqs.js} +1 -1
- package/dist/cli/{index-xfeg0c0c.js → index-kq9zb1cv.js} +14 -14
- package/dist/cli/{index-4g3nq4sh.js → index-qyn0b2jj.js} +1 -1
- package/dist/cli/{index-fx7bn93y.js → index-t1gszcwg.js} +2 -2
- package/dist/cli/{index-tegdwx34.js → index-ym516a9a.js} +5 -5
- package/dist/cli/index.js +12 -12
- package/dist/cli/{knowledge-escalator-0060q7we.js → knowledge-escalator-3tjhpwjf.js} +3 -3
- package/dist/cli/{knowledge-events-yh2qwa6k.js → knowledge-events-0akk3p15.js} +1 -1
- package/dist/cli/{knowledge-store-geqaez58.js → knowledge-store-7nvfh2n3.js} +1 -1
- package/dist/cli/{knowledge-validator-4zq4vm7t.js → knowledge-validator-z618vhda.js} +4 -4
- package/dist/cli/{scan-cursor-nk2rybhq.js → scan-cursor-5zqr3afj.js} +2 -2
- package/dist/cli/{schema-th3tx32c.js → schema-n1cj94m0.js} +1 -1
- package/dist/cli/{skill-generator-1947bbkn.js → skill-generator-560ksca8.js} +5 -5
- package/dist/hooks/pr-workflow-gate.d.ts +5 -5
- package/dist/hooks/pr-workflow-response-gate.d.ts +32 -1
- package/dist/index.js +8 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire}from"node:module";var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__toCommonJS=(from)=>{var entry=(__moduleCache??=new WeakMap).get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function"){for(var key of __getOwnPropNames(from))if(!__hasOwnProp.call(entry,key))__defProp(entry,key,{get:__accessProp.bind(from,key),enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return __moduleCache.set(from,entry),entry},__moduleCache,__commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __esm=(fn2,res)=>()=>(fn2&&(res=fn2(fn2=0)),res);var __require=createRequire(import.meta.url);var package_default;var init_package=__esm(()=>{package_default={name:"opencode-swarm",version:"7.135.4",description:"Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",main:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"},"./package.json":"./package.json"},bin:{"opencode-swarm":"./dist/cli/index.js"},type:"module",engines:{bun:">=1.3.13"},license:"MIT",repository:{type:"git",url:"https://github.com/ZaxbyHub/opencode-swarm.git"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},keywords:["opencode","opencode-plugin","ai","agents","orchestration","swarm","multi-agent","llm"],files:["dist","dist/lang/grammars","binaries","evaluation-fixtures",".opencode/skills/brainstorm",".opencode/skills/specify",".opencode/skills/clarify-spec",".opencode/skills/resume",".opencode/skills/clarify",".opencode/skills/discover",".opencode/skills/consult",".opencode/skills/pre-phase-briefing",".opencode/skills/council",".opencode/skills/deep-dive",".opencode/skills/deep-research",".opencode/skills/codebase-review-swarm",".opencode/skills/swarm-implement",".opencode/skills/design-docs",".opencode/skills/swarm-pr-review",".opencode/skills/swarm",".opencode/skills/swarm-pr-feedback",".opencode/skills/swarm-pr-subscribe",".opencode/skills/swarm-ci-monitor",".opencode/skills/issue-ingest",".opencode/skills/plan",".opencode/skills/critic-gate",".opencode/skills/execute",".opencode/skills/phase-wrap",".opencode/skills/loop",".opencode/skills/writing-tests",".opencode/skills/running-tests",".opencode/skills/engineering-conventions",".opencode/skills/commit-pr",".opencode/skills/ci-failure-batching",".opencode/skills/gate-attribution",".opencode/skills/merge-queue-readiness",".opencode/skills/skill-edit-validation",".opencode/skills/worktree-retry-cleanup",".opencode/skills/test-file-split",".opencode/skills/fork-pr-operations",".opencode/skills/parallel-work-check",".opencode/skills/ci-fix-monitor",".opencode/skills/issue-tracer","tests/fixtures/memory-recall","README.md","LICENSE"],scripts:{clean:`bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,build:"bun run clean && bun run scripts/copy-grammars.ts && bun build src/index.ts --outdir dist --target node --format esm --external web-tree-sitter --minify-whitespace --minify-syntax && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external bash-parser --splitting && bun run scripts/copy-grammars.ts --to-dist && tsc --emitDeclarationOnly",typecheck:"tsc --noEmit",test:"bun test",lint:"biome lint .","lint:ci":"biome ci .","test:unit:ci":"bun scripts/ci/run-unit-tests-local.ts","drift:check":"bun run scripts/drift-check.ts","drift:fix":"bun run scripts/drift-check.ts --fix --confirm","skills:sync":"bun run scripts/sync-qa-gate-skills.ts",format:"biome format . --write",check:"biome check --write .",dev:"bun run build && opencode","package:smoke":"node scripts/package-smoke.mjs",prepare:"bun run build","repro:704":"node scripts/repro-704.mjs","repro:1144":"bun scripts/repro-1144.mjs","repro:1873":"bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs"},dependencies:{"@opencode-ai/plugin":"^1.18.3","@opencode-ai/sdk":"^1.18.3","@vscode/tree-sitter-wasm":"^0.3.0","bash-parser":"^0.5.0","p-limit":"^7.3.0",picomatch:"^4.0.4","proper-lockfile":"^4.1.2","quick-lru":"^7.3.0","web-tree-sitter":"^0.25.0",zod:"^4.1.8"},devDependencies:{"@biomejs/biome":"2.3.14","@types/picomatch":"^4.0.3","bun-types":"1.3.8","js-yaml":"^4.1.1",typescript:"^5.7.3"}}});var QA_AGENTS,PIPELINE_AGENTS,ORCHESTRATOR_NAME="architect",ALL_SUBAGENT_NAMES,ALL_AGENT_NAMES;var init_agent_names=__esm(()=>{QA_AGENTS=["reviewer","critic","critic_oversight","critic_finding_validator"],PIPELINE_AGENTS=["explorer","coder","test_engineer"],ALL_SUBAGENT_NAMES=["sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","curator_postmortem","curator_consolidation","council_generalist","council_skeptic","council_domain_expert","skill_improver","spec_writer",...QA_AGENTS,...PIPELINE_AGENTS],ALL_AGENT_NAMES=["architect",...ALL_SUBAGENT_NAMES]});function getPrWorkflowToolCapability(toolName,mode){let metadata=TOOL_METADATA[toolName];if(!metadata?.prWorkflow?.modes.includes(mode))return null;return metadata.prWorkflow.capability}var TOOL_METADATA,TOOL_NAMES,TOOL_NAME_SET,TOOL_DESCRIPTIONS,AGENT_TOOL_MAP;var init_tool_metadata=__esm(()=>{init_agent_names();TOOL_METADATA={diff:{description:"structured git diff with contract change detection",agents:["architect","reviewer","critic_finding_validator","critic_oversight","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},diff_summary:{description:"filter classified AST changes by category, risk level, or file for reviewer drill-down",agents:["architect","reviewer","critic_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},syntax_check:{description:"check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",agents:["architect","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},placeholder_scan:{description:"todo and FIXME comment detection",agents:["architect","reviewer","critic_finding_validator"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},imports:{description:"find all consumers that import from a given file — use before refactoring shared modules to avoid breaking unseen dependents",agents:["architect","sme","researcher","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic_finding_validator","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},lint:{description:"run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",agents:["architect","reviewer","critic_finding_validator","coder"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},secretscan:{description:"scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",agents:["architect","reviewer","critic_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},sast_scan:{description:"static analysis security scan",agents:["architect","reviewer","critic_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},build_check:{description:"discover and run build, typecheck, and test commands for various project ecosystems in the working directory",agents:["architect","coder","test_engineer"]},pre_check_batch:{description:"parallel verification: lint:check + secretscan + sast_scan + quality_budget",agents:["architect","reviewer","critic_finding_validator"]},quality_budget:{description:"code quality budget check",agents:["architect"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},symbols:{description:"extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",agents:["architect","sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","reviewer","critic_finding_validator","critic","coder","test_engineer"]},complexity_hotspots:{description:"git churn × complexity risk map",agents:["architect","sme","researcher","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic_finding_validator","critic","critic_oversight","explorer","test_engineer"]},schema_drift:{description:"OpenAPI spec vs route drift",agents:["architect","sme","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},todo_extract:{description:"structured TODO/FIXME extraction",agents:["architect","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},evidence_check:{description:"verify task evidence completeness",agents:["architect","critic_oversight"]},check_gate_status:{description:"check the gate status of a specific task",agents:["architect","critic_oversight"]},completion_verify:{description:"verify completed tasks have required evidence",agents:["architect","critic_oversight"]},complete_pr_workflow:{description:"validate terminal PR workflow evidence and clear its durable session gate",agents:["architect"]},abort_pr_workflow:{description:"abort an unrecoverable PR_REVIEW/PR_FEEDBACK mechanical gate and clear its durable session state",agents:["architect"]},approve_plan_critic:{description:"record a MANUAL plan_critic_gate approval snapshot to unblock the ratchet-tighter critic_pre_plan execution gate when the critic already returned APPROVED but the mechanical recorder failed to persist it (issue #2012)",agents:["architect"]},prepare_pr_workflow_checkout:{description:"preserve explicit dirty tracked files before an unbound PR workflow checkout with an auditable recovery receipt",agents:["architect"]},run_pr_feedback_stage_a:{description:"execute and persist mandatory PR-feedback Stage A checks on a content-bound revision",agents:["architect"]},submit_council_verdicts:{description:"submit pre-collected council member verdicts for synthesis (architect MUST dispatch critic/reviewer/sme/test_engineer/explorer as Agent tasks first; this tool synthesizes only, it does not contact members)",agents:[]},submit_phase_council_verdicts:{description:"submit pre-collected phase-level council member verdicts for holistic phase synthesis (architect MUST dispatch all 5 council members with phase-scoped context first; this tool synthesizes only, it does not contact members)",agents:[]},declare_council_criteria:{description:"pre-declare acceptance criteria for a task before the coder starts work; criteria are read back during council evaluation",agents:[]},sbom_generate:{description:"SBOM generation for dependency inventory",agents:["architect"]},checkpoint:{description:"create named git checkpoints for save, restore, and delete — use before risky operations to enable rollback",agents:["architect"]},pkg_audit:{description:"dependency vulnerability scan — npm/pip/cargo",agents:["architect","critic_hallucination_verifier","reviewer","critic_finding_validator","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},parse_lane_candidates:{description:"Parse [CANDIDATE] rows from a dispatch_lanes or collect_lane_results artifact (by output_ref), produce structured records with provenance, optionally persist to a per-batch sidecar JSONL. Pure-parser variant exists as internal module.",agents:["architect"]},plan_conflict_check:{description:"read-only advisory check (#1656): compute a pairwise file-conflict matrix for N proposed parallel task groups using declared scopes and optional git co-change; returns a verdict (all_disjoint / conflicts_present / unknown_scopes), per-pair evidence, and a suggested serialization order. Writes nothing — the execution gate independently recomputes the verdict inline at dispatch time via the same helper. Call BEFORE attempting parallel dispatch to confirm disjointness.",agents:["architect"]},write_pr_review_trigger_eval:{description:"persist the complete PR-review trigger evaluation with exact-set validation, dispatch provenance, and live merge-base verification",agents:["architect"]},write_pr_review_artifact:{description:"persist schema-validated PR-review findings checkpoints and exact actionable feedback handoffs under the active run",agents:["architect"]},prepare_pr_feedback_scope:{description:"prepare an exact file scope for one PR-feedback coder Task after immutable feedback verification settles",agents:["architect"]},test_runner:{description:"auto-detect and run tests",agents:["architect","reviewer","critic_finding_validator","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},test_impact:{description:"identify test files impacted by changed source files via import analysis",agents:["architect","reviewer","critic_finding_validator","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},mutation_test:{description:"executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",agents:["architect","test_engineer"]},generate_mutants:{description:"generate LLM-based mutation testing patches for source files; returns MutationPatch[] for direct consumption by the mutation_test tool",agents:["architect"]},detect_domains:{description:"detect which SME domains are relevant for a given text",agents:["architect","sme","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic","critic_oversight","explorer"]},git_blame:{description:"per-line git blame metadata: sha, author, date, summary for each line in a file",agents:["reviewer","critic_finding_validator","explorer","architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},gitingest:{description:"fetch a GitHub repository full content via gitingest.com",agents:["architect","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},retrieve_summary:{description:"retrieve the full content of a stored tool output summary",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","spec_writer","reviewer","critic_finding_validator","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},retrieve_lane_output:{description:"retrieve paged full dispatch lane output by output_ref; use before consuming truncated lane previews or routing candidates from lane results",agents:["architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},extract_code_blocks:{description:"extract code blocks from text content and save them to files",agents:["docs","docs_design","designer","spec_writer","coder","test_engineer"]},phase_complete:{description:"mark a phase as complete and track dispatched agents",agents:["architect"]},save_plan:{description:"save a structured implementation plan",agents:["architect"]},update_task_status:{description:"mark tasks complete, track phase progress",agents:["architect"]},lint_spec:{description:"validate .swarm/spec.md format and required fields",agents:["architect","spec_writer"]},write_retro:{description:"document phase retrospectives via phase_complete workflow, capture lessons learned",agents:["architect"]},write_drift_evidence:{description:"write drift verification evidence for a completed phase",agents:["architect"]},write_hallucination_evidence:{description:"write hallucination verification evidence for a completed phase",agents:["architect"]},write_mutation_evidence:{description:"write mutation gate evidence for a completed phase; normalizes PASS/WARN/FAIL/SKIP verdicts and writes .swarm/evidence/{phase}/mutation-gate.json",agents:["architect"]},declare_scope:{description:"declare file scope for next coder delegation",agents:["architect"]},knowledge_query:{description:"query swarm or hive knowledge with optional filters",agents:["architect","skill_improver","spec_writer"]},doc_scan:{description:"scan project documentation files and build an index manifest",agents:["architect","docs_design","skill_improver","spec_writer","explorer"]},doc_extract:{description:"extract actionable constraints from project documentation",agents:["architect","docs_design","skill_improver","spec_writer"]},curator_analyze:{description:"run curator phase analysis and optionally apply knowledge recommendations",agents:["architect"]},consensus_mine:{description:"mine cross-run consensus from existing .swarm evidence into an immutable proposals-only report; also deletes its own reports past consensus.report_retention, appends to the shared recommendation dedup ledger (in the shared cohort root, outside this project, when a knowledge link is active), and mirrors proposals into pending swarm-memory proposals when memory is enabled",agents:["architect","curator_phase","curator_postmortem"]},knowledge_add:{description:"store a new lesson in the knowledge base",agents:["architect","coder"]},knowledge_recall:{description:"search the knowledge base for relevant past decisions",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic_finding_validator","critic","critic_oversight","explorer","coder","test_engineer"]},knowledge_remove:{description:"delete an outdated swarm knowledge entry by ID (swarm tier only)",agents:["architect"]},co_change_analyzer:{description:"detect hidden couplings by analyzing git history",agents:["architect"]},context_status:{description:"report current context-window headroom for the active session — returns tokens-used, model-limit, usage-percent, threshold-state (none/warn/critical), model name, and provider. Pure read-only: no state mutation, no warning injection. Works whether context_budget.enabled is true or false.",agents:["architect"]},search:{description:"Workspace-scoped ripgrep-style text search with structured JSON output. Supports literal and regex modes, glob filtering, and result limits. NOTE: This is text search, not structural AST search — use symbols and imports tools for structural queries.",agents:["architect","sme","docs","docs_design","designer","critic_hallucination_verifier","skill_improver","spec_writer","reviewer","critic_finding_validator","critic_oversight","explorer","coder","test_engineer","researcher"]},ast_grep:{description:"Read-only structural AST search using ast-grep patterns with optional language and glob filters. Use for syntax-aware code pattern searches; does not rewrite files.",agents:["architect","sme","docs","docs_design","critic_hallucination_verifier","spec_writer","explorer","coder","test_engineer","researcher"]},actionlint_scan:{description:"Run actionlint against GitHub Actions workflow YAML files with structured findings. Resolves actionlint lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},osv_scan:{description:"Run OSV-Scanner against a workspace path and return structured dependency vulnerability findings. Resolves osv-scanner lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},gh_evidence:{description:"Fetch bounded GitHub pull request or issue metadata through gh for review and CI evidence. Resolves gh lazily and is read-only.",agents:["architect","researcher"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},pr_workflow_status:{description:"Read-only architect observation of local git state (HEAD, branch, clean/dirty with a bounded changed-file list, remotes) plus a session-pinned PR workflow gate summary. Use to observe state under the fail-closed PR_REVIEW/PR_FEEDBACK gate. Never executes PR-controlled scripts and never reads another session gate.",agents:["architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},batch_symbols:{description:"Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",agents:["architect","critic_hallucination_verifier","reviewer","critic_finding_validator","critic_oversight","explorer"]},suggest_patch:{description:"Reviewer-safe structured patch suggestion tool. Produces context-anchored patch artifacts without file modification. Returns structured diagnostics on context mismatch.",agents:["architect","reviewer","critic_finding_validator"]},req_coverage:{description:"query requirement coverage status for tracked functional requirements",agents:["critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","critic","critic_oversight"]},get_approved_plan:{description:"retrieve the last critic-approved immutable plan snapshot for baseline drift comparison",agents:["critic_drift_verifier","critic","critic_oversight"]},repo_map:{description:"query the repo code graph: importers, dependencies, blast radius, localization, ontology facts, package boundaries, and heuristic preflight packets before refactoring; ontology findings are advisory, not formal proofs",agents:["architect","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","reviewer","critic_finding_validator","critic","critic_oversight","explorer","coder"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},get_qa_gate_profile:{description:"retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council), lock state, and profile hash. Read-only.",agents:["architect"]},set_qa_gates:{description:"configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only — rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council.",agents:["architect"]},web_search:{description:"External web search (Tavily or Brave) for architect-driven council research, SME domain research, researcher auto-research, and skill-improver research. Returns titled results with snippets, URLs, normalized query metadata, temporal intent, freshness, and removed stale years. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides. Requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents, by SME for opt-in external skill/source evaluation, and by the researcher agent for multi-source auto-research.",agents:["sme","researcher","skill_improver"]},web_fetch:{description:"Fetch the readable text of a single http(s) URL (architect-only). Returns decoded page text, document title, final URL after redirects, and an evidence reference. Reads primary sources that web_search only surfaces as snippets. Config-gated on council.general.enabled. Blocks private/loopback/link-local/metadata addresses (re-validated and re-pinned across redirects); enforces timeout and body size cap.",agents:[]},convene_general_council:{description:"Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",agents:[]},write_final_council_evidence:{description:"Persist project-scoped final council evidence to .swarm/evidence/final-council.json. PREREQUISITE: dispatch critic, reviewer, sme, test_engineer, and explorer as project-scoped Agent tasks and collect their CouncilMemberVerdict JSON — this tool synthesizes only. Rejects on insufficient quorum or CONCERNS with unresolved requiredFixes; normalizes verdicts to approved/concerns/rejected. Architect-only.",agents:[]},skill_generate:{description:"compile knowledge entries into a structured SKILL.md draft",agents:["skill_improver"]},skill_list:{description:"list generated skill files and their status",agents:["skill_improver"]},skill_apply:{description:"activate a draft skill proposal",agents:[]},skill_inspect:{description:"inspect the content and source entries of a skill file",agents:["skill_improver"]},run_stale_reconciliation:{description:"reconcile skills against the knowledge store: mark skills stale when source knowledge is archived or deleted, or clear stale markers",agents:["architect"]},skill_regenerate:{description:"regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",agents:[]},skill_retire:{description:"retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",agents:[]},skill_improve:{description:"run the skill_improver agent to review and refine skills",agents:["skill_improver"]},spec_write:{description:"author or update .swarm/spec.md for the current project",agents:["spec_writer"]},knowledge_receipt:{description:"file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic_finding_validator","critic","coder","test_engineer"]},knowledge_archive:{description:"archive (default), quarantine, or purge a swarm or hive knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",agents:["architect"]},swarm_memory_recall:{description:"recall scoped Swarm memory for the current repository as untrusted background",agents:[]},swarm_memory_propose:{description:"create a pending Swarm memory proposal; does not write durable memory directly",agents:[]},swarm_command:{description:"run supported /swarm commands through the canonical command registry",agents:["architect","sme","researcher","docs","docs_design","designer","reviewer","critic_finding_validator","critic","explorer","coder","test_engineer"]},dispatch_lanes:{description:"dispatch read-only exploration/review lanes concurrently and BLOCK until all finish; prefer dispatch_lanes_async for non-blocking dispatch, use this only when promptAsync is unavailable",agents:["architect"]},dispatch_lanes_async:{description:"launch read-only advisory lanes non-blockingly and return a batch id plus lane session handles immediately so you can keep working; launch_timeout_ms is only a promptAsync acceptance budget, not a lane runtime timeout; poll incrementally with collect_lane_results (wait omitted or false) while doing independent investigation, or join with wait: true when you need all results",agents:["architect"]},collect_lane_results:{description:"collect or poll results for a dispatch_lanes_async batch; supports both non-blocking polling (wait omitted or false) and blocking join (wait: true). Non-blocking polls include pending lane identities by default and process settled lanes incrementally while continuing independent work; busy/retry lanes are not timed out just because they run for a long time. Does not advance workflow gates. Inline output for a settled lane is delivered only once: later polls of the same lane set output_omitted_repeat: true and omit output, but still include output_ref for recovery via retrieve_lane_output.",agents:["architect"]},summarize_work:{description:"emit a short structured summary of completed work (key decisions, assumptions, risks, constraints) at task completion; rolls up per phase for architecture-supervisor review. Advisory, never blocks.",agents:["architect","sme","researcher","docs","docs_design","designer","explorer","coder","test_engineer"]},write_architecture_supervisor_evidence:{description:"persist the architecture supervisor verdict for a phase (architect MUST dispatch critic_architecture_supervisor first and collect its JSON verdict; this tool persists only, it does not contact the supervisor)",agents:["architect"]},lean_turbo_plan_lanes:{description:"partition phase tasks into parallel lanes based on file-scope conflicts for Lean Turbo execution",agents:[]},lean_turbo_acquire_locks:{description:"acquire file locks for all files in a lane (all-or-nothing) before lane execution",agents:[]},lean_turbo_runner_status:{description:"read Lean Turbo run state from .swarm/turbo-state.json",agents:[]},lean_turbo_review:{description:"dispatch a read-only reviewer agent to evaluate a completed Lean Turbo phase",agents:[]},lean_turbo_run_phase:{description:"Execute a phase using Lean Turbo parallel lane execution. Plans lanes, acquires file locks, and dispatches coder agents concurrently. Use when Lean Turbo is active and you want to execute all tasks in a phase in parallel lanes.",agents:[]},lean_turbo_status:{description:"returns Lean Turbo configuration and active status for the current session",agents:[]},swarm_apply_patch:{description:"Apply a unified diff patch to workspace files with exact context matching, atomic writes, and path validation. Use standard unified diff format only — does NOT support *** Begin Patch / *** Update File payloads (use native apply_patch for those).",agents:["coder","test_engineer"]},external_skill_discover:{description:"Discover external skill candidates from configured sources. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_list:{description:"List external skill candidates in the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_inspect:{description:"Inspect a specific external skill candidate by ID. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_promote:{description:"Promote a validated external skill candidate to an active generated skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_reject:{description:"Reject an external skill candidate after evaluation. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_delete:{description:"Delete an external skill candidate from the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_revoke:{description:"Revoke a previously promoted external skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},epic_decide_phase:{description:"Compute the Epic Mode verdict for a phase WITHOUT dispatching coders. Runs preflight + calibration + the three gates (p-threshold, hot-module, greenfield), persists the decision, and returns the verdict so the architect can dispatch waves via the visible Task tool (promote) or fall back to per-task serial (demote). Pair with `epic_plan_waves` to get the wave plan when promoted. Use when /swarm epic is on for the session.",agents:["architect"]},epic_plan_waves:{description:"Partition a phase's pending tasks into ordered concurrent waves for Epic Mode dispatch. A wave is a set of tasks with mutually disjoint declared scopes and all dependencies satisfied by prior waves. Returns `{ waves: [{ waveId, taskIds, files }, ...], serializedTasks, degradedTasks }`. "+'For each wave in order, the architect dispatches one `Task(subagent_type="coder", ...)` per `taskId` — all in one assistant message — so the wave runs concurrently and each coder appears as a visible subagent. '+"Wait for the wave to finish before dispatching the next. Pair with `epic_decide_phase` (called first; this tool is only relevant on a `promote` verdict). "+"Preflight reject reasons: `no-plan`, `no-phase`, `phase-empty`, `phase-already-complete`, `scopes-missing` (call `declare_scope` for `missingScopes`), `git-failed` (transient — retry), `planner-error`.",agents:["architect"]},epic_record_divergence:{description:"After every `update_task_status(completed)`, record the task's declared-vs-actual divergence to .swarm/epic/divergence.jsonl. Feeds Epic Mode's self-calibration loop (Capability D). Best-effort: never blocks.",agents:["architect"]}},TOOL_NAMES=Object.keys(TOOL_METADATA),TOOL_NAME_SET=new Set(TOOL_NAMES);TOOL_DESCRIPTIONS=Object.fromEntries(Object.entries(TOOL_METADATA).map(([name,meta])=>[name,meta.description])),AGENT_TOOL_MAP=(()=>{let map=Object.fromEntries(ALL_AGENT_NAMES.map((agent)=>[agent,[]]));for(let[name,meta]of Object.entries(TOOL_METADATA))for(let agent of meta.agents)map[agent].push(name);return map})()});function deepMergeInternal(base,override,depth){if(depth>=10)throw Error("deepMerge exceeded maximum depth of 10");let result={...base};for(let key of Object.keys(override)){let baseVal=base[key],overrideVal=override[key];if(typeof baseVal==="object"&&baseVal!==null&&typeof overrideVal==="object"&&overrideVal!==null&&!Array.isArray(baseVal)&&!Array.isArray(overrideVal))result[key]=deepMergeInternal(baseVal,overrideVal,depth+1);else result[key]=overrideVal}return result}function deepMerge(base,override){if(!base)return override;if(!override)return base;return deepMergeInternal(base,override,0)}var MAX_MERGE_DEPTH=10;function freezeSet(items){let set=new Set(items),proxy=new Proxy(set,{get(target,prop){if(prop==="add"||prop==="delete"||prop==="clear")return()=>{throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")};if(prop==="forEach")return(callback,thisArg)=>{let wrapped=(v,k)=>callback.call(thisArg??void 0,v,k,proxy);return set.forEach(wrapped)};let value=Reflect.get(target,prop);return typeof value==="function"?value.bind(target):value},set(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},deleteProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},defineProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},setPrototypeOf(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")}});return proxy}function isQAAgent(name){return QA_AGENTS.includes(name)}function isSubagent(name){return ALL_SUBAGENT_NAMES.includes(name)}function isLowCapabilityModel(modelId){let lower=(modelId||"").toLowerCase();return LOW_CAPABILITY_MODELS.some((substr)=>lower.includes(substr))}var OPENCODE_NATIVE_AGENTS,CLAUDE_CODE_NATIVE_COMMANDS,MEMORY_AGENT_TOOL_MAP,EXTERNAL_SKILL_TOOL_NAMES,EXTERNAL_SKILL_AGENT_TOOL_MAP,COUNCIL_TOOL_NAMES,COUNCIL_AGENT_TOOL_MAP,GENERAL_COUNCIL_TOOL_NAMES,GENERAL_COUNCIL_AGENT_TOOL_MAP,TURBO_TOOL_NAMES,TURBO_AGENT_TOOL_MAP,SKILL_TOOL_NAMES,SKILL_AGENT_TOOL_MAP,WRITE_TOOL_NAMES,SUMMARIZER_EXEMPT_TOOL_NAMES,DEFAULT_MODELS,DEFAULT_AGENT_CONFIGS,DEFAULT_SCORING_CONFIG,LOW_CAPABILITY_MODELS,TURBO_MODE_BANNER=`## \uD83D\uDE80 TURBO MODE ACTIVE
|
|
1
|
+
import{createRequire}from"node:module";var __create=Object.create;var{getPrototypeOf:__getProtoOf,defineProperty:__defProp,getOwnPropertyNames:__getOwnPropNames,getOwnPropertyDescriptor:__getOwnPropDesc}=Object,__hasOwnProp=Object.prototype.hasOwnProperty;function __accessProp(key){return this[key]}var __toESMCache_node,__toESMCache_esm,__toESM=(mod,isNodeMode,target)=>{var canCache=mod!=null&&typeof mod==="object";if(canCache){var cache=isNodeMode?__toESMCache_node??=new WeakMap:__toESMCache_esm??=new WeakMap,cached=cache.get(mod);if(cached)return cached}target=mod!=null?__create(__getProtoOf(mod)):{};let to=isNodeMode||!mod||!mod.__esModule?__defProp(target,"default",{value:mod,enumerable:!0}):target;for(let key of __getOwnPropNames(mod))if(!__hasOwnProp.call(to,key))__defProp(to,key,{get:__accessProp.bind(mod,key),enumerable:!0});if(canCache)cache.set(mod,to);return to},__toCommonJS=(from)=>{var entry=(__moduleCache??=new WeakMap).get(from),desc;if(entry)return entry;if(entry=__defProp({},"__esModule",{value:!0}),from&&typeof from==="object"||typeof from==="function"){for(var key of __getOwnPropNames(from))if(!__hasOwnProp.call(entry,key))__defProp(entry,key,{get:__accessProp.bind(from,key),enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return __moduleCache.set(from,entry),entry},__moduleCache,__commonJS=(cb,mod)=>()=>(mod||cb((mod={exports:{}}).exports,mod),mod.exports);var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __esm=(fn2,res)=>()=>(fn2&&(res=fn2(fn2=0)),res);var __require=createRequire(import.meta.url);var package_default;var init_package=__esm(()=>{package_default={name:"opencode-swarm",version:"7.135.5",description:"Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",main:"dist/index.js",types:"dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",default:"./dist/index.js"},"./package.json":"./package.json"},bin:{"opencode-swarm":"./dist/cli/index.js"},type:"module",engines:{bun:">=1.3.13"},license:"MIT",repository:{type:"git",url:"https://github.com/ZaxbyHub/opencode-swarm.git"},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},keywords:["opencode","opencode-plugin","ai","agents","orchestration","swarm","multi-agent","llm"],files:["dist","dist/lang/grammars","binaries","evaluation-fixtures",".opencode/skills/brainstorm",".opencode/skills/specify",".opencode/skills/clarify-spec",".opencode/skills/resume",".opencode/skills/clarify",".opencode/skills/discover",".opencode/skills/consult",".opencode/skills/pre-phase-briefing",".opencode/skills/council",".opencode/skills/deep-dive",".opencode/skills/deep-research",".opencode/skills/codebase-review-swarm",".opencode/skills/swarm-implement",".opencode/skills/design-docs",".opencode/skills/swarm-pr-review",".opencode/skills/swarm",".opencode/skills/swarm-pr-feedback",".opencode/skills/swarm-pr-subscribe",".opencode/skills/swarm-ci-monitor",".opencode/skills/issue-ingest",".opencode/skills/plan",".opencode/skills/critic-gate",".opencode/skills/execute",".opencode/skills/phase-wrap",".opencode/skills/loop",".opencode/skills/writing-tests",".opencode/skills/running-tests",".opencode/skills/engineering-conventions",".opencode/skills/commit-pr",".opencode/skills/ci-failure-batching",".opencode/skills/gate-attribution",".opencode/skills/merge-queue-readiness",".opencode/skills/skill-edit-validation",".opencode/skills/worktree-retry-cleanup",".opencode/skills/test-file-split",".opencode/skills/fork-pr-operations",".opencode/skills/parallel-work-check",".opencode/skills/ci-fix-monitor",".opencode/skills/issue-tracer","tests/fixtures/memory-recall","README.md","LICENSE"],scripts:{clean:`bun -e "require('fs').rmSync('dist',{recursive:true,force:true})"`,build:"bun run clean && bun run scripts/copy-grammars.ts && bun build src/index.ts --outdir dist --target node --format esm --external web-tree-sitter --minify-whitespace --minify-syntax && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external bash-parser --splitting && bun run scripts/copy-grammars.ts --to-dist && tsc --emitDeclarationOnly",typecheck:"tsc --noEmit",test:"bun test",lint:"biome lint .","lint:ci":"biome ci .","test:unit:ci":"bun scripts/ci/run-unit-tests-local.ts","drift:check":"bun run scripts/drift-check.ts","drift:fix":"bun run scripts/drift-check.ts --fix --confirm","skills:sync":"bun run scripts/sync-qa-gate-skills.ts",format:"biome format . --write",check:"biome check --write .",dev:"bun run build && opencode","package:smoke":"node scripts/package-smoke.mjs",prepare:"bun run build","repro:704":"node scripts/repro-704.mjs","repro:1144":"bun scripts/repro-1144.mjs","repro:1873":"bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs"},dependencies:{"@opencode-ai/plugin":"^1.18.3","@opencode-ai/sdk":"^1.18.3","@vscode/tree-sitter-wasm":"^0.3.0","bash-parser":"^0.5.0","p-limit":"^7.3.0",picomatch:"^4.0.4","proper-lockfile":"^4.1.2","quick-lru":"^7.3.0","web-tree-sitter":"^0.25.0",zod:"^4.1.8"},devDependencies:{"@biomejs/biome":"2.3.14","@types/picomatch":"^4.0.3","bun-types":"1.3.8","js-yaml":"^4.1.1",typescript:"^5.7.3"}}});var QA_AGENTS,PIPELINE_AGENTS,ORCHESTRATOR_NAME="architect",ALL_SUBAGENT_NAMES,ALL_AGENT_NAMES;var init_agent_names=__esm(()=>{QA_AGENTS=["reviewer","critic","critic_oversight","critic_finding_validator"],PIPELINE_AGENTS=["explorer","coder","test_engineer"],ALL_SUBAGENT_NAMES=["sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","curator_postmortem","curator_consolidation","council_generalist","council_skeptic","council_domain_expert","skill_improver","spec_writer",...QA_AGENTS,...PIPELINE_AGENTS],ALL_AGENT_NAMES=["architect",...ALL_SUBAGENT_NAMES]});function getPrWorkflowToolCapability(toolName,mode){let metadata=TOOL_METADATA[toolName];if(!metadata?.prWorkflow?.modes.includes(mode))return null;return metadata.prWorkflow.capability}var TOOL_METADATA,TOOL_NAMES,TOOL_NAME_SET,TOOL_DESCRIPTIONS,AGENT_TOOL_MAP;var init_tool_metadata=__esm(()=>{init_agent_names();TOOL_METADATA={diff:{description:"structured git diff with contract change detection",agents:["architect","reviewer","critic_finding_validator","critic_oversight","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},diff_summary:{description:"filter classified AST changes by category, risk level, or file for reviewer drill-down",agents:["architect","reviewer","critic_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},syntax_check:{description:"check syntax of source files using tree-sitter parsers across multiple languages, returning per-file errors",agents:["architect","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},placeholder_scan:{description:"todo and FIXME comment detection",agents:["architect","reviewer","critic_finding_validator"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},imports:{description:"find all consumers that import from a given file — use before refactoring shared modules to avoid breaking unseen dependents",agents:["architect","sme","researcher","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic_finding_validator","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},lint:{description:"run project linter in check or fix mode; supports biome, eslint, ruff, clippy, and more, returns structured results",agents:["architect","reviewer","critic_finding_validator","coder"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},secretscan:{description:"scan for secrets (API keys, tokens, passwords) via regex and entropy; returns redacted previews, excludes common dirs",agents:["architect","reviewer","critic_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},sast_scan:{description:"static analysis security scan",agents:["architect","reviewer","critic_finding_validator","critic_oversight"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},build_check:{description:"discover and run build, typecheck, and test commands for various project ecosystems in the working directory",agents:["architect","coder","test_engineer"]},pre_check_batch:{description:"parallel verification: lint:check + secretscan + sast_scan + quality_budget",agents:["architect","reviewer","critic_finding_validator"]},quality_budget:{description:"code quality budget check",agents:["architect"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},symbols:{description:"extract exported symbols (functions, classes, interfaces, types) from source files; supports TypeScript, JavaScript, and Python",agents:["architect","sme","researcher","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","reviewer","critic_finding_validator","critic","coder","test_engineer"]},complexity_hotspots:{description:"git churn × complexity risk map",agents:["architect","sme","researcher","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","reviewer","critic_finding_validator","critic","critic_oversight","explorer","test_engineer"]},schema_drift:{description:"OpenAPI spec vs route drift",agents:["architect","sme","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},todo_extract:{description:"structured TODO/FIXME extraction",agents:["architect","researcher","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},evidence_check:{description:"verify task evidence completeness",agents:["architect","critic_oversight"]},check_gate_status:{description:"check the gate status of a specific task",agents:["architect","critic_oversight"]},completion_verify:{description:"verify completed tasks have required evidence",agents:["architect","critic_oversight"]},complete_pr_workflow:{description:"validate terminal PR workflow evidence and clear its durable session gate",agents:["architect"]},abort_pr_workflow:{description:"abort an unrecoverable PR_REVIEW/PR_FEEDBACK mechanical gate and clear its durable session state",agents:["architect"]},approve_plan_critic:{description:"record a MANUAL plan_critic_gate approval snapshot to unblock the ratchet-tighter critic_pre_plan execution gate when the critic already returned APPROVED but the mechanical recorder failed to persist it (issue #2012)",agents:["architect"]},prepare_pr_workflow_checkout:{description:"preserve explicit dirty tracked files before an unbound PR workflow checkout with an auditable recovery receipt",agents:["architect"]},run_pr_feedback_stage_a:{description:"execute and persist mandatory PR-feedback Stage A checks on a content-bound revision",agents:["architect"]},submit_council_verdicts:{description:"submit pre-collected council member verdicts for synthesis (architect MUST dispatch critic/reviewer/sme/test_engineer/explorer as Agent tasks first; this tool synthesizes only, it does not contact members)",agents:[]},submit_phase_council_verdicts:{description:"submit pre-collected phase-level council member verdicts for holistic phase synthesis (architect MUST dispatch all 5 council members with phase-scoped context first; this tool synthesizes only, it does not contact members)",agents:[]},declare_council_criteria:{description:"pre-declare acceptance criteria for a task before the coder starts work; criteria are read back during council evaluation",agents:[]},sbom_generate:{description:"SBOM generation for dependency inventory",agents:["architect"]},checkpoint:{description:"create named git checkpoints for save, restore, and delete — use before risky operations to enable rollback",agents:["architect"]},pkg_audit:{description:"dependency vulnerability scan — npm/pip/cargo",agents:["architect","critic_hallucination_verifier","reviewer","critic_finding_validator","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},parse_lane_candidates:{description:"Parse [CANDIDATE] rows from a dispatch_lanes or collect_lane_results artifact (by output_ref), produce structured records with provenance, optionally persist to a per-batch sidecar JSONL. Pure-parser variant exists as internal module.",agents:["architect"]},plan_conflict_check:{description:"read-only advisory check (#1656): compute a pairwise file-conflict matrix for N proposed parallel task groups using declared scopes and optional git co-change; returns a verdict (all_disjoint / conflicts_present / unknown_scopes), per-pair evidence, and a suggested serialization order. Writes nothing — the execution gate independently recomputes the verdict inline at dispatch time via the same helper. Call BEFORE attempting parallel dispatch to confirm disjointness.",agents:["architect"]},write_pr_review_trigger_eval:{description:"persist the complete PR-review trigger evaluation with exact-set validation, dispatch provenance, and live merge-base verification",agents:["architect"]},write_pr_review_artifact:{description:"persist schema-validated PR-review findings checkpoints and exact actionable feedback handoffs under the active run",agents:["architect"]},prepare_pr_feedback_scope:{description:"prepare an exact file scope for one PR-feedback coder Task after immutable feedback verification settles",agents:["architect"]},test_runner:{description:"auto-detect and run tests",agents:["architect","reviewer","critic_finding_validator","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},test_impact:{description:"identify test files impacted by changed source files via import analysis",agents:["architect","reviewer","critic_finding_validator","critic_oversight","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},mutation_test:{description:"executes pre-generated mutation patches against tests, evaluates kill rate against quality gate thresholds",agents:["architect","test_engineer"]},generate_mutants:{description:"generate LLM-based mutation testing patches for source files; returns MutationPatch[] for direct consumption by the mutation_test tool",agents:["architect"]},detect_domains:{description:"detect which SME domains are relevant for a given text",agents:["architect","sme","docs","docs_design","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic","critic_oversight","explorer"]},git_blame:{description:"per-line git blame metadata: sha, author, date, summary for each line in a file",agents:["reviewer","critic_finding_validator","explorer","architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},gitingest:{description:"fetch a GitHub repository full content via gitingest.com",agents:["architect","docs","explorer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},retrieve_summary:{description:"retrieve the full content of a stored tool output summary",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","spec_writer","reviewer","critic_finding_validator","critic","coder","test_engineer"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},retrieve_lane_output:{description:"retrieve paged full dispatch lane output by output_ref; use before consuming truncated lane previews or routing candidates from lane results",agents:["architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},extract_code_blocks:{description:"extract code blocks from text content and save them to files",agents:["docs","docs_design","designer","spec_writer","coder","test_engineer"]},phase_complete:{description:"mark a phase as complete and track dispatched agents",agents:["architect"]},save_plan:{description:"save a structured implementation plan",agents:["architect"]},update_task_status:{description:"mark tasks complete, track phase progress",agents:["architect"]},lint_spec:{description:"validate .swarm/spec.md format and required fields",agents:["architect","spec_writer"]},write_retro:{description:"document phase retrospectives via phase_complete workflow, capture lessons learned",agents:["architect"]},write_drift_evidence:{description:"write drift verification evidence for a completed phase",agents:["architect"]},write_hallucination_evidence:{description:"write hallucination verification evidence for a completed phase",agents:["architect"]},write_mutation_evidence:{description:"write mutation gate evidence for a completed phase; normalizes PASS/WARN/FAIL/SKIP verdicts and writes .swarm/evidence/{phase}/mutation-gate.json",agents:["architect"]},declare_scope:{description:"declare file scope for next coder delegation",agents:["architect"]},knowledge_query:{description:"query swarm or hive knowledge with optional filters",agents:["architect","skill_improver","spec_writer"]},doc_scan:{description:"scan project documentation files and build an index manifest",agents:["architect","docs_design","skill_improver","spec_writer","explorer"]},doc_extract:{description:"extract actionable constraints from project documentation",agents:["architect","docs_design","skill_improver","spec_writer"]},curator_analyze:{description:"run curator phase analysis and optionally apply knowledge recommendations",agents:["architect"]},consensus_mine:{description:"mine cross-run consensus from existing .swarm evidence into an immutable proposals-only report; also deletes its own reports past consensus.report_retention, appends to the shared recommendation dedup ledger (in the shared cohort root, outside this project, when a knowledge link is active), and mirrors proposals into pending swarm-memory proposals when memory is enabled",agents:["architect","curator_phase","curator_postmortem"]},knowledge_add:{description:"store a new lesson in the knowledge base",agents:["architect","coder"]},knowledge_recall:{description:"search the knowledge base for relevant past decisions",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic_finding_validator","critic","critic_oversight","explorer","coder","test_engineer"]},knowledge_remove:{description:"delete an outdated swarm knowledge entry by ID (swarm tier only)",agents:["architect"]},co_change_analyzer:{description:"detect hidden couplings by analyzing git history",agents:["architect"]},context_status:{description:"report current context-window headroom for the active session — returns tokens-used, model-limit, usage-percent, threshold-state (none/warn/critical), model name, and provider. Pure read-only: no state mutation, no warning injection. Works whether context_budget.enabled is true or false.",agents:["architect"]},search:{description:"Workspace-scoped ripgrep-style text search with structured JSON output. Supports literal and regex modes, glob filtering, and result limits. NOTE: This is text search, not structural AST search — use symbols and imports tools for structural queries.",agents:["architect","sme","docs","docs_design","designer","critic_hallucination_verifier","skill_improver","spec_writer","reviewer","critic_finding_validator","critic_oversight","explorer","coder","test_engineer","researcher"]},ast_grep:{description:"Read-only structural AST search using ast-grep patterns with optional language and glob filters. Use for syntax-aware code pattern searches; does not rewrite files.",agents:["architect","sme","docs","docs_design","critic_hallucination_verifier","spec_writer","explorer","coder","test_engineer","researcher"]},actionlint_scan:{description:"Run actionlint against GitHub Actions workflow YAML files with structured findings. Resolves actionlint lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},osv_scan:{description:"Run OSV-Scanner against a workspace path and return structured dependency vulnerability findings. Resolves osv-scanner lazily and does not modify files.",agents:["architect","test_engineer"],prWorkflow:{modes:["PR_REVIEW"],capability:"validate"}},gh_evidence:{description:"Fetch bounded GitHub pull request or issue metadata through gh for review and CI evidence. Resolves gh lazily and is read-only.",agents:["architect","researcher"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},pr_workflow_status:{description:"Read-only architect observation of local git state (HEAD, branch, clean/dirty with a bounded changed-file list, remotes) plus a session-pinned PR workflow gate summary. Use to observe state under the fail-closed PR_REVIEW/PR_FEEDBACK gate. Never executes PR-controlled scripts and never reads another session gate.",agents:["architect"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},batch_symbols:{description:"Batched symbol extraction across multiple files. Returns per-file symbol summaries with isolated error handling.",agents:["architect","critic_hallucination_verifier","reviewer","critic_finding_validator","critic_oversight","explorer"]},suggest_patch:{description:"Reviewer-safe structured patch suggestion tool. Produces context-anchored patch artifacts without file modification. Returns structured diagnostics on context mismatch.",agents:["architect","reviewer","critic_finding_validator"]},req_coverage:{description:"query requirement coverage status for tracked functional requirements",agents:["critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","spec_writer","critic","critic_oversight"]},get_approved_plan:{description:"retrieve the last critic-approved immutable plan snapshot for baseline drift comparison",agents:["critic_drift_verifier","critic","critic_oversight"]},repo_map:{description:"query the repo code graph: importers, dependencies, blast radius, localization, ontology facts, package boundaries, and heuristic preflight packets before refactoring; ontology findings are advisory, not formal proofs",agents:["architect","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","reviewer","critic_finding_validator","critic","critic_oversight","explorer","coder"],prWorkflow:{modes:["PR_REVIEW","PR_FEEDBACK"],capability:"observe"}},get_qa_gate_profile:{description:"retrieve the QA gate profile for the current plan: gates (reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council), lock state, and profile hash. Read-only.",agents:["architect"]},set_qa_gates:{description:"configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only — rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council.",agents:["architect"]},web_search:{description:"External web search (Tavily or Brave) for architect-driven council research, SME domain research, researcher auto-research, and skill-improver research. Returns titled results with snippets, URLs, normalized query metadata, temporal intent, freshness, and removed stale years. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides. Requires a search API key. Used by the architect in MODE: COUNCIL to gather a RESEARCH CONTEXT before dispatching council agents, by SME for opt-in external skill/source evaluation, and by the researcher agent for multi-source auto-research.",agents:["sme","researcher","skill_improver"]},web_fetch:{description:"Fetch the readable text of a single http(s) URL (architect-only). Returns decoded page text, document title, final URL after redirects, and an evidence reference. Reads primary sources that web_search only surfaces as snippets. Config-gated on council.general.enabled. Blocks private/loopback/link-local/metadata addresses (re-validated and re-pinned across redirects); enforces timeout and body size cap.",agents:[]},convene_general_council:{description:"Synthesize responses from a multi-model General Council. Accepts parallel member responses (Round 1, optionally Round 2), detects disagreements, and returns consensus points, persisting disagreements, and a structured synthesis. Architect-only. Config-gated on council.general.enabled in the resolved config: global ~/.config/opencode/opencode-swarm.json, then project .opencode/opencode-swarm.json overrides.",agents:[]},write_final_council_evidence:{description:"Persist project-scoped final council evidence to .swarm/evidence/final-council.json. PREREQUISITE: dispatch critic, reviewer, sme, test_engineer, and explorer as project-scoped Agent tasks and collect their CouncilMemberVerdict JSON — this tool synthesizes only. Rejects on insufficient quorum or CONCERNS with unresolved requiredFixes; normalizes verdicts to approved/concerns/rejected. Architect-only.",agents:[]},skill_generate:{description:"compile knowledge entries into a structured SKILL.md draft",agents:["skill_improver"]},skill_list:{description:"list generated skill files and their status",agents:["skill_improver"]},skill_apply:{description:"activate a draft skill proposal",agents:[]},skill_inspect:{description:"inspect the content and source entries of a skill file",agents:["skill_improver"]},run_stale_reconciliation:{description:"reconcile skills against the knowledge store: mark skills stale when source knowledge is archived or deleted, or clear stale markers",agents:["architect"]},skill_regenerate:{description:"regenerate an active skill by re-clustering its source knowledge entries and updating the SKILL.md in place",agents:[]},skill_retire:{description:"retire a generated skill by adding a retired.marker file; retired skills are excluded from scoring and injection",agents:[]},skill_improve:{description:"run the skill_improver agent to review and refine skills",agents:["skill_improver"]},spec_write:{description:"author or update .swarm/spec.md for the current project",agents:["spec_writer"]},knowledge_receipt:{description:"file a receipt for retrieved knowledge (applied/ignored/contradicted + new lessons), recorded as immutable knowledge events",agents:["architect","sme","docs","docs_design","designer","critic_sounding_board","critic_drift_verifier","critic_hallucination_verifier","critic_architecture_supervisor","curator_init","curator_phase","skill_improver","spec_writer","reviewer","critic_finding_validator","critic","coder","test_engineer"]},knowledge_archive:{description:"archive (default), quarantine, or purge a swarm or hive knowledge entry by ID with an immutable audit tombstone; purge requires an admin flag",agents:["architect"]},swarm_memory_recall:{description:"recall scoped Swarm memory for the current repository as untrusted background",agents:[]},swarm_memory_propose:{description:"create a pending Swarm memory proposal; does not write durable memory directly",agents:[]},swarm_command:{description:"run supported /swarm commands through the canonical command registry",agents:["architect","sme","researcher","docs","docs_design","designer","reviewer","critic_finding_validator","critic","explorer","coder","test_engineer"]},dispatch_lanes:{description:"dispatch read-only exploration/review lanes concurrently and BLOCK until all finish; prefer dispatch_lanes_async for non-blocking dispatch, use this only when promptAsync is unavailable",agents:["architect"]},dispatch_lanes_async:{description:"launch read-only advisory lanes non-blockingly and return a batch id plus lane session handles immediately so you can keep working; launch_timeout_ms is only a promptAsync acceptance budget, not a lane runtime timeout; poll incrementally with collect_lane_results (wait omitted or false) while doing independent investigation, or join with wait: true when you need all results",agents:["architect"]},collect_lane_results:{description:"collect or poll results for a dispatch_lanes_async batch; supports both non-blocking polling (wait omitted or false) and blocking join (wait: true). Non-blocking polls include pending lane identities by default and process settled lanes incrementally while continuing independent work; busy/retry lanes are not timed out just because they run for a long time. Does not advance workflow gates. Inline output for a settled lane is delivered only once: later polls of the same lane set output_omitted_repeat: true and omit output, but still include output_ref for recovery via retrieve_lane_output.",agents:["architect"]},summarize_work:{description:"emit a short structured summary of completed work (key decisions, assumptions, risks, constraints) at task completion; rolls up per phase for architecture-supervisor review. Advisory, never blocks.",agents:["architect","sme","researcher","docs","docs_design","designer","explorer","coder","test_engineer"]},write_architecture_supervisor_evidence:{description:"persist the architecture supervisor verdict for a phase (architect MUST dispatch critic_architecture_supervisor first and collect its JSON verdict; this tool persists only, it does not contact the supervisor)",agents:["architect"]},lean_turbo_plan_lanes:{description:"partition phase tasks into parallel lanes based on file-scope conflicts for Lean Turbo execution",agents:[]},lean_turbo_acquire_locks:{description:"acquire file locks for all files in a lane (all-or-nothing) before lane execution",agents:[]},lean_turbo_runner_status:{description:"read Lean Turbo run state from .swarm/turbo-state.json",agents:[]},lean_turbo_review:{description:"dispatch a read-only reviewer agent to evaluate a completed Lean Turbo phase",agents:[]},lean_turbo_run_phase:{description:"Execute a phase using Lean Turbo parallel lane execution. Plans lanes, acquires file locks, and dispatches coder agents concurrently. Use when Lean Turbo is active and you want to execute all tasks in a phase in parallel lanes.",agents:[]},lean_turbo_status:{description:"returns Lean Turbo configuration and active status for the current session",agents:[]},swarm_apply_patch:{description:"Apply a unified diff patch to workspace files with exact context matching, atomic writes, and path validation. Use standard unified diff format only — does NOT support *** Begin Patch / *** Update File payloads (use native apply_patch for those).",agents:["coder","test_engineer"]},external_skill_discover:{description:"Discover external skill candidates from configured sources. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_list:{description:"List external skill candidates in the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_inspect:{description:"Inspect a specific external skill candidate by ID. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_promote:{description:"Promote a validated external skill candidate to an active generated skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_reject:{description:"Reject an external skill candidate after evaluation. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_delete:{description:"Delete an external skill candidate from the quarantine store. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},external_skill_revoke:{description:"Revoke a previously promoted external skill. Returns a disabled message when external_skills.curation_enabled is false.",agents:[]},epic_decide_phase:{description:"Compute the Epic Mode verdict for a phase WITHOUT dispatching coders. Runs preflight + calibration + the three gates (p-threshold, hot-module, greenfield), persists the decision, and returns the verdict so the architect can dispatch waves via the visible Task tool (promote) or fall back to per-task serial (demote). Pair with `epic_plan_waves` to get the wave plan when promoted. Use when /swarm epic is on for the session.",agents:["architect"]},epic_plan_waves:{description:"Partition a phase's pending tasks into ordered concurrent waves for Epic Mode dispatch. A wave is a set of tasks with mutually disjoint declared scopes and all dependencies satisfied by prior waves. Returns `{ waves: [{ waveId, taskIds, files }, ...], serializedTasks, degradedTasks }`. "+'For each wave in order, the architect dispatches one `Task(subagent_type="coder", ...)` per `taskId` — all in one assistant message — so the wave runs concurrently and each coder appears as a visible subagent. '+"Wait for the wave to finish before dispatching the next. Pair with `epic_decide_phase` (called first; this tool is only relevant on a `promote` verdict). "+"Preflight reject reasons: `no-plan`, `no-phase`, `phase-empty`, `phase-already-complete`, `scopes-missing` (call `declare_scope` for `missingScopes`), `git-failed` (transient — retry), `planner-error`.",agents:["architect"]},epic_record_divergence:{description:"After every `update_task_status(completed)`, record the task's declared-vs-actual divergence to .swarm/epic/divergence.jsonl. Feeds Epic Mode's self-calibration loop (Capability D). Best-effort: never blocks.",agents:["architect"]}},TOOL_NAMES=Object.keys(TOOL_METADATA),TOOL_NAME_SET=new Set(TOOL_NAMES);TOOL_DESCRIPTIONS=Object.fromEntries(Object.entries(TOOL_METADATA).map(([name,meta])=>[name,meta.description])),AGENT_TOOL_MAP=(()=>{let map=Object.fromEntries(ALL_AGENT_NAMES.map((agent)=>[agent,[]]));for(let[name,meta]of Object.entries(TOOL_METADATA))for(let agent of meta.agents)map[agent].push(name);return map})()});function deepMergeInternal(base,override,depth){if(depth>=10)throw Error("deepMerge exceeded maximum depth of 10");let result={...base};for(let key of Object.keys(override)){let baseVal=base[key],overrideVal=override[key];if(typeof baseVal==="object"&&baseVal!==null&&typeof overrideVal==="object"&&overrideVal!==null&&!Array.isArray(baseVal)&&!Array.isArray(overrideVal))result[key]=deepMergeInternal(baseVal,overrideVal,depth+1);else result[key]=overrideVal}return result}function deepMerge(base,override){if(!base)return override;if(!override)return base;return deepMergeInternal(base,override,0)}var MAX_MERGE_DEPTH=10;function freezeSet(items){let set=new Set(items),proxy=new Proxy(set,{get(target,prop){if(prop==="add"||prop==="delete"||prop==="clear")return()=>{throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")};if(prop==="forEach")return(callback,thisArg)=>{let wrapped=(v,k)=>callback.call(thisArg??void 0,v,k,proxy);return set.forEach(wrapped)};let value=Reflect.get(target,prop);return typeof value==="function"?value.bind(target):value},set(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},deleteProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},defineProperty(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")},setPrototypeOf(){throw TypeError("CLAUDE_CODE_NATIVE_COMMANDS is readonly")}});return proxy}function isQAAgent(name){return QA_AGENTS.includes(name)}function isSubagent(name){return ALL_SUBAGENT_NAMES.includes(name)}function isLowCapabilityModel(modelId){let lower=(modelId||"").toLowerCase();return LOW_CAPABILITY_MODELS.some((substr)=>lower.includes(substr))}var OPENCODE_NATIVE_AGENTS,CLAUDE_CODE_NATIVE_COMMANDS,MEMORY_AGENT_TOOL_MAP,EXTERNAL_SKILL_TOOL_NAMES,EXTERNAL_SKILL_AGENT_TOOL_MAP,COUNCIL_TOOL_NAMES,COUNCIL_AGENT_TOOL_MAP,GENERAL_COUNCIL_TOOL_NAMES,GENERAL_COUNCIL_AGENT_TOOL_MAP,TURBO_TOOL_NAMES,TURBO_AGENT_TOOL_MAP,SKILL_TOOL_NAMES,SKILL_AGENT_TOOL_MAP,WRITE_TOOL_NAMES,SUMMARIZER_EXEMPT_TOOL_NAMES,DEFAULT_MODELS,DEFAULT_AGENT_CONFIGS,DEFAULT_SCORING_CONFIG,LOW_CAPABILITY_MODELS,TURBO_MODE_BANNER=`## \uD83D\uDE80 TURBO MODE ACTIVE
|
|
2
2
|
|
|
3
3
|
**Speed optimization enabled for this session.**
|
|
4
4
|
|
|
@@ -182,7 +182,7 @@ ${trimmed}`}else malformedRows++;continue}let rowFields=fields.slice(0,CANDIDATE
|
|
|
182
182
|
`)){let trimmed=line.trim();if(trimmed.length===0)continue;let fields=trimmed.split("\t");if(fields.length<3)return null;let added=fields[0]==="-"?0:Number.parseInt(fields[0],10),deleted=fields[1]==="-"?0:Number.parseInt(fields[1],10);if(Number.isNaN(added)||Number.isNaN(deleted))return null;changedFiles+=1,changedLines+=added+deleted}let rawOutput=await runGitAsync(directory,["diff","--raw",range]);if(rawOutput===null)return null;let hasSubmoduleChange=rawOutput.split(`
|
|
183
183
|
`).some((line)=>GITLINK_MODE_PATTERN.test(line.trim()));return{changedLines,changedFiles,hasSubmoduleChange}}function isSafeGitRevisionToken(value){return/^(?!-)[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$/.test(value)&&!value.includes("..")&&!value.includes("//")&&!value.includes("@{")}function resolveCurrentUpstreamRemoteRef(directory){let upstream=runGit(directory,["rev-parse","--symbolic-full-name","@{upstream}"]);if(!upstream?.startsWith("refs/remotes/")||upstream.endsWith("/HEAD"))return null;return upstream}function resolveCurrentUpstreamPushTarget(directory){let localBranchRef=runGit(directory,["symbolic-ref","--quiet","HEAD"]);if(!localBranchRef?.startsWith("refs/heads/"))return null;let encoded=runGit(directory,["for-each-ref","--format=%(upstream:remotename)%00%(upstream:remoteref)%00%(upstream)",localBranchRef]);if(!encoded)return null;let[remoteName,remoteBranchRef,remoteTrackingRef,...extras]=encoded.split("\x00");if(extras.length>0||!remoteName||remoteName.startsWith("-")||/[\s;&|<>`]/.test(remoteName)||!remoteBranchRef?.startsWith("refs/heads/")||remoteBranchRef==="refs/heads/"||/[\s;&|<>`]/.test(remoteBranchRef)||!remoteTrackingRef?.startsWith("refs/remotes/")||remoteTrackingRef.endsWith("/HEAD"))return null;return{remoteName,remoteBranchRef,remoteTrackingRef}}async function resolveCurrentUpstreamPushTargetAsync(directory){let localBranchRef=await runGitAsync(directory,["symbolic-ref","--quiet","HEAD"]);if(!localBranchRef?.startsWith("refs/heads/"))return null;let encoded=await runGitAsync(directory,["for-each-ref","--format=%(upstream:remotename)%00%(upstream:remoteref)%00%(upstream)",localBranchRef]);if(!encoded)return null;let[remoteName,remoteBranchRef,remoteTrackingRef,...extras]=encoded.split("\x00");if(extras.length>0||!remoteName||remoteName.startsWith("-")||/[\s;&|<>`]/.test(remoteName)||!remoteBranchRef?.startsWith("refs/heads/")||remoteBranchRef==="refs/heads/"||/[\s;&|<>`]/.test(remoteBranchRef)||!remoteTrackingRef?.startsWith("refs/remotes/")||remoteTrackingRef.endsWith("/HEAD"))return null;return{remoteName,remoteBranchRef,remoteTrackingRef}}function resolveExactRemoteBranchHead(directory,remoteName,remoteBranchRef){if(!remoteName||remoteName.startsWith("-")||/[\s;&|<>`]/.test(remoteName)||!remoteBranchRef.startsWith("refs/heads/")||remoteBranchRef==="refs/heads/"||/[\s;&|<>`]/.test(remoteBranchRef))return null;let output=runGit(directory,["ls-remote","--exit-code","--heads",remoteName,remoteBranchRef],20000);if(!output)return null;let rows=output.split(/\r?\n/).filter(Boolean);if(rows.length!==1)return null;let[objectName,refName,...extras]=rows[0].split(/\s+/);if(extras.length>0||refName!==remoteBranchRef||!objectName||!(/^[0-9a-f]{40}$/i.test(objectName)||/^[0-9a-f]{64}$/i.test(objectName)))return null;return objectName}async function resolveExactRemoteBranchHeadAsync(directory,remoteName,remoteBranchRef){if(!remoteName||remoteName.startsWith("-")||/[\s;&|<>`]/.test(remoteName)||!remoteBranchRef.startsWith("refs/heads/")||remoteBranchRef==="refs/heads/"||/[\s;&|<>`]/.test(remoteBranchRef))return null;let output=await runGitAsync(directory,["ls-remote","--exit-code","--heads",remoteName,remoteBranchRef],20000);if(!output)return null;let rows=output.split(/\r?\n/).filter(Boolean);if(rows.length!==1)return null;let[objectName,refName,...extras]=rows[0].split(/\s+/);if(extras.length>0||refName!==remoteBranchRef||!objectName||!(/^[0-9a-f]{40}$/i.test(objectName)||/^[0-9a-f]{64}$/i.test(objectName)))return null;return objectName}function resolveGitControlStateDigest(directory){let head=runGit(directory,["rev-parse","--verify","HEAD^{commit}"]),symbolicHead=runGit(directory,["symbolic-ref","--quiet","HEAD"]),upstream=resolveCurrentUpstreamPushTarget(directory),refs=runGit(directory,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/remotes","refs/tags"]),config2=runGit(directory,["config","--null","--show-origin","--show-scope","--list"]),index=runGit(directory,["ls-files","--stage","-z"]);if(head===null||symbolicHead===null||!upstream||refs===null||config2===null||index===null)return null;return digest(`head\x00${head}\x00symbolic\x00${symbolicHead}\x00upstream\x00${upstream.remoteName}\x00${upstream.remoteBranchRef}\x00${upstream.remoteTrackingRef}\x00refs\x00${refs}\x00config\x00${config2}\x00index\x00${index}`)}async function resolveGitControlStateDigestAsync(directory){let head=await runGitAsync(directory,["rev-parse","--verify","HEAD^{commit}"]),symbolicHead=await runGitAsync(directory,["symbolic-ref","--quiet","HEAD"]),upstream=await resolveCurrentUpstreamPushTargetAsync(directory),refs=await runGitAsync(directory,["for-each-ref","--format=%(refname)%00%(objectname)","refs/heads","refs/remotes","refs/tags"]),config2=await runGitAsync(directory,["config","--null","--show-origin","--show-scope","--list"]),index=await runGitAsync(directory,["ls-files","--stage","-z"]);if(head===null||symbolicHead===null||!upstream||refs===null||config2===null||index===null)return null;return digest(`head\x00${head}\x00symbolic\x00${symbolicHead}\x00upstream\x00${upstream.remoteName}\x00${upstream.remoteBranchRef}\x00${upstream.remoteTrackingRef}\x00refs\x00${refs}\x00config\x00${config2}\x00index\x00${index}`)}function resolveIsWorkingTreeClean(directory){let status=runGit(directory,["status","--porcelain=v1","--untracked-files=all"]);return status===null?null:status.length===0}async function resolveIsWorkingTreeCleanAsync(directory){let status=await runGitAsync(directory,["status","--porcelain=v1","--untracked-files=all"]);return status===null?null:status.length===0}function resolveCommitCountSince(directory,baseHeadSha,currentHeadSha){if(!isSafeGitRevisionToken(baseHeadSha)||!isSafeGitRevisionToken(currentHeadSha))return null;let output=runGit(directory,["rev-list","--count","--ancestry-path",`${baseHeadSha}..${currentHeadSha}`,"--"]);if(!output||!/^\d+$/.test(output))return null;let count=Number(output);return Number.isSafeInteger(count)?count:null}async function resolveCommitCountSinceAsync(directory,baseHeadSha,currentHeadSha){if(!isSafeGitRevisionToken(baseHeadSha)||!isSafeGitRevisionToken(currentHeadSha))return null;let output=await runGitAsync(directory,["rev-list","--count","--ancestry-path",`${baseHeadSha}..${currentHeadSha}`,"--"]);if(!output||!/^\d+$/.test(output))return null;let count=Number(output);return Number.isSafeInteger(count)?count:null}function resolveIsExactSingleChildCommit(directory,baseHeadSha,currentHeadSha){if(!isSafeGitRevisionToken(baseHeadSha)||!isSafeGitRevisionToken(currentHeadSha))return null;let base=runGit(directory,["rev-parse","--verify",`${baseHeadSha}^{commit}`,"--"]),current=runGit(directory,["rev-parse","--verify",`${currentHeadSha}^{commit}`,"--"]);if(!base||!current)return null;let commitAndParents=runGit(directory,["rev-list","--parents","-n","1",current]);if(commitAndParents===null)return null;let fields=commitAndParents.trim().split(/\s+/);return fields.length===2&&fields[0]?.toLowerCase()===current.toLowerCase()&&fields[1]?.toLowerCase()===base.toLowerCase()}async function resolveIsExactSingleChildCommitAsync(directory,baseHeadSha,currentHeadSha){if(!isSafeGitRevisionToken(baseHeadSha)||!isSafeGitRevisionToken(currentHeadSha))return null;let base=await runGitAsync(directory,["rev-parse","--verify",`${baseHeadSha}^{commit}`,"--"]),current=await runGitAsync(directory,["rev-parse","--verify",`${currentHeadSha}^{commit}`,"--"]);if(!base||!current)return null;let commitAndParents=await runGitAsync(directory,["rev-list","--parents","-n","1",current]);if(commitAndParents===null)return null;let fields=commitAndParents.trim().split(/\s+/);return fields.length===2&&fields[0]?.toLowerCase()===current.toLowerCase()&&fields[1]?.toLowerCase()===base.toLowerCase()}function resolveRemoteRefsContainingHead(directory,headSha){let output=runGit(directory,["for-each-ref","--format=%(refname)%09%(objectname)","refs/remotes"]);if(output===null)return null;return output.split(/\r?\n/).map((line)=>line.trim().split("\t")).filter(([ref,objectName])=>ref?.startsWith("refs/remotes/")&&!ref.endsWith("/HEAD")&&objectName?.toLowerCase()===headSha.toLowerCase()).map(([ref])=>ref)}async function resolveRemoteRefsContainingHeadAsync(directory,headSha){let output=await runGitAsync(directory,["for-each-ref","--format=%(refname)%09%(objectname)","refs/remotes"]);if(output===null)return null;return output.split(/\r?\n/).map((line)=>line.trim().split("\t")).filter(([ref,objectName])=>ref?.startsWith("refs/remotes/")&&!ref.endsWith("/HEAD")&&objectName?.toLowerCase()===headSha.toLowerCase()).map(([ref])=>ref)}async function resolvePrFeedbackTrackingCandidatesAsync(directory,headSha){let[localOutput,remoteRefs]=await Promise.all([runGitAsync(directory,["for-each-ref","--format=%(refname)%09%(objectname)%09%(upstream)","refs/heads"]),resolveRemoteRefsContainingHeadAsync(directory,headSha)]);if(localOutput===null||remoteRefs===null)return null;let exactRemoteRefs=new Set(remoteRefs);return{local:localOutput.split(/\r?\n/).map((line)=>line.trim().split("\t")).flatMap(([ref,objectName,upstream,...extras])=>{if(extras.length>0||!ref?.startsWith("refs/heads/")||objectName?.toLowerCase()!==headSha.toLowerCase()||!upstream?.startsWith("refs/remotes/")||!exactRemoteRefs.has(upstream))return[];return[{kind:"local",branchName:ref.slice(11),remoteTrackingRef:upstream}]}),remote:remoteRefs.map((remoteTrackingRef)=>({kind:"remote",remoteTrackingRef}))}}async function switchPrFeedbackTrackingCandidateAsync(directory,candidate){let args2=candidate.kind==="local"?["switch","--no-guess","--",candidate.branchName]:["switch","--track","--",candidate.remoteTrackingRef];return await runGitAsync(directory,args2)!==null}function resolvePrWorkflowRevisionDigest(directory,baseHeadSha){let projectRoot=path11.resolve(directory),baseHead=runGit(projectRoot,["rev-parse","--verify",`${baseHeadSha}^{commit}`]),diffNames=runGit(projectRoot,["diff","--no-ext-diff","--name-only","-z",baseHeadSha]),porcelain=runGit(projectRoot,["status","--porcelain=v1","-z","--untracked-files=all"]);if(!baseHead||diffNames===null||porcelain===null)return null;let porcelainPaths=parsePorcelainPaths(porcelain);if(!porcelainPaths)return null;let changedPaths=[...new Set([...parseNulPaths(diffNames),...porcelainPaths])].sort((left,right)=>left.localeCompare(right));if(changedPaths.length>REVISION_MAX_FILES)return null;let hash2=createHash6("sha256");hash2.update(`base\x00${baseHead}\x00`);let totalBytes=0;for(let relativePath of changedPaths){let resolvedPath=path11.resolve(projectRoot,relativePath),relativeToRoot=path11.relative(projectRoot,resolvedPath);if(!relativeToRoot||relativeToRoot.startsWith("..")||path11.isAbsolute(relativeToRoot))return null;hash2.update(`path\x00${relativePath}\x00`);let stats2;try{stats2=fs7.lstatSync(resolvedPath)}catch(error49){if(error49.code==="ENOENT"){hash2.update("deleted\x00");continue}return null}if(stats2.isSymbolicLink())try{hash2.update(`symlink\x00${fs7.readlinkSync(resolvedPath)}\x00`);continue}catch{return null}if(!stats2.isFile()){hash2.update(`node\x00${stats2.mode}\x00`);continue}if(totalBytes+=stats2.size,totalBytes>REVISION_MAX_TOTAL_BYTES)return null;try{hash2.update(`file\x00${stats2.mode}\x00`),hash2.update(fs7.readFileSync(resolvedPath)),hash2.update("\x00")}catch{return null}}return hash2.digest("hex")}async function resolvePrWorkflowRevisionDigestAsync(directory,baseHeadSha){let projectRoot=path11.resolve(directory),[baseHead,diffNames,porcelain]=await Promise.all([runGitAsync(projectRoot,["rev-parse","--verify",`${baseHeadSha}^{commit}`]),runGitAsync(projectRoot,["diff","--no-ext-diff","--name-only","-z",baseHeadSha]),runGitAsync(projectRoot,["status","--porcelain=v1","-z","--untracked-files=all"])]);if(!baseHead||diffNames===null||porcelain===null)return null;let porcelainPaths=parsePorcelainPaths(porcelain);if(!porcelainPaths)return null;let changedPaths=[...new Set([...parseNulPaths(diffNames),...porcelainPaths])].sort((left,right)=>left.localeCompare(right));if(changedPaths.length>REVISION_MAX_FILES)return null;let hash2=createHash6("sha256");hash2.update(`base\x00${baseHead}\x00`);let totalBytes=0,chunksSinceYield=0;for(let relativePath of changedPaths){let resolvedPath=path11.resolve(projectRoot,relativePath),relativeToRoot=path11.relative(projectRoot,resolvedPath);if(!relativeToRoot||relativeToRoot.startsWith("..")||path11.isAbsolute(relativeToRoot))return null;hash2.update(`path\x00${relativePath}\x00`);let stats2;try{stats2=await fs7.promises.lstat(resolvedPath)}catch(error49){if(error49.code==="ENOENT"){hash2.update("deleted\x00");continue}return null}if(stats2.isSymbolicLink())try{hash2.update(`symlink\x00${await fs7.promises.readlink(resolvedPath)}\x00`);continue}catch{return null}if(!stats2.isFile()){hash2.update(`node\x00${stats2.mode}\x00`);continue}if(totalBytes+=stats2.size,totalBytes>REVISION_MAX_TOTAL_BYTES)return null;hash2.update(`file\x00${stats2.mode}\x00`);let handle;try{handle=await fs7.promises.open(resolvedPath,"r");let buffer=Buffer.allocUnsafe(REVISION_READ_CHUNK_BYTES);for(let position=0;position<stats2.size;){let length=Math.min(REVISION_READ_CHUNK_BYTES,stats2.size-position),{bytesRead}=await handle.read(buffer,0,length,position);if(bytesRead<=0)return null;if(hash2.update(buffer.subarray(0,bytesRead)),position+=bytesRead,chunksSinceYield++,chunksSinceYield>=REVISION_YIELD_EVERY_CHUNKS)chunksSinceYield=0,await _internals6.yieldControl()}hash2.update("\x00")}catch{return null}finally{await handle?.close().catch(()=>{return})}}return hash2.digest("hex")}function parseNulPaths(output){return output.split("\x00").filter((entry)=>entry.length>0)}function parsePorcelainPaths(output){let entries=parseNulPaths(output),paths=[];for(let index=0;index<entries.length;index++){let entry=entries[index];if(entry.length<4||entry[2]!==" ")return null;let status=entry.slice(0,2),changedPath=entry.slice(3);if(!changedPath)return null;if(paths.push(changedPath),status.includes("R")||status.includes("C")){let originalPath=entries[++index];if(!originalPath)return null;paths.push(originalPath)}}return[...new Set(paths)]}function parsePorcelainV2Snapshot(output){let records=output.split("\x00"),headers=[];while(records[0]?.startsWith("# "))headers.push(records.shift());let oidMatch=headers.join(`
|
|
184
184
|
`).match(/^# branch\.oid (.+)$/m);if(!oidMatch)return null;if(!/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i.test(oidMatch[1])&&oidMatch[1]!=="(initial)")return null;let gitHead=oidMatch[1]==="(initial)"?null:oidMatch[1],dirtyTrackedPaths=[],untrackedPaths=[],unmergedPaths=[],unmergedCodes=[],dirtySubmodulePaths=[],renameOrCopy=!1;for(let index=0;index<records.length;index++){let record2=records[index];if(!record2)continue;if(record2.startsWith("? ")){untrackedPaths.push(record2.slice(2));continue}if(record2.startsWith("1 ")){let fields=record2.split(" "),changedPath=porcelainV2PathAfterFields(record2,8);if(!changedPath||!fields[2])return null;if(dirtyTrackedPaths.push(changedPath),fields[2]!=="N...")dirtySubmodulePaths.push(changedPath);continue}if(record2.startsWith("2 ")){let fields=record2.split(" "),changedPath=porcelainV2PathAfterFields(record2,9),originalPath=records[++index];if(!changedPath||!originalPath||!fields[2])return null;if(renameOrCopy=!0,dirtyTrackedPaths.push(changedPath,originalPath),fields[2]!=="N...")dirtySubmodulePaths.push(changedPath);continue}if(record2.startsWith("u ")){let fields=record2.split(" "),changedPath=porcelainV2PathAfterFields(record2,10),unmergedCode=fields[1];if(!changedPath||!fields[2]||!unmergedCode||!/^(?:DD|AU|UD|UA|DU|AA|UU)$/.test(unmergedCode))return null;if(unmergedPaths.push(changedPath),unmergedCodes.push(unmergedCode),dirtyTrackedPaths.push(changedPath),fields[2]!=="N...")dirtySubmodulePaths.push(changedPath);continue}return null}return{gitHead,dirtyTrackedPaths:[...new Set(dirtyTrackedPaths)],untrackedPaths:[...new Set(untrackedPaths)],renameOrCopy,unmergedPaths:[...new Set(unmergedPaths)],unmergedCodes:[...new Set(unmergedCodes)],dirtySubmodulePaths:[...new Set(dirtySubmodulePaths)]}}function porcelainV2PathAfterFields(record2,fields){let offset=0;for(let index=0;index<fields;index++){let delimiter=record2.indexOf(" ",offset);if(delimiter<0)return null;offset=delimiter+1}return record2.slice(offset)||null}function captureWorkspaceSnapshot(directory,optionsOrScope=null,prHeadShaArg=null){let scope=typeof optionsOrScope==="object"&&optionsOrScope!==null?optionsOrScope.scope??null:optionsOrScope,configuredPrHeadSha=(()=>{if(typeof optionsOrScope!=="object"||optionsOrScope===null)return prHeadShaArg;return optionsOrScope.prHeadSha??null})(),resolveCurrentPrHeadSha=typeof optionsOrScope==="object"&&optionsOrScope!==null&&optionsOrScope.resolveCurrentPrHeadSha===!0,upstreamBefore=resolveCurrentPrHeadSha?runGit(directory,["rev-parse","@{upstream}"]):null,porcelain=runGit(directory,["status","--porcelain=v2","--branch","-z","--untracked-files=all"]),snapshot=porcelain===null?null:parsePorcelainV2Snapshot(porcelain),upstreamAfter=resolveCurrentPrHeadSha?runGit(directory,["rev-parse","@{upstream}"]):null,prHeadSha=resolveCurrentPrHeadSha?upstreamBefore&&upstreamBefore===upstreamAfter?upstreamBefore:null:configuredPrHeadSha;return{directory:path11.resolve(directory),gitHead:snapshot?.gitHead??null,dirtyHash:porcelain===null?null:digest(porcelain),changedFiles:snapshot?[...new Set([...snapshot.dirtyTrackedPaths,...snapshot.untrackedPaths])]:null,prHeadSha,scope}}function changedFilesSinceSnapshot(directory,baseline){if(!baseline?.gitHead||baseline.changedFiles==null)return null;if(baseline.changedFiles.length>0)return null;let current=captureWorkspaceSnapshot(directory);if(!current.gitHead||current.changedFiles==null)return null;let changed=new Set(current.changedFiles);if(baseline.gitHead!==current.gitHead){let committed=runGit(directory,["diff","--name-only","-z",baseline.gitHead,current.gitHead]);if(committed===null)return null;for(let changedPath of parseNulPaths(committed))changed.add(changedPath)}return[...changed]}function workspaceSnapshotMatches(expected,current){if(!expected)return{ok:!0};if(path11.resolve(expected.directory)!==path11.resolve(current.directory))return{ok:!1,reason:`directory changed: expected ${expected.directory}, got ${current.directory}`};let checks3=["gitHead","dirtyHash","prHeadSha"];for(let key of checks3){let expectedValue=expected[key];if(expectedValue===null)continue;if(current[key]!==expectedValue)return{ok:!1,reason:`${key} changed: expected ${expectedValue}, got ${current[key]??"unknown"}`}}return{ok:!0}}function compareWorkspaceSnapshots(expected,current){let result=workspaceSnapshotMatches(expected,current);if(result.ok)return{stale:!1};return{stale:!0,reason:result.reason}}function digest(text){return createHash6("sha256").update(text).digest("hex")}var GIT_SNAPSHOT_TIMEOUT_MS=3000,GIT_SNAPSHOT_MAX_BUFFER=524288,REVISION_MAX_FILES=5000,REVISION_MAX_TOTAL_BYTES=67108864,REVISION_READ_CHUNK_BYTES=65536,REVISION_YIELD_EVERY_CHUNKS=16,GITLINK_MODE_PATTERN,compareWorkspaceSnapshot,_internals6;var init_workspace_snapshot=__esm(()=>{init_bun_compat();GITLINK_MODE_PATTERN=/^:\d{6} 160000 |^:160000 \d{6} /;compareWorkspaceSnapshot=workspaceSnapshotMatches;_internals6={spawnSync:child_process.spawnSync,bunSpawn,gitTimeoutMs:GIT_SNAPSHOT_TIMEOUT_MS,yieldControl:()=>new Promise((resolve7)=>setImmediate(resolve7)),parsePorcelainV2Snapshot}});import*as fs8 from"node:fs";import*as path12 from"node:path";function isExecutableFile(candidate){try{return fs8.statSync(candidate).isFile()}catch{return!1}}function resolveExecutableFromPath(names,envPath=process.env.PATH??"",platform=process.platform){let pathEntries=envPath.split(path12.delimiter).filter(Boolean),isWindows=platform==="win32";for(let rawName of names){if(!rawName)continue;if(path12.isAbsolute(rawName)&&isExecutableFile(rawName))return rawName;let extensions=isWindows&&path12.extname(rawName)===""?DEFAULT_WINDOWS_EXTENSIONS:[""];for(let dir of pathEntries)for(let ext of extensions){let candidate=path12.join(dir,`${rawName}${ext}`);if(isExecutableFile(candidate))return candidate}}return null}async function readBoundedStream(stream,maxBytes){let reader=stream.getReader(),lockReleased=!1,releaseLock=()=>{if(lockReleased)return;lockReleased=!0;try{reader.releaseLock()}catch{}},cancelAndRelease=async()=>{try{await reader.cancel()}catch{}finally{releaseLock()}};if(maxBytes<=0)return await cancelAndRelease(),{text:"",truncated:!0};let chunks=[],total=0,truncated=!1;try{for(;;){let{done,value}=await reader.read();if(done)break;if(!value)continue;let remaining=maxBytes-total;if(value.byteLength>remaining){if(remaining>0)chunks.push(value.slice(0,remaining)),total+=remaining;truncated=!0,await cancelAndRelease();break}chunks.push(value),total+=value.byteLength}}finally{releaseLock()}let out=new Uint8Array(total),offset=0;for(let chunk of chunks)out.set(chunk,offset),offset+=chunk.byteLength;return{text:new TextDecoder().decode(out),truncated}}function timeoutKillSignal(platform){return platform==="win32"?"SIGTERM":"SIGKILL"}function killProcess(proc){try{proc?.kill(timeoutKillSignal(_internals7.platform()))}catch{}}async function runExternalTool(options){if(!path12.isAbsolute(options.cwd))return{status:"spawn-error",exitCode:null,stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1,message:"external tool cwd must be absolute"};if(options.abortSignal?.aborted)return{status:"cancelled",exitCode:null,stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1,message:"external tool execution cancelled before spawn"};let proc,timeoutHandle,abortListener,exitSettled=!1,settledExitCode=null;try{proc=_internals7.bunSpawn([options.executable,...options.args],{cwd:options.cwd,env:options.env,stdin:"ignore",stdout:"pipe",stderr:"pipe",timeout:options.timeoutMs});let exitPromise=proc.exited.then((exitCode)=>{return exitSettled=!0,settledExitCode=exitCode,{kind:"exit",exitCode}}),timeout=new Promise((resolve7)=>{timeoutHandle=setTimeout(()=>{if(exitSettled){resolve7({kind:"exit",exitCode:settledExitCode??proc?.exitCode??0});return}killProcess(proc),resolve7({kind:"timeout"})},options.timeoutMs)}),cancelled=new Promise((resolve7)=>{if(!options.abortSignal)return;let handled=!1;if(abortListener=()=>{if(handled)return;handled=!0,killProcess(proc),resolve7({kind:"cancelled"})},options.abortSignal.addEventListener("abort",abortListener,{once:!0}),options.abortSignal.aborted)abortListener()}),stdoutPromise=readBoundedStream(proc.stdout,options.maxStdoutBytes),stderrPromise=readBoundedStream(proc.stderr,options.maxStderrBytes),exitResult=await Promise.race([exitPromise,timeout,cancelled]);if(exitResult.kind==="timeout")return{status:"timeout",exitCode:proc.exitCode,stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1};if(exitResult.kind==="cancelled")return{status:"cancelled",exitCode:proc.exitCode,stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1,message:"external tool execution cancelled"};let[stdout,stderr]=await Promise.all([stdoutPromise,stderrPromise]);return{status:"completed",exitCode:exitResult.exitCode,stdout:stdout.text,stderr:stderr.text,stdoutTruncated:stdout.truncated,stderrTruncated:stderr.truncated}}catch(err){return{status:"spawn-error",exitCode:proc?.exitCode??null,stdout:"",stderr:"",stdoutTruncated:!1,stderrTruncated:!1,message:err instanceof Error?err.message:String(err)}}finally{if(timeoutHandle!==void 0)clearTimeout(timeoutHandle);if(abortListener&&options.abortSignal)options.abortSignal.removeEventListener("abort",abortListener);if(proc)try{proc.kill()}catch{}}}var DEFAULT_WINDOWS_EXTENSIONS,_internals7;var init_external_tool_runner=__esm(()=>{init_bun_compat();DEFAULT_WINDOWS_EXTENSIONS=[".exe",".cmd",".bat"];_internals7={bunSpawn,platform:()=>process.platform}});import*as fsp2 from"node:fs/promises";import*as path13 from"node:path";function boundPath(value){let cleaned=value.replace(/[\p{Cc}]/gu," ").replace(/[`<>]/g," ").replace(/\s+/g," ").trim();return cleaned.length>MAX_EVIDENCE_PATH_LENGTH?`${cleaned.slice(0,MAX_EVIDENCE_PATH_LENGTH)}...`:cleaned}function evidence(parsed,worktreeRoot,gitDir,operations,detail){let allPaths=parsed?[...parsed.unmergedPaths,...parsed.dirtySubmodulePaths,...parsed.dirtyTrackedPaths,...parsed.untrackedPaths]:[],uniquePaths=[...new Set(allPaths)].map(boundPath);return{worktreeRoot:worktreeRoot?boundPath(worktreeRoot):null,gitDir:gitDir?boundPath(gitDir):null,operations,unmergedCodes:parsed?[...new Set(parsed.unmergedCodes)].sort():[],paths:uniquePaths.slice(0,MAX_EVIDENCE_PATHS),trackedCount:parsed?.dirtyTrackedPaths.length??0,untrackedCount:parsed?.untrackedPaths.length??0,pathsTruncated:uniquePaths.length>MAX_EVIDENCE_PATHS,...detail?{detail}:{}}}async function runGitCapture(directory,args2){let result=await runExternalTool({executable:"git",args:[...args2],cwd:path13.resolve(directory),timeoutMs:GIT_TIMEOUT_MS,maxStdoutBytes:MAX_GIT_OUTPUT_BYTES,maxStderrBytes:65536});return{ok:result.status==="completed"&&result.exitCode===0&&!result.stdoutTruncated&&!result.stderrTruncated,stdout:result.stdout}}async function activeOperations(gitDir){return(await Promise.all(OPERATION_MARKERS.map(async([name,marker])=>{try{return await fsp2.lstat(path13.join(gitDir,marker)),name}catch(error49){if(error49.code==="ENOENT")return null;throw error49}}))).filter((value)=>value!==null)}async function classifyPrWorkflowGitState(directory){let[statusResult,rootResult,gitDirResult]=await Promise.all([_internals8.runGitCapture(directory,["status","--porcelain=v2","--branch","-z","--untracked-files=all"]),_internals8.runGitCapture(directory,["rev-parse","--show-toplevel"]),_internals8.runGitCapture(directory,["rev-parse","--absolute-git-dir"])]);if(!statusResult.ok||!rootResult.ok||!gitDirResult.ok)return{kind:"indeterminate",code:"GIT_STATE_INDETERMINATE",retryable:!1,requiredAction:"Confirm this is a readable Git worktree and resolve filesystem or Git errors before starting the PR workflow.",evidence:evidence(null,null,null,[],"required Git inspection failed")};let worktreeRoot=rootResult.stdout.trim(),gitDir=gitDirResult.stdout.trim(),parsed=parsePorcelainV2Snapshot(statusResult.stdout);if(!worktreeRoot||!gitDir||!parsed)return{kind:"indeterminate",code:"GIT_STATE_INDETERMINATE",retryable:!1,requiredAction:"Resolve the malformed or incomplete Git status before starting the PR workflow.",evidence:evidence(parsed,worktreeRoot||null,gitDir||null,[],"Git returned an incomplete status snapshot")};let operations;try{operations=await _internals8.activeOperations(path13.resolve(gitDir))}catch{return{kind:"indeterminate",code:"GIT_STATE_INDETERMINATE",retryable:!1,requiredAction:"Resolve the unreadable Git operation state before starting the PR workflow.",evidence:evidence(parsed,worktreeRoot,gitDir,[],"Git operation markers could not be inspected")}}let stateEvidence=evidence(parsed,worktreeRoot,gitDir,operations);if(parsed.unmergedCodes.length>0)return{kind:"recovery-required",code:"UNMERGED_INDEX",retryable:!1,requiredAction:"Resolve or abort the current merge/rebase/cherry-pick/revert operation manually; conflicted index entries must never be stashed by PR workflow startup.",evidence:stateEvidence};if(operations.length>0)return{kind:"recovery-required",code:"GIT_OPERATION_IN_PROGRESS",retryable:!1,requiredAction:"Complete or abort the active Git operation manually before starting the PR workflow.",evidence:stateEvidence};if(parsed.dirtySubmodulePaths.length>0)return{kind:"recovery-required",code:"DIRTY_SUBMODULE",retryable:!1,requiredAction:"Resolve or preserve dirty submodule worktrees manually; the checkout-preparation stash cannot safely preserve them.",evidence:stateEvidence};if([...parsed.dirtyTrackedPaths,...parsed.untrackedPaths].find((candidate)=>candidate===".swarm"||candidate.startsWith(".swarm/")||candidate.startsWith(".swarm\\")))return{kind:"recovery-required",code:"SWARM_STATE_TRACKING_ERROR",retryable:!1,requiredAction:"Restore .swarm/ so it is git-excluded before starting the PR workflow; runtime state must not be treated as checkout dirt.",evidence:stateEvidence};if(parsed.dirtyTrackedPaths.length===0&&parsed.untrackedPaths.length===0)return{kind:"clean",code:"CLEAN",retryable:!0,requiredAction:"No checkout recovery is required.",evidence:stateEvidence};return{kind:"stashable",code:"STASHABLE_CHANGES",retryable:!0,requiredAction:"Run prepare_pr_workflow_checkout once to preserve the ordinary working-tree changes before checkout.",evidence:stateEvidence}}var GIT_TIMEOUT_MS=5000,MAX_GIT_OUTPUT_BYTES=524288,MAX_EVIDENCE_PATHS=20,MAX_EVIDENCE_PATH_LENGTH=240,OPERATION_MARKERS,_internals8;var init_pr_workflow_state=__esm(()=>{init_workspace_snapshot();init_external_tool_runner();OPERATION_MARKERS=[["merge","MERGE_HEAD"],["rebase-merge","rebase-merge"],["rebase-apply-or-am","rebase-apply"],["cherry-pick","CHERRY_PICK_HEAD"],["revert","REVERT_HEAD"],["bisect","BISECT_START"],["sequencer","sequencer"]];_internals8={runGitCapture,activeOperations,parsePorcelainV2:parsePorcelainV2Snapshot}});import{createHash as createHash7,randomUUID as randomUUID2}from"node:crypto";import{readFileSync as readFileSync6}from"node:fs";import*as fsp3 from"node:fs/promises";import*as path14 from"node:path";function computePrReviewDepthTier(stats2){if(!stats2)return"L";if(stats2.hasSubmoduleChange)return"L";if(stats2.changedLines<=PR_REVIEW_DEPTH_TIER_THRESHOLDS.smallMaxChangedLines&&stats2.changedFiles<=PR_REVIEW_DEPTH_TIER_THRESHOLDS.smallMaxChangedFiles)return"S";if(stats2.changedLines<=PR_REVIEW_DEPTH_TIER_THRESHOLDS.mediumMaxChangedLines&&stats2.changedFiles<=PR_REVIEW_DEPTH_TIER_THRESHOLDS.mediumMaxChangedFiles)return"M";return"L"}function formatCheckoutRecoveryBlock(state){let evidence2=JSON.stringify({operations:state.evidence.operations,unmerged_codes:state.evidence.unmergedCodes,paths:state.evidence.paths,paths_truncated:state.evidence.pathsTruncated});return`BLOCKED: PR workflow checkout requires manual Git recovery before activation. code=${state.code} retryable=false required_action=${state.requiredAction} evidence=${evidence2}`}function checkoutRecoveryRecord(state){if(state.kind!=="recovery-required"&&state.kind!=="indeterminate")throw Error("PR workflow checkout recovery requires a terminal Git state");return{code:state.code,retryable:!1,requiredAction:state.requiredAction,evidence:state.evidence,detectedAt:isoNow()}}async function activatePrWorkflow(directory,sessionID,mode,options={}){let normalizedSessionID=normalizeSessionID(sessionID),existing=await readPrWorkflowGateState(directory,normalizedSessionID);if(existing?.mode===mode){let activeState=existing;if(mode==="PR_FEEDBACK"&&options.prUrl){let requestedTarget=canonicalGitHubPrUrl(options.prUrl);if(!requestedTarget)throw Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");let existingTarget=existing.prFeedbackTargetUrl?canonicalGitHubPrUrl(existing.prFeedbackTargetUrl):null;if(existingTarget&&requestedTarget!==existingTarget)throw Error("BLOCKED: active PR_FEEDBACK targets a different GitHub pull request");if(!existingTarget)activeState={...existing,prFeedbackTargetUrl:options.prUrl,updatedAt:isoNow()},await persistState(directory,activeState)}return options.prHeadSha?bindPrWorkflowHead(directory,normalizedSessionID,options.prHeadSha):activeState}if(existing)throw Error(`BLOCKED: session "${normalizedSessionID}" already has an active ${existing.mode} workflow; complete it before starting ${mode}`);if(options.requireCheckoutPreflight){let checkoutState=await classifyPrWorkflowGitState(directory);if(checkoutState.kind==="recovery-required"||checkoutState.kind==="indeterminate")throw Error(formatCheckoutRecoveryBlock(checkoutState))}let initialHead=options.prHeadSha?await assertCurrentCheckoutHead(directory,options.prHeadSha,mode):void 0,timestamp=isoNow(),feedbackTargetUrl=mode==="PR_FEEDBACK"&&options.prUrl?canonicalGitHubPrUrl(options.prUrl)?options.prUrl:null:void 0;if(feedbackTargetUrl===null)throw Error("BLOCKED: PR_FEEDBACK target must be a canonical GitHub PR URL");let nextState={schemaVersion:GATE_SCHEMA_VERSION,revision:0,workflowInstanceId:randomUUID2(),sessionID:normalizedSessionID,mode,activatedAt:timestamp,updatedAt:timestamp,...initialHead?{prHeadSha:initialHead}:{},...feedbackTargetUrl?{prFeedbackTargetUrl:feedbackTargetUrl}:{}};return await persistState(directory,nextState),nextState}async function readPrWorkflowGateState(directory,sessionID){let normalizedSessionID=normalizeSessionID(sessionID),state=await readPrWorkflowGateStateFromDisk(directory,normalizedSessionID);if(state)rememberState(directory,state);else trackedStatesByProjectSession.delete(stateCacheKey(directory,normalizedSessionID));return state}async function withPrWorkflowCheckoutPreparationLock(directory,sessionID,action){let normalizedSessionID=normalizeSessionID(sessionID);return withPrWorkflowCheckoutMutationLock(directory,async()=>withSessionStateMutation(directory,normalizedSessionID,async()=>{let state=await readPrWorkflowGateStateFromDisk(directory,normalizedSessionID);if(!state)throw Error(`BLOCKED: no active PR workflow gate for session "${normalizedSessionID}". The gate is activated by running \`/swarm pr-review <pr-ref>\` (which activates PR_REVIEW) or \`/swarm pr-feedback <pr-ref>\` (which activates PR_FEEDBACK), or by the first dispatch_lanes_async call with mode "swarm-pr-review:*" / "swarm-pr-feedback:*". Run the appropriate command first, then retry checkout preparation.`);if(state.prHeadSha)throw Error(`BLOCKED: ${state.mode} checkout preparation is allowed only before the PR head is bound`);return action(state,{markRecoveryRequired:async(gitState)=>{let nextState={...state,updatedAt:isoNow(),checkoutRecovery:checkoutRecoveryRecord(gitState)},persisted=await writeStateWhileLocked(directory,nextState);return Object.assign(state,persisted),persisted}})}))}async function clearPrWorkflowGateState(directory,sessionID,expectedRevision){let normalizedSessionID=normalizeSessionID(sessionID);await withSessionStateMutation(directory,normalizedSessionID,async()=>{if(expectedRevision!==void 0){let current=await readPrWorkflowGateStateFromDisk(directory,normalizedSessionID);if(!current||current.revision!==expectedRevision)throw Error("BLOCKED: PR workflow gate state changed during terminal completion; revalidate the current session state before retrying")}try{await fsp3.rm(workflowGateStatePath(directory,normalizedSessionID),{force:!0})}catch(error49){if(error49.code!=="ENOENT")throw error49}trackedStatesByProjectSession.delete(stateCacheKey(directory,normalizedSessionID))})}async function abortPrWorkflow(directory,sessionID,options={}){let state=await requireAnyActiveState(directory,sessionID);if(options.expectedMode&&state.mode!==options.expectedMode)throw wrongModeError(state,options.expectedMode);if(state.prFeedbackReadyToPublish)throw Error(`BLOCKED: ${state.mode} is armed for publication; abort is blocked. Complete the workflow with complete_pr_workflow (or push the bound commit first) before aborting.`);let openLanes=readDelegations(directory).filter((record2)=>record2.parentSessionId===state.sessionID&&record2.mode?.startsWith("swarm-pr-")&&(record2.status==="pending"||record2.status==="running"));if(openLanes.length>0){let laneIds=openLanes.map((record2)=>record2.laneId??record2.subagentSessionId??"unknown").filter(Boolean).slice(0,10).join(", ");throw Error(`BLOCKED: ${state.mode} abort refused while ${openLanes.length} PR workflow lane(s) are still in flight (lane ids: ${laneIds}). Collect their results or let them settle before aborting.`)}let sanitizedReason=typeof options.reason==="string"?options.reason.trim().slice(0,500):void 0,abortEvent={type:"pr_workflow_aborted",timestamp:isoNow(),sessionID:state.sessionID,mode:state.mode,...state.prHeadSha?{prHeadSha:state.prHeadSha}:{},openLanes:openLanes.length,...sanitizedReason?{reason:sanitizedReason}:{}};try{let eventsPath=validateSwarmPath(directory,"events.jsonl");await fsp3.appendFile(eventsPath,`${JSON.stringify(abortEvent)}
|
|
185
|
-
`,"utf-8")}catch{}return await clearPrWorkflowGateState(directory,sessionID,state.revision),{mode:state.mode,...state.prHeadSha?{prHeadSha:state.prHeadSha}:{},openLanes:openLanes.length}}async function bindPrWorkflowHead(directory,sessionID,prHeadSha){let normalizedHead=normalizePrHeadSha(prHeadSha);return withPrWorkflowCheckoutMutationLock(directory,async()=>withSessionStateMutation(directory,normalizeSessionID(sessionID),async()=>{let state=await readPrWorkflowGateStateFromDisk(directory,normalizeSessionID(sessionID));if(!state)throw Error(`BLOCKED: no active PR workflow gate for session "${normalizeSessionID(sessionID)}". The gate must be activated before the PR head can be bound.`);if(await assertCurrentCheckoutHead(directory,normalizedHead,state.mode),state.prHeadSha&&state.prHeadSha!==normalizedHead)throw Error(`BLOCKED: active ${state.mode} workflow is bound to PR head "${state.prHeadSha}"; received "${normalizedHead}"`);if(!state.prHeadSha)await assertPrReviewCleanCheckout(directory,state.mode);if(!state.prHeadSha&&state.mode==="PR_FEEDBACK")await assertPrFeedbackTrackingCheckout(directory,normalizedHead);if(state.prHeadSha===normalizedHead){if(state.mode==="PR_FEEDBACK")await assertPrFeedbackTrackingCheckout(directory,normalizedHead);return state}let nextState={...state,prHeadSha:normalizedHead,updatedAt:isoNow()};return await _test_exports.beforePrFeedbackTrackingPersist?.(),writeStateWhileLocked(directory,nextState)}))}async function bindPrReviewBase(directory,sessionID,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_REVIEW")throw Error("BLOCKED: only PR_REVIEW can bind a review merge base");let baseRef=options.baseRef.trim(),baseSha=normalizePrHeadSha(options.baseSha).toLowerCase();if(!baseRef)throw Error("BLOCKED: PR_REVIEW base_ref must not be empty");if(state.prReviewBaseRef&&state.prReviewBaseRef!==baseRef||state.prReviewBaseSha&&state.prReviewBaseSha!==baseSha)throw Error(`BLOCKED: active PR_REVIEW is bound to merge-base scope "${state.prReviewBaseRef??"(unbound)"}" at "${state.prReviewBaseSha??"(unbound)"}"; received "${baseRef}" at "${baseSha}"`);if(state.prReviewBaseRef===baseRef&&state.prReviewBaseSha===baseSha)return state;let prHeadSha=normalizePrHeadSha(options.prHeadSha).toLowerCase(),diffStats=await _test_exports.resolvePrReviewDiffStatsAsync(directory,baseSha,prHeadSha);return state={...state,prReviewBaseRef:baseRef,prReviewBaseSha:baseSha,prReviewDepthTier:computePrReviewDepthTier(diffStats),...diffStats?{prReviewDiffStats:diffStats}:{},updatedAt:isoNow()},await persistState(directory,state),state}async function assertCurrentCheckoutHead(directory,expectedHead,mode="PR_REVIEW"){let normalizedExpected=normalizePrHeadSha(expectedHead),currentHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(!currentHead)throw Error(`BLOCKED: cannot resolve the current Git HEAD in "${directory}" to verify against PR head "${normalizedExpected}". This means Git could not resolve HEAD (the working directory may not be a Git repository, HEAD may be unborn, the commit object may be missing in a shallow clone, the Git binary may not be on PATH, or the bounded Git invocation may have timed out). Verify with: git -C "${directory}" rev-parse --verify HEAD^{commit}`);if(currentHead.toLowerCase()!==normalizedExpected.toLowerCase()){let remediation=mode==="PR_FEEDBACK"?"Check out the intended local tracking branch at that exact head (for example with a safe standalone `gh pr checkout <number-or-url>` or `git switch -c <local> --track <remote>/<branch>`), then retry the bind. Do not create a new detached feedback checkout.":`Run these bare, standalone commands from that directory: if the commit is not present locally, \`git fetch origin <pr-head-ref>\`; then \`git switch --detach ${normalizedExpected}\`. Do not prefix the switch with \`git -C\`; the read-only shell classifier refuses \`git -C ... switch\`.`;throw Error(`BLOCKED: current checkout HEAD "${currentHead}" does not match PR head "${normalizedExpected}" (working directory: "${directory}"). ${remediation}`)}return normalizedExpected}async function assertPrReviewCleanCheckout(directory,mode="PR_REVIEW"){if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error(`BLOCKED: ${mode} requires a clean index and working tree at the exact PR head`)}async function assertPrFeedbackTrackingCheckout(directory,prHeadSha){let currentHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(!currentHead)throw Error("BLOCKED: PR_FEEDBACK requires a resolved exact Git HEAD before first head bind");if(currentHead.toLowerCase()!==prHeadSha.toLowerCase())throw Error(`BLOCKED: PR_FEEDBACK exact head changed before attach; expected ${prHeadSha}, received ${currentHead}`);let currentUpstream=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory),matchingRemoteRefs=await _test_exports.resolveRemoteRefsContainingHeadAsync(directory,prHeadSha);if(currentUpstream){if(matchingRemoteRefs===null)throw Error("BLOCKED: PR_FEEDBACK could not verify the current upstream against the exact intake PR head; the bounded Git query failed or timed out");if(matchingRemoteRefs.includes(currentUpstream.remoteTrackingRef))return;throw Error(`BLOCKED: PR_FEEDBACK current upstream "${currentUpstream.remoteTrackingRef}" must point to the exact intake PR head "${prHeadSha}"; refusing to replace an existing tracking relationship`)}let candidates=await resolvePrFeedbackTrackingCandidatesAsync(directory,prHeadSha);if(!candidates)throw Error(`BLOCKED: PR_FEEDBACK could not inspect tracked branches for exact PR head "${prHeadSha}"; the bounded Git query failed or timed out`);let{local:localCandidates,remote:remoteCandidates}=candidates;if(localCandidates.length===1){if(await _test_exports.beforePrFeedbackTrackingSwitch?.(),!await switchPrFeedbackTrackingCandidateAsync(directory,localCandidates[0]))throw Error(`BLOCKED: PR_FEEDBACK could not attach exact local tracked branch "${localCandidates[0].branchName}"; it may be checked out in another linked worktree or the bounded Git switch failed`)}else if(localCandidates.length>1)throw Error(`BLOCKED: PR_FEEDBACK exact head "${prHeadSha}" matches multiple local tracked branches: ${localCandidates.map((candidate)=>candidate.branchName).join(", ")}`);else if(remoteCandidates.length===1){if(await _test_exports.beforePrFeedbackTrackingSwitch?.(),!await switchPrFeedbackTrackingCandidateAsync(directory,remoteCandidates[0]))throw Error(`BLOCKED: PR_FEEDBACK could not attach exact remote-tracking branch "${remoteCandidates[0].remoteTrackingRef}"; the bounded Git switch failed or timed out`)}else if(remoteCandidates.length>1)throw Error(`BLOCKED: PR_FEEDBACK exact head "${prHeadSha}" matches multiple remote-tracking refs: ${remoteCandidates.map((candidate)=>candidate.remoteTrackingRef).join(", ")}`);else throw Error("BLOCKED: PR_FEEDBACK requires a current local branch or exact remote-tracking ref that points to the intake PR head before the first bind");await _test_exports.afterPrFeedbackTrackingSwitch?.();let attachedHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(attachedHead?.toLowerCase()!==prHeadSha.toLowerCase())throw Error(`BLOCKED: PR_FEEDBACK exact head changed after attach; expected ${prHeadSha}, received ${attachedHead??"(unresolved)"}`);if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error("BLOCKED: PR_FEEDBACK requires a clean working tree after checkout attachment");let attachedUpstream=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory);if(!attachedUpstream)throw Error("BLOCKED: PR_FEEDBACK could not resolve the attached branch upstream after checkout promotion");if(!(await _test_exports.resolveRemoteRefsContainingHeadAsync(directory,prHeadSha))?.includes(attachedUpstream.remoteTrackingRef))throw Error(`BLOCKED: PR_FEEDBACK upstream "${attachedUpstream.remoteTrackingRef}" must point to the exact intake PR head "${prHeadSha}" before the first head bind`)}async function enforcePrWorkflowDispatchLanesAsync(directory,sessionID,toolName){let state=await readPrWorkflowGateState(directory,sessionID);if(!state)return null;if(toolName===DISPATCH_TOOL_NAME)return state;if(toolName===BLOCKING_DISPATCH_TOOL_NAME)throw Error(`BLOCKED: active ${state.mode} workflow for session "${state.sessionID}" requires ${DISPATCH_TOOL_NAME}; ${BLOCKING_DISPATCH_TOOL_NAME} is not allowed`);return state}async function enforcePrReviewBaseDimensions(directory,sessionID,lanes,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_REVIEW")throw wrongModeError(state,"PR_REVIEW");let normalizedLanes=normalizeWorkflowLanes(lanes),claimedDimensionIds=normalizedLanes.flatMap((lane)=>lane.ownedWorkflowLanes??[lane.workflowLane]);if(claimedDimensionIds.filter((laneId)=>!PR_REVIEW_BASE_DIMENSION_IDS.includes(laneId)).length>0){let expected=PR_REVIEW_BASE_DIMENSION_IDS.join(", "),received=claimedDimensionIds.join(", ")||"(none)";throw Error(`BLOCKED: PR_REVIEW base dispatch lane ids must be drawn from: ${expected}. Received: ${received}`)}if((state.prReviewDepthTier??"L")==="L"&&normalizedLanes.some((lane)=>(lane.ownedWorkflowLanes?.length??1)!==1))throw Error("BLOCKED: PR_REVIEW base dispatch at depth tier L requires one dedicated lane per dimension; consolidated owned_workflow_lanes are allowed only at tiers S and M");let batchId=normalizeBatchId(options.batchId),previous=state.prReviewBaseDispatches??[];if(previous.some((record3)=>record3.batchId===batchId))throw Error(`BLOCKED: PR_REVIEW base batch id "${batchId}" is already recorded`);if(previous.length>=MAX_WORKFLOW_BATCHES)throw Error("BLOCKED: PR_REVIEW base batch limit reached");let record2={batchId,lanes:normalizedLanes.map((lane)=>({laneId:lane.laneId,workflowLane:lane.workflowLane,...lane.ownedWorkflowLanes?{ownedWorkflowLanes:lane.ownedWorkflowLanes}:{}})),validatedAt:isoNow()},nextState={...state,updatedAt:isoNow(),prReviewBaseDispatches:[...previous,record2],prReviewBaseDispatch:record2};return await persistState(directory,nextState),nextState}async function assertPrReviewBaseCoverageSettled(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_REVIEW"),batches=state.prReviewBaseDispatches??[];if(batches.length===0)throw Error("BLOCKED: PR_REVIEW requires at least one base batch");let covered=new Set,malformedDiagnostics=[];for(let batch of batches){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:base",batch.validatedAt,!0,new Set,void 0,malformedDiagnostics);for(let obligation of successful)covered.add(obligation)}let missing=PR_REVIEW_BASE_DIMENSION_IDS.filter((dimension)=>!covered.has(dimension));if(missing.length>0||covered.size!==PR_REVIEW_BASE_DIMENSION_IDS.length)throw Error(`BLOCKED: PR_REVIEW base coverage is incomplete; missing dimensions: ${missing.join(", ")||"(none)"}${malformedDiagnostics.length>0?`; malformed candidate diagnostics: ${malformedDiagnostics.join(" | ")}`:""}`);return state}async function recordPrReviewValidationBatch(directory,sessionID,phase,lanes,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_REVIEW")throw wrongModeError(state,"PR_REVIEW");if(!state.prReviewTriggerEvalPath)throw Error("BLOCKED: PR_REVIEW validation dispatch requires a completed trigger evaluation");if(phase==="reviewer"&&(state.prReviewValidationBatches??[]).some((batch)=>batch.phase==="council"))state=await assertPrReviewValidationSettled(directory,sessionID,"council");else if(phase==="critic")state=await assertPrReviewValidationSettled(directory,sessionID,"reviewer");let normalizedLanes=normalizeWorkflowLanes(lanes);if((phase==="reviewer"||phase==="critic")&&normalizedLanes.some((lane)=>!lane.reviewItemIds?.length))throw Error(`BLOCKED: PR_REVIEW ${phase} lanes require non-empty review_item_ids ownership`);if(phase==="reviewer"||phase==="critic"){assertNoDuplicates(normalizedLanes.flatMap((lane)=>lane.reviewItemIds??[]),`PR_REVIEW ${phase} review item ownership`);let assigned=normalizedLanes.flatMap((lane)=>lane.reviewItemIds??[]),required2=phase==="reviewer"?derivePrReviewCandidateInventory(directory,state):derivePrReviewCriticInventory(directory,state);assertExactStringSet(assigned,required2,`PR_REVIEW ${phase} ownership`)}let batchId=normalizeBatchId(options.batchId),previous=state.prReviewValidationBatches??[];if(previous.some((batch)=>batch.batchId===batchId))throw Error(`BLOCKED: PR_REVIEW validation batch id "${batchId}" is already recorded`);if(previous.length>=MAX_WORKFLOW_BATCHES)throw Error("BLOCKED: PR_REVIEW validation batch limit reached");let record2={batchId,phase,lanes:normalizedLanes,validatedAt:isoNow()},retained=phase==="reviewer"?previous.filter((batch)=>batch.phase!=="critic"):previous,nextState={...state,updatedAt:isoNow(),prReviewValidationBatches:[...retained,record2]};return await persistState(directory,nextState),nextState}async function assertPrReviewValidationSettled(directory,sessionID,phase){let state=await requireBoundState(directory,sessionID,"PR_REVIEW"),declaredPhases=new Set((state.prReviewValidationBatches??[]).map((batch)=>batch.phase)),phases=phase?[phase]:["council","reviewer","critic"].filter((candidate)=>declaredPhases.has(candidate));for(let requiredPhase of phases){let validationBatches=state.prReviewValidationBatches??[],forbiddenSubagentSessionIds=new Set;if(requiredPhase==="critic")for(let reviewerBatch of validationBatches.filter((batch)=>batch.phase==="reviewer"))for(let record2 of findByBatchId(directory,reviewerBatch.batchId,{parentSessionId:state.sessionID})){let subagentSessionId=record2.subagentSessionId?.trim();if(subagentSessionId)forbiddenSubagentSessionIds.add(subagentSessionId)}let batches=validationBatches.filter((batch)=>batch.phase===requiredPhase);if(requiredPhase==="reviewer"){let latestCouncilIndex=-1;for(let index=0;index<validationBatches.length;index++)if(validationBatches[index]?.phase==="council")latestCouncilIndex=index;if(latestCouncilIndex>=0)batches=validationBatches.slice(latestCouncilIndex+1).filter((batch)=>batch.phase==="reviewer")}if(batches.length===0)throw Error(requiredPhase==="reviewer"&&declaredPhases.has("council")?"BLOCKED: PR_REVIEW requires at least one reviewer batch after the latest council batch":`BLOCKED: PR_REVIEW requires at least one ${requiredPhase} batch`);let allObligations=new Set(batches.flatMap((batch)=>batch.lanes.map((lane)=>lane.workflowLane))),settled=new Set,hasFullySuccessfulExactBatch=!1;for(let batch of batches){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,`swarm-pr-review:${requiredPhase}`,batch.validatedAt,!0,forbiddenSubagentSessionIds);if(successful.size===batch.lanes.length&&batch.lanes.every((lane)=>successful.has(lane.workflowLane)))hasFullySuccessfulExactBatch=!0;for(let obligation of successful)settled.add(obligation)}if((requiredPhase==="reviewer"||requiredPhase==="critic")&&!hasFullySuccessfulExactBatch)throw Error(`BLOCKED: PR_REVIEW ${requiredPhase} requires one fully successful exact batch; complementary partial retries are not a coherent verdict set`);let missing=[...allObligations].filter((obligation)=>!settled.has(obligation));if(missing.length>0)throw Error(`BLOCKED: PR_REVIEW ${requiredPhase} obligations lack successful exact artifacts: ${missing.join(", ")}`)}return state}async function declarePrFeedbackInventory(directory,sessionID,inventoryIds,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_FEEDBACK")throw wrongModeError(state,"PR_FEEDBACK");let normalizedInventory=normalizeInventoryIds(inventoryIds),requiredHandoffIds=state.prFeedbackReviewHandoff?.findingIds??[],inventorySet=new Set(normalizedInventory),missingHandoffIds=requiredHandoffIds.filter((findingId)=>!inventorySet.has(findingId));if(missingHandoffIds.length>0)throw Error(`BLOCKED: PR_FEEDBACK inventory must include every continued review finding: ${missingHandoffIds.join(", ")}`);if(state.prFeedbackInventory){if(!sameStringArray(state.prFeedbackInventory,normalizedInventory))throw Error("BLOCKED: PR_FEEDBACK inventory is immutable after declaration");return state}let nextState={...state,updatedAt:isoNow(),prFeedbackInventory:normalizedInventory,prFeedbackVerifications:[]};return await persistState(directory,nextState),nextState}async function enforcePrFeedbackVerificationOwnership(directory,sessionID,ownership,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_FEEDBACK")throw wrongModeError(state,"PR_FEEDBACK");let inventory=state.prFeedbackInventory;if(!inventory||inventory.length===0)throw Error(`BLOCKED: PR_FEEDBACK verification for session "${state.sessionID}" requires a declared feedback inventory before dispatch`);let normalizedOwnership=normalizeOwnership(ownership),inventorySet=new Set(inventory),claimedByItemId=new Map,previous=state.prFeedbackVerifications??[],batchId=normalizeBatchId(options.batchId);if(previous.some((record3)=>record3.batchId===batchId))throw Error(`BLOCKED: PR_FEEDBACK verification batch id "${batchId}" is already recorded`);if(previous.length>=MAX_WORKFLOW_BATCHES)throw Error("BLOCKED: PR_FEEDBACK verification batch limit reached");for(let record3 of previous)for(let lane of record3.ownership)for(let itemId of lane.ownedItemIds)claimedByItemId.set(itemId,lane.laneId);for(let lane of normalizedOwnership)for(let itemId of lane.ownedItemIds){if(!inventorySet.has(itemId))throw Error(`BLOCKED: PR_FEEDBACK verification lane "${lane.laneId}" owns undeclared item "${itemId}"`);let previousLane=claimedByItemId.get(itemId);if(previousLane&&previousLane!==lane.laneId)throw Error(`BLOCKED: PR_FEEDBACK verification item "${itemId}" is owned by both "${previousLane}" and "${lane.laneId}"`);claimedByItemId.set(itemId,lane.laneId)}let record2={batchId,ownership:normalizedOwnership,validatedAt:isoNow()},nextState={...state,updatedAt:isoNow(),prFeedbackVerifications:[...previous,record2],prFeedbackVerification:record2};return await persistState(directory,nextState),nextState}async function assertPrFeedbackVerificationSettled(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),currentDigest=await currentPrFeedbackRevisionDigest(directory,state),inventory=state.prFeedbackInventory,batches=state.prFeedbackVerifications??[];if(!inventory||batches.length===0)throw Error("BLOCKED: PR_FEEDBACK requires an immutable inventory and verification batches");let covered=new Set;for(let batch of batches){let successfulLaneIds=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.ownership.map((lane)=>({laneId:lane.laneId,workflowLane:lane.laneId})),"swarm-pr-feedback:verification",batch.validatedAt,!1,new Set,currentDigest);for(let lane of batch.ownership){if(!successfulLaneIds.has(lane.laneId))continue;if(!feedbackArtifactCoversItems(directory,state,batch.batchId,lane.laneId,lane.ownedItemIds))continue;for(let itemId of lane.ownedItemIds)covered.add(itemId)}}let missing=inventory.filter((itemId)=>!covered.has(itemId));if(missing.length>0||covered.size!==inventory.length)throw Error(`BLOCKED: PR_FEEDBACK verification ownership is incomplete; missing inventory items: ${missing.join(", ")||"(none)"}`);return state}async function recordPrFeedbackStageA(directory,sessionID,revisionDigest,checks3,options={}){let state=await assertPrFeedbackVerificationSettled(directory,sessionID),currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(revisionDigest!==currentDigest)throw Error("BLOCKED: PR_FEEDBACK Stage A receipt is stale because the working-tree revision changed during validation");if(checks3.length<2||checks3.length>258)throw Error("BLOCKED: PR_FEEDBACK Stage A requires two to 258 controller-created check receipts");let optionalCategoryOrder=["build","typecheck","lint"],applicableCategories=options.applicableCategories??optionalCategoryOrder.filter((category)=>checks3.some((check2)=>check2.category===category));if(assertNoDuplicates(applicableCategories,"PR_FEEDBACK Stage A applicable categories"),applicableCategories.some((category)=>!optionalCategoryOrder.includes(category)))throw Error("BLOCKED: PR_FEEDBACK Stage A applicability may contain only build, typecheck, and lint");let required2=new Set(["diff-check","reproduction",...applicableCategories]),singletonSeen=new Set,applicableObligations=[...options.applicableObligations??[]];assertNoDuplicates(applicableObligations.map(({id})=>id),"PR_FEEDBACK Stage A applicable obligations");let requiredObligationIds=new Set(applicableObligations.map(({id})=>id)),commandDigests=new Set,reproductionFeedbackItemIds=[];for(let check2 of checks3){if(["diff-check","reproduction"].includes(check2.category)&&singletonSeen.has(check2.category))throw Error(`BLOCKED: PR_FEEDBACK Stage A contains duplicate category "${check2.category}"`);if(singletonSeen.add(check2.category),required2.delete(check2.category),check2.obligationId){let obligation=applicableObligations.find((candidate)=>candidate.id===check2.obligationId);if(!obligation||obligation.category!==check2.category||obligation.workingDirectory!==(check2.workingDirectory??".")||!requiredObligationIds.delete(check2.obligationId))throw Error(`BLOCKED: PR_FEEDBACK Stage A receipt does not match one exact applicable obligation: ${check2.obligationId}`);let sourceContract=obligation.source.includes(".pr-validation.json#")?{path:obligation.source.slice(0,obligation.source.lastIndexOf("#")),id:obligation.source.slice(obligation.source.lastIndexOf("#")+1)}:void 0,requiredContract=obligation.validatorContract??sourceContract;if(requiredContract&&(check2.validatorContract?.path!==requiredContract.path||check2.validatorContract.id!==requiredContract.id))throw Error(`BLOCKED: PR_FEEDBACK Stage A obligation ${obligation.id} requires exact validator contract provenance`)}let commandDigest=createHash7("sha256").update(`${check2.obligationId??check2.category}\x00${check2.workingDirectory??"."}\x00${check2.command.join("\x00")}`).digest("hex");if(commandDigests.has(commandDigest))throw Error("BLOCKED: PR_FEEDBACK Stage A cannot reuse one command as multiple check receipts");if(commandDigests.add(commandDigest),check2.category==="diff-check"&&!sameStringArray(check2.command,["git","diff","--check"]))throw Error("BLOCKED: PR_FEEDBACK Stage A diff-check receipt is not the exact git diff --check command");if(check2.category==="reproduction"&&(!check2.targets?.length||!check2.feedbackTargets?.length||check2.targets.some((target)=>!check2.command.join(" ").includes(target))))throw Error("BLOCKED: PR_FEEDBACK Stage A reproduction receipt requires exact selected targets");if(check2.category==="reproduction"){if(reproductionFeedbackItemIds=check2.feedbackTargets.map((mapping)=>mapping.feedbackItemId),assertNoDuplicates(reproductionFeedbackItemIds,"PR_FEEDBACK Stage A reproduction feedback item mappings"),check2.feedbackTargets.some((mapping)=>!check2.targets.includes(mapping.target)))throw Error("BLOCKED: PR_FEEDBACK Stage A feedback mappings must reference exact executed reproduction targets")}}if(required2.size>0)throw Error(`BLOCKED: PR_FEEDBACK Stage A is missing required checks: ${[...required2].join(", ")}`);if(requiredObligationIds.size>0)throw Error(`BLOCKED: PR_FEEDBACK Stage A is missing applicable workspace obligations: ${[...requiredObligationIds].join(", ")}`);if(!sameStringArray(reproductionFeedbackItemIds,state.prFeedbackInventory??[]))throw Error("BLOCKED: PR_FEEDBACK Stage A reproduction must map every immutable feedback item exactly once and in declared order");let nextState={...state,updatedAt:isoNow(),prFeedbackStageA:{revisionDigest:currentDigest,checks:[...checks3],feedbackItemIds:reproductionFeedbackItemIds,applicableCategories:optionalCategoryOrder.filter((category)=>applicableCategories.includes(category)),applicableObligations,validatedAt:isoNow()},prFeedbackGateBatches:[],prFeedbackReadyToPublish:void 0};return await persistState(directory,nextState),nextState}async function recordPrFeedbackGateBatch(directory,sessionID,phase,lane,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_FEEDBACK")throw wrongModeError(state,"PR_FEEDBACK");let inventory=state.prFeedbackInventory;if(!inventory?.length)throw Error("BLOCKED: PR_FEEDBACK ordered gates require an immutable feedback inventory");let normalized=normalizeOwnership([lane])[0];if(!sameStringArray(normalized.ownedItemIds,inventory))throw Error(`BLOCKED: PR_FEEDBACK ${phase} must own every inventory item exactly once and in declared order`);let phaseIndex=PR_FEEDBACK_PHASE_ORDER.indexOf(phase),prerequisite=PR_FEEDBACK_PHASE_ORDER[phaseIndex-1];if(prerequisite)state=await assertPrFeedbackGatePhaseSettled(directory,sessionID,prerequisite);let{prFeedbackStageA:stageA,prFeedbackInventory:refreshedInventory}=state,currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(!stageA||!refreshedInventory||stageA.revisionDigest!==currentDigest||!sameStringArray(stageA.feedbackItemIds??[],refreshedInventory)||options.revisionDigest!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} requires fresh Stage A checks on the current revision`);let batchId=normalizeBatchId(options.batchId),previous=state.prFeedbackGateBatches??[];if(previous.some((batch)=>batch.batchId===batchId))throw Error(`BLOCKED: PR_FEEDBACK gate batch id "${batchId}" is already recorded`);let retained=previous.filter((batch)=>PR_FEEDBACK_PHASE_ORDER.indexOf(batch.phase)<phaseIndex),record2={batchId,phase,laneId:normalized.laneId,itemIds:normalized.ownedItemIds,revisionDigest:currentDigest,validatedAt:isoNow()},nextState={...state,updatedAt:isoNow(),prFeedbackGateBatches:[...retained,record2]};return await persistState(directory,nextState),nextState}async function assertPrFeedbackGatePhaseSettled(directory,sessionID,phase){let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(state.prFeedbackStageA?.revisionDigest!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} cannot use stale Stage A evidence`);if(!sameStringArray(state.prFeedbackStageA?.feedbackItemIds??[],state.prFeedbackInventory??[]))throw Error(`BLOCKED: PR_FEEDBACK ${phase} Stage A reproduction is not bound to the exact immutable feedback inventory`);let batch=[...state.prFeedbackGateBatches??[]].reverse().find((candidate)=>candidate.phase===phase);if(!batch||batch.revisionDigest!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} has no validation batch on the current revision`);if(!successfulObligationsFromExactBatch(directory,state,batch.batchId,[{laneId:batch.laneId,workflowLane:phase,reviewItemIds:batch.itemIds}],`swarm-pr-feedback:${phase}`,batch.validatedAt,!0,new Set,currentDigest).has(phase))throw Error(`BLOCKED: PR_FEEDBACK ${phase} requires one complete, non-degraded positive verdict row per inventory item`);if(findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===batch.laneId)?.workspace?.dirtyHash!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} artifact is not bound to the current revision digest`);return assertIndependentFeedbackGateSessions(directory,state,phase),state}function assertIndependentFeedbackGateSessions(directory,state,throughPhase){let throughIndex=PR_FEEDBACK_PHASE_ORDER.indexOf(throughPhase),batches=(state.prFeedbackGateBatches??[]).filter((batch)=>PR_FEEDBACK_PHASE_ORDER.indexOf(batch.phase)<=throughIndex),seenSessions=new Set;for(let batch of batches){let matching=findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).filter((record3)=>record3.laneId===batch.laneId);if(matching.length!==1)throw Error(`BLOCKED: PR_FEEDBACK ${batch.phase} must resolve from exactly one durable child session`);let record2=matching[0],expectedRole=PR_FEEDBACK_PHASE_ROLE[batch.phase];if(!(record2.normalizedAgent===expectedRole||expectedRole==="critic"&&record2.normalizedAgent.startsWith("critic_")))throw Error(`BLOCKED: PR_FEEDBACK ${batch.phase} requires role ${expectedRole}, received ${record2.normalizedAgent||"(unknown)"}`);if(seenSessions.has(record2.subagentSessionId))throw Error(`BLOCKED: PR_FEEDBACK independent phases reused child session "${record2.subagentSessionId}"`);seenSessions.add(record2.subagentSessionId)}}async function assertPrFeedbackReadyToPublish(directory,sessionID){let state=await assertPrFeedbackVerificationSettled(directory,sessionID);for(let phase of PR_FEEDBACK_PHASE_ORDER)state=await assertPrFeedbackGatePhaseSettled(directory,sessionID,phase);return state}async function assertPrFeedbackPublicationArmed(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),armed=state.prFeedbackReadyToPublish;if(!armed)throw Error("BLOCKED: PR_FEEDBACK publication is not armed; call complete_pr_workflow once after every ordered gate passes");let currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(armed.revisionDigest!==currentDigest)throw Error("BLOCKED: PR_FEEDBACK changed after publication was armed; rerun Stage A and every independent gate");if((await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim()!==armed.localHead)throw Error("BLOCKED: PR_FEEDBACK current Git HEAD changed after publication was armed");if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error("BLOCKED: PR_FEEDBACK working tree changed after publication was armed");let currentTarget=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory);if(!currentTarget||currentTarget.remoteName!==armed.remoteName||currentTarget.remoteBranchRef!==armed.remoteBranchRef||currentTarget.remoteTrackingRef!==armed.remoteRef)throw Error("BLOCKED: PR_FEEDBACK upstream publication target changed after publication was armed");return state}async function markPrReviewTriggerEvaluationComplete(directory,sessionID,artifactPath){let state=await assertPrReviewBaseCoverageSettled(directory,sessionID),normalizedPath=artifactPath.trim();if(!normalizedPath)throw Error("BLOCKED: PR_REVIEW trigger artifact path is required");let nextState={...state,updatedAt:isoNow(),prReviewTriggerEvalPath:normalizedPath};return await persistState(directory,nextState),nextState}async function bindPrReviewTriggerLedger(directory,sessionID,input){let ledger;try{ledger=validatePrReviewInlineTriggerLedger(input)}catch(error49){throw Error(`BLOCKED: invalid PR_REVIEW trigger_evaluation: ${error49 instanceof Error?error49.message:String(error49)}`)}let state=await assertPrReviewBaseCoverageSettled(directory,sessionID);if(state.prReviewTriggerLedger){let frozen;try{frozen=validatePrReviewInlineTriggerLedger(state.prReviewTriggerLedger)}catch(error49){throw Error(`BLOCKED: persisted PR_REVIEW trigger ledger is invalid: ${error49 instanceof Error?error49.message:String(error49)}`)}if(prReviewTriggerLedgerDigest(frozen.rows)!==prReviewTriggerLedgerDigest(ledger.rows))throw Error("BLOCKED: PR_REVIEW trigger_evaluation must remain exactly identical across every micro dispatch and the final receipt");return state}let nextState={...state,updatedAt:isoNow(),prReviewTriggerLedger:ledger.rows};return await persistState(directory,nextState),nextState}async function assertPrReviewArtifactBoundary(directory,sessionID,runId,boundary,findingIds){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");if(!state.prReviewTriggerEvalPath)throw Error("BLOCKED: PR_REVIEW findings persistence requires the trigger evaluation artifact");let persistedBoundaries=state.prReviewArtifactBoundaries??[],boundaryOrder=["post_explorer","post_reviewer","post_critic"],boundaryIndex=boundaryOrder.indexOf(boundary),requiredPriorBoundary=boundaryOrder[boundaryIndex-1];if(requiredPriorBoundary&&!persistedBoundaries.includes(requiredPriorBoundary))throw Error(`BLOCKED: PR_REVIEW ${boundary} findings require the prior ${requiredPriorBoundary} checkpoint`);if(persistedBoundaries.some((persisted)=>boundaryOrder.indexOf(persisted)>boundaryIndex))throw Error(`BLOCKED: PR_REVIEW ${boundary} findings cannot be persisted after a later checkpoint`);if(boundary==="post_reviewer")state=await assertPrReviewValidationSettled(directory,sessionID,"reviewer");else if(boundary==="post_critic"){if(await assertPrReviewValidationSettled(directory,sessionID,"reviewer"),derivePrReviewCriticInventory(directory,state).length>0)state=await assertPrReviewValidationSettled(directory,sessionID,"critic")}if(state.prReviewArtifactRunId&&state.prReviewArtifactRunId!==runId)throw Error(`BLOCKED: PR_REVIEW artifacts are already bound to run "${state.prReviewArtifactRunId}"`);let expectedFindingIds=derivePrReviewCandidateInventory(directory,state),normalizedFindingIds=[...new Set(findingIds)].sort();if(normalizedFindingIds.length!==findingIds.length||JSON.stringify(normalizedFindingIds)!==JSON.stringify([...expectedFindingIds].sort()))throw Error(`BLOCKED: PR_REVIEW ${boundary} findings must exactly cover the discovered candidate inventory`);return state}async function assertPrReviewArtifactRecordsMatchAuthoritativeVerdicts(directory,sessionID,boundary,records){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");if(boundary==="post_explorer"){for(let record2 of records)if(record2.status!=="PENDING"||record2.next_action!=="route_to_reviewer")throw Error(`BLOCKED: PR_REVIEW post_explorer record ${record2.finding_id} must remain PENDING and route_to_reviewer`);return}let reviewerVerdicts=deriveLatestPrReviewReviewerVerdicts(directory,state),criticVerdicts=boundary==="post_critic"?deriveLatestPrReviewCriticVerdicts(directory,state):void 0;for(let record2 of records){let reviewer=reviewerVerdicts.get(record2.finding_id);if(!reviewer)throw Error(`BLOCKED: PR_REVIEW ${boundary} record ${record2.finding_id} has no authoritative reviewer verdict`);if(record2.severity&&record2.severity!==reviewer.severity)throw Error(`BLOCKED: PR_REVIEW ${boundary} record ${record2.finding_id} severity differs from its reviewer verdict`);let requiresCritic=reviewer.classification==="CONFIRMED"&&["CRITICAL","HIGH","MEDIUM"].includes(reviewer.severity);if(boundary==="post_reviewer"){let expectedStatus=reviewer.classification==="UNVERIFIED"?"PENDING":reviewer.classification;if(record2.status!==expectedStatus)throw Error(`BLOCKED: PR_REVIEW post_reviewer record ${record2.finding_id} status differs from its reviewer verdict`);let expectedAction=requiresCritic?"route_to_critic":reviewer.classification==="CONFIRMED"||reviewer.classification==="PRE_EXISTING"?"report":reviewer.classification==="DISPROVED"?"suppress_with_reason":"route_to_reviewer";if(record2.next_action!==expectedAction)throw Error(`BLOCKED: PR_REVIEW post_reviewer record ${record2.finding_id} action does not match reviewer disposition`);continue}if(!requiresCritic){let expectedStatus=reviewer.classification==="UNVERIFIED"?"PENDING":reviewer.classification,expectedAction=reviewer.classification==="CONFIRMED"||reviewer.classification==="PRE_EXISTING"?"report":reviewer.classification==="DISPROVED"?"suppress_with_reason":"route_to_reviewer";if(record2.status!==expectedStatus||record2.next_action!==expectedAction)throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} cannot override its non-critic reviewer disposition`);continue}let critic=criticVerdicts?.get(record2.finding_id);if(!critic)throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} has no authoritative critic verdict`);if(record2.severity&&record2.severity!==critic.severity)throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} severity differs from its critic verdict`);if(critic.status==="DISPROVED"){if(record2.status!=="DISPROVED"||record2.next_action!=="suppress_with_reason")throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} must preserve the critic DISPROVED disposition`)}else if(record2.status!=="CONFIRMED"||!["report","handoff_to_feedback"].includes(record2.next_action))throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} action does not match its critic verdict`)}}async function markPrReviewArtifactBoundary(directory,sessionID,runId,boundary,artifactPath,findingIds,handoffRequired){let state=await assertPrReviewArtifactBoundary(directory,sessionID,runId,boundary,findingIds),boundaries=new Set(state.prReviewArtifactBoundaries??[]);boundaries.add(boundary);let nextState={...state,updatedAt:isoNow(),prReviewArtifactRunId:runId,prReviewFindingsPath:artifactPath,prReviewArtifactBoundaries:[...boundaries],prReviewHandoffRequired:handoffRequired};return await persistState(directory,nextState),nextState}async function markPrReviewHandoffComplete(directory,sessionID,runId,artifactPath){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");if(state.prReviewArtifactRunId!==runId||!(state.prReviewArtifactBoundaries??[]).includes("post_critic"))throw Error("BLOCKED: PR_REVIEW handoff requires the final findings boundary for the same run");let nextState={...state,updatedAt:isoNow(),prReviewHandoffPath:artifactPath};return await persistState(directory,nextState),nextState}function normalizePrReviewFeedbackHandoffPath(handoffPath){let normalized=handoffPath.trim().replace(/\\/g,"/"),relative4=normalized.startsWith(".swarm/")?normalized.slice(7):normalized,matched=relative4.match(PR_REVIEW_HANDOFF_RELATIVE_PATH_PATTERN);if(!matched)return null;return{runId:matched[1],relativePath:relative4}}async function readBoundedSwarmRegularFile(directory,relativePath,maxBytes,label){let absPath=validateSwarmPath(directory,relativePath),swarmRoot=path14.resolve(directory,".swarm"),rootStat,artifactStat;try{rootStat=await fsp3.lstat(swarmRoot,{bigint:!0}),artifactStat=await fsp3.lstat(absPath,{bigint:!0})}catch(error49){if(error49.code==="ENOENT")throw Error(`BLOCKED: ${label} "${relativePath}" does not exist`);throw error49}if(rootStat.isSymbolicLink()||!rootStat.isDirectory())throw Error(`BLOCKED: ${label} root must be a real project .swarm directory`);if(artifactStat.isSymbolicLink()||!artifactStat.isFile())throw Error(`BLOCKED: ${label} must be a bounded regular file`);if(artifactStat.size>BigInt(maxBytes))throw Error(`BLOCKED: ${label} exceeds ${maxBytes} bytes`);let[realRoot,realArtifact]=await Promise.all([fsp3.realpath(swarmRoot),fsp3.realpath(absPath)]),relativeRealPath=path14.relative(realRoot,realArtifact);if(relativeRealPath===""||relativeRealPath===".."||relativeRealPath.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeRealPath))throw Error(`BLOCKED: ${label} escapes the project .swarm directory`);await _test_exports.beforeBoundedSwarmFileOpen?.();let handle=await fsp3.open(realArtifact,"r");try{let openedStat=await handle.stat({bigint:!0});if(!openedStat.isFile()||openedStat.size>BigInt(maxBytes)||!sameBigIntFileIdentity(artifactStat,openedStat))throw Error(`BLOCKED: ${label} changed during its bounded read`);let[postRootStat,postArtifactStat,postRealRoot,postRealArtifact]=await Promise.all([fsp3.lstat(swarmRoot,{bigint:!0}),fsp3.lstat(absPath,{bigint:!0}),fsp3.realpath(swarmRoot),fsp3.realpath(absPath)]),postRelativeRealPath=path14.relative(postRealRoot,postRealArtifact);if(postRootStat.isSymbolicLink()||!postRootStat.isDirectory()||!sameBigIntFileIdentity(rootStat,postRootStat)||postArtifactStat.isSymbolicLink()||!postArtifactStat.isFile()||!sameBigIntFileIdentity(artifactStat,postArtifactStat)||!sameBigIntFileIdentity(openedStat,postArtifactStat)||normalizeComparableFsPath(realRoot)!==normalizeComparableFsPath(postRealRoot)||normalizeComparableFsPath(realArtifact)!==normalizeComparableFsPath(postRealArtifact)||postRelativeRealPath===""||postRelativeRealPath===".."||postRelativeRealPath.startsWith(`..${path14.sep}`)||path14.isAbsolute(postRelativeRealPath))throw Error(`BLOCKED: ${label} changed or escaped during its bounded read`);let buffer=Buffer.allocUnsafe(maxBytes+1),{bytesRead}=await handle.read(buffer,0,maxBytes+1,0);if(bytesRead>maxBytes)throw Error(`BLOCKED: ${label} exceeds ${maxBytes} bytes`);return buffer.subarray(0,bytesRead).toString("utf8")}finally{await handle.close()}}function sameBigIntFileIdentity(left,right){return left.dev===right.dev&&left.ino===right.ino}function normalizeComparableFsPath(value){let normalized=path14.normalize(path14.resolve(value));return process.platform==="win32"?normalized.toLowerCase():normalized}async function readPrReviewFeedbackHandoffArtifact(directory,relativePath){let raw=await readBoundedSwarmRegularFile(directory,relativePath,PR_REVIEW_HANDOFF_MAX_BYTES,"PR_REVIEW feedback handoff artifact"),parsedJson;try{parsedJson=JSON.parse(raw)}catch{throw Error("BLOCKED: PR_REVIEW feedback handoff artifact is not valid JSON")}let parsed=PrReviewFeedbackHandoffArtifactSchema.safeParse(parsedJson);if(!parsed.success)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact is invalid");if(new Set(parsed.data.finding_ids).size!==parsed.data.finding_ids.length)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact contains duplicate finding IDs");return{artifact:parsed.data,digest:createHash7("sha256").update(raw,"utf8").digest("hex")}}async function readActionableReviewFindingIds(directory,state,runId){let expectedPath=`pr-review/${runId}/findings.jsonl`;if(state.prReviewFindingsPath!==expectedPath)throw Error(`BLOCKED: PR_REVIEW transition requires the exact final findings artifact "${expectedPath}"`);let raw=await readBoundedSwarmRegularFile(directory,expectedPath,PR_REVIEW_FINDINGS_MAX_BYTES,"PR_REVIEW final findings artifact"),latest=new Map;for(let[index,line]of raw.split(/\r?\n/).entries()){if(!line.trim())continue;let value;try{value=JSON.parse(line)}catch{throw Error(`BLOCKED: PR_REVIEW final findings artifact contains invalid JSON at line ${index+1}`)}let parsed=PrReviewFindingProjectionSchema.safeParse(value);if(!parsed.success)throw Error(`BLOCKED: PR_REVIEW final findings artifact contains an invalid record at line ${index+1}`);latest.set(parsed.data.finding_id,parsed.data)}return[...latest.values()].filter((record2)=>record2.status==="CONFIRMED"&&record2.next_action==="handoff_to_feedback").map((record2)=>record2.finding_id).sort()}function canonicalGitHubPrUrl(value){try{let url2=new URL(value);if(url2.protocol!=="https:"||url2.hostname.toLowerCase()!=="github.com")return null;let matched=url2.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(!matched)return null;let prNumber=Number(matched[3]);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return`github.com/${matched[1].toLowerCase()}/${matched[2].toLowerCase()}/pull/${prNumber}`}catch{return null}}function workflowIdentity(state){return state.workflowInstanceId??`legacy-${createHash7("sha256").update(`${state.sessionID}\x00${state.mode}\x00${state.activatedAt}`).digest("hex").slice(0,32)}`}function sameHandoffIds(left,right){let normalizedLeft=[...new Set(left)].sort(),normalizedRight=[...new Set(right)].sort();return sameStringArray(normalizedLeft,normalizedRight)}function assertSamePrFeedbackHandoff(state,relativePath,read,requestedPrUrl){let existing=state.prFeedbackReviewHandoff;if(!existing)throw Error(`BLOCKED: session "${state.sessionID}" is already active in PR_FEEDBACK without persisted review handoff provenance`);let artifactPr=canonicalGitHubPrUrl(read.artifact.pr_url),requestedPr=requestedPrUrl?canonicalGitHubPrUrl(requestedPrUrl):artifactPr;if(!artifactPr||requestedPrUrl&&requestedPr!==artifactPr||existing.path!==relativePath||existing.runId!==read.artifact.run_id||existing.digest!==read.digest||existing.sourcePrHeadSha.toLowerCase()!==read.artifact.pr_head_sha.toLowerCase()||canonicalGitHubPrUrl(existing.prUrl)!==artifactPr||!sameHandoffIds(existing.findingIds,read.artifact.finding_ids))throw Error(`BLOCKED: session "${state.sessionID}" is already active in PR_FEEDBACK for a different handoff or PR`)}async function assertPrReviewTerminalReady(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");await assertPrReviewCleanCheckout(directory,"PR_REVIEW");let open3=readDelegations(directory).filter((record2)=>record2.parentSessionId===state.sessionID&&record2.mode?.startsWith("swarm-pr-")&&(record2.status==="pending"||record2.status==="running"));if(open3.length>0)throw Error(`BLOCKED: PR_REVIEW transition has ${open3.length} unsettled PR workflow lane(s)`);if(await assertPrReviewBaseCoverageSettled(directory,sessionID),!state.prReviewTriggerEvalPath)throw Error("BLOCKED: PR_REVIEW transition requires a persisted trigger evaluation artifact");if((state.prReviewValidationBatches??[]).some((batch)=>batch.phase==="council"))await assertPrReviewValidationSettled(directory,sessionID,"council");await assertPrReviewValidationSettled(directory,sessionID,"reviewer");let criticInventory=derivePrReviewCriticInventory(directory,state);if(criticInventory.length>0){if(!(state.prReviewValidationBatches??[]).some((batch)=>batch.phase==="critic"))throw Error(`BLOCKED: PR_REVIEW reviewer verdicts require critic coverage for: ${criticInventory.join(", ")}`);await assertPrReviewValidationSettled(directory,sessionID,"critic")}let requiredBoundaries=["post_explorer","post_reviewer","post_critic"],persistedBoundaries=new Set(state.prReviewArtifactBoundaries??[]),missing=requiredBoundaries.filter((boundary)=>!persistedBoundaries.has(boundary));if(!state.prReviewFindingsPath||missing.length>0)throw Error(`BLOCKED: PR_REVIEW transition requires durable findings checkpoints; missing: ${missing.join(", ")||"findings path"}`);if(state.prReviewHandoffRequired&&!state.prReviewHandoffPath)throw Error("BLOCKED: PR_REVIEW actionable findings require a persisted feedback handoff artifact");return state}async function transitionPrReviewToFeedback(directory,sessionID,request){let normalizedSessionID=normalizeSessionID(sessionID),normalizedHandoff=normalizePrReviewFeedbackHandoffPath(request.handoffPath);if(!normalizedHandoff||normalizedHandoff.runId!==request.runId)throw Error("BLOCKED: PR-feedback continuation must use .swarm/pr-review/<run_id>/feedback-handoff.json");let preliminaryRead=await readPrReviewFeedbackHandoffArtifact(directory,normalizedHandoff.relativePath),artifact=preliminaryRead.artifact,artifactPr=canonicalGitHubPrUrl(artifact.pr_url),requestedPr=request.prUrl?canonicalGitHubPrUrl(request.prUrl):null;if(!artifactPr||request.prUrl&&requestedPr!==artifactPr)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact does not match the requested GitHub PR URL");if(artifact.run_id!==request.runId)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact does not match the requested review run");let preliminary=await readPrWorkflowGateState(directory,normalizedSessionID);if(preliminary?.mode==="PR_FEEDBACK")return assertSamePrFeedbackHandoff(preliminary,normalizedHandoff.relativePath,preliminaryRead,request.prUrl),preliminary;let sourceIdentity,sourceRevision=0,provenance;if(preliminary){if(preliminary.mode!=="PR_REVIEW")throw wrongModeError(preliminary,"PR_REVIEW");let ready=await assertPrReviewTerminalReady(directory,normalizedSessionID);if(workflowIdentity(ready)!==workflowIdentity(preliminary)||ready.revision!==preliminary.revision||ready.mode!=="PR_REVIEW"||ready.prReviewHandoffPath!==normalizedHandoff.relativePath||ready.prReviewArtifactRunId!==request.runId||!ready.prHeadSha||ready.prHeadSha.toLowerCase()!==artifact.pr_head_sha.toLowerCase()||canonicalGitHubPrUrl(artifact.pr_url)!==canonicalGitHubPrUrl(request.prUrl??artifact.pr_url))throw Error("BLOCKED: PR_REVIEW feedback handoff does not match the terminal active review state");let actionableIds=await readActionableReviewFindingIds(directory,ready,request.runId);if(!sameHandoffIds(actionableIds,artifact.finding_ids))throw Error("BLOCKED: PR_REVIEW feedback handoff finding IDs do not match the authoritative final findings ledger");sourceIdentity=workflowIdentity(ready),sourceRevision=ready.revision,provenance="active-review-v1"}else{if(!request.prUrl)throw Error("BLOCKED: continuing a completed PR_REVIEW requires an explicit GitHub PR URL");sourceIdentity=`external-${preliminaryRead.digest.slice(0,32)}`,provenance="external-v1"}return await _test_exports.beforePrFeedbackTransitionLock?.(),withSessionStateMutation(directory,normalizedSessionID,async()=>{let current=await readPrWorkflowGateStateFromDisk(directory,normalizedSessionID);if(current?.mode==="PR_FEEDBACK")return assertSamePrFeedbackHandoff(current,normalizedHandoff.relativePath,preliminaryRead,request.prUrl),current;if(provenance==="active-review-v1"){if(!current||current.mode!=="PR_REVIEW"||workflowIdentity(current)!==sourceIdentity||current.revision!==sourceRevision||current.prHeadSha?.toLowerCase()!==artifact.pr_head_sha.toLowerCase()||current.prReviewArtifactRunId!==request.runId||current.prReviewHandoffPath!==normalizedHandoff.relativePath)throw Error("BLOCKED: PR_REVIEW state changed while validating the feedback handoff; retry from current state")}else if(current)throw Error("BLOCKED: another PR workflow became active while validating the external handoff");let lockedRead=await readPrReviewFeedbackHandoffArtifact(directory,normalizedHandoff.relativePath);if(lockedRead.digest!==preliminaryRead.digest)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact changed during transition");if(artifactPr!==canonicalGitHubPrUrl(lockedRead.artifact.pr_url)||lockedRead.artifact.run_id!==request.runId||lockedRead.artifact.pr_head_sha.toLowerCase()!==artifact.pr_head_sha.toLowerCase()||!sameHandoffIds(lockedRead.artifact.finding_ids,artifact.finding_ids))throw Error("BLOCKED: PR_REVIEW feedback handoff artifact changed during transition");let timestamp=isoNow(),nextState={schemaVersion:GATE_SCHEMA_VERSION,revision:sourceRevision,workflowInstanceId:randomUUID2(),sessionID:normalizedSessionID,mode:"PR_FEEDBACK",activatedAt:timestamp,updatedAt:timestamp,prFeedbackReviewHandoff:{path:normalizedHandoff.relativePath,runId:lockedRead.artifact.run_id,sourcePrHeadSha:lockedRead.artifact.pr_head_sha.toLowerCase(),prUrl:lockedRead.artifact.pr_url,findingIds:[...new Set(lockedRead.artifact.finding_ids)].sort(),digest:preliminaryRead.digest,sourceWorkflowInstanceId:sourceIdentity,provenance},prFeedbackTargetUrl:artifact.pr_url};return writeStateWhileLocked(directory,nextState,{replaceWorkflowInstanceId:provenance==="active-review-v1"?current?.workflowInstanceId:void 0})})}async function declarePrFeedbackScope(directory,sessionID,taskId,files){let state=await assertPrFeedbackVerificationSettled(directory,sessionID),revisionDigest=await currentPrFeedbackRevisionDigest(directory,state),previous=state.prFeedbackScopes??[];if(previous.find((entry)=>entry.taskId===taskId)?.consumedByCallId)throw Error(`SCOPE_NOT_DECLARED: PR-feedback scope ${taskId} was already consumed; use a fresh task_id for any retry`);let record2={taskId,files,revisionDigest,declaredAt:isoNow()},nextState={...state,updatedAt:isoNow(),prFeedbackScopes:[...previous.filter((entry)=>entry.taskId!==taskId),record2]};return await persistState(directory,nextState),nextState}async function resolvePrFeedbackScopeDeclaration(directory,sessionID,taskId){let state=await readPrWorkflowGateState(directory,sessionID);if(state?.mode!=="PR_FEEDBACK")return null;let declaration=(state.prFeedbackScopes??[]).find((entry)=>entry.taskId===taskId);if(!declaration)return null;return await assertPrFeedbackVerificationSettled(directory,sessionID),await currentPrFeedbackRevisionDigest(directory,state)===declaration.revisionDigest?declaration:null}async function consumePrFeedbackScopeDeclaration(directory,sessionID,taskId,callID){let declaration=await resolvePrFeedbackScopeDeclaration(directory,sessionID,taskId);if(!declaration)return null;if(declaration.consumedByCallId&&declaration.consumedByCallId!==callID)throw Error(`SCOPE_NOT_DECLARED: PR-feedback scope ${taskId} was already consumed by another Task call`);if(declaration.consumedByCallId===callID)return declaration;let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),nextState={...state,updatedAt:isoNow(),prFeedbackScopes:(state.prFeedbackScopes??[]).map((entry)=>entry.taskId===taskId?{...entry,consumedByCallId:callID}:entry)};return await persistState(directory,nextState),{...declaration,consumedByCallId:callID}}async function validatePrFeedbackScopeBinding(directory,binding){if(!binding.workflowSessionId||!binding.workflowRevisionDigest)return!1;let declaration=await resolvePrFeedbackScopeDeclaration(directory,binding.workflowSessionId,binding.taskId);return Boolean(declaration&&declaration.consumedByCallId===binding.dispatchCallId&&declaration.revisionDigest===binding.workflowRevisionDigest&&JSON.stringify(declaration.files)===JSON.stringify(binding.files))}async function enforcePrWorkflowToolBefore(directory,sessionID,toolName,args2,generatedAgentNames=[]){let state=await readPrWorkflowGateState(directory,sessionID);if(!state)return;let normalizedTool=toolName.toLowerCase(),isDirectAgentTask=normalizedTool==="task"||normalizedTool==="run_agent",requestedRoles=["subagent_type","agent"].filter((field)=>Object.hasOwn(args2??{},field)).map((field)=>{let value=args2?.[field];if(typeof value!=="string"||!value.trim())return"";return resolveGeneratedAgentRole(value.trim(),generatedAgentNames)}),isDirectWrite=WRITE_TOOL_NAMES.includes(normalizedTool),command=typeof args2?.command==="string"?args2.command.trim():"",serializedArgs=JSON.stringify(args2??{}),referencesProtectedWorkflowEvidence=containsProtectedWorkflowPath(command||serializedArgs),isInternalWorkflowTool=isPrWorkflowControllerTool(state.mode,normalizedTool),isShellTool=normalizedTool==="bash"||normalizedTool==="shell",isReadOnlyShell=!1,shellPermissionEnvelope=null;if(isShellTool&&command.length>0){let trackingFetchTarget=state.prHeadSha?await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory):null;shellPermissionEnvelope={allowCheckout:!state.prHeadSha,allowFetch:!state.prHeadSha,allowTrackingFetch:Boolean(state.prHeadSha),trackingFetchTarget},isReadOnlyShell=isAllowedPrWorkflowReadOnlyShell(command,shellPermissionEnvelope)}let trustedCapability=getPrWorkflowToolCapability(normalizedTool,state.mode),isNamedReadOnlyTool=trustedCapability!==null&&isTrustedPrWorkflowToolInvocationSafe(normalizedTool,args2??{})||normalizedTool!=="build_check"&&isAllowedPrReviewReadOnlyToolName(normalizedTool)&&readOnlyToolArgumentsAreSafe(args2??{}),isRecoverySafeEvidenceTool=trustedCapability==="observe"&&isTrustedPrWorkflowToolInvocationSafe(normalizedTool,args2??{})||normalizedTool!=="build_check"&&isAllowedPrReviewReadOnlyToolName(normalizedTool)&&readOnlyToolArgumentsAreSafe(args2??{});if(state.checkoutRecovery){if(isRecoverySafeEvidenceTool||isReadOnlyShell||normalizedTool==="abort_pr_workflow"||normalizedTool==="pr_workflow_status"||normalizedTool==="prepare_pr_workflow_checkout")return;throw Error(`BLOCKED: ${state.mode} requires manual Git recovery before controller work can continue. code=${state.checkoutRecovery.code} retryable=false required_action=${state.checkoutRecovery.requiredAction}`)}if(referencesProtectedWorkflowEvidence&&!isInternalWorkflowTool&&!isNamedReadOnlyTool&&!isReadOnlyShell)throw Error(`BLOCKED: active ${state.mode} workflow evidence under .swarm is controller-owned and cannot be modified directly`);let isShellCommandRequiringVerification=isShellTool&&command.length>0&&!isReadOnlyShell,isRemoteReviewTool=/(?:git|github|pull|(?:^|[_-])pr(?:[_-]|$)|issue|review)/i.test(normalizedTool),hasRemoteMutationVerb=/(?:^|[_-])(?:add|approve|cancel|close|comment|commit|convert|create|delete|dismiss|edit|mark|merge|push|ready|reopen|rerun|resolve|submit|transfer|unresolve|update)(?:[_-]|$)/i.test(normalizedTool),hasRemoteReadVerb=/(?:^|[_-])(?:github|git)[_-]+(?:check|checks|checkout|diff|fetch|get|inspect|list|read|search|status|view)(?:[_-]|$)/i.test(normalizedTool)||/(?:^|[_-])(?:github|git)[_-]+(?:pull[_-]+request|pr|issue|review[_-]+thread)[_-]+(?:check|checks|checkout|diff|fetch|get|inspect|list|read|search|status|view)(?:[_-]|$)/i.test(normalizedTool),isRemoteMutationTool=isRemoteReviewTool&&(hasRemoteMutationVerb||!hasRemoteReadVerb),isRemoteCheckoutTool=/(?:^|[_-])(?:github|git)[_-]+checkout(?:[_-]|$)/i.test(normalizedTool),isShellCheckout=(normalizedTool==="bash"||normalizedTool==="shell")&&(/\bgit\b(?:(?![;&|]).){0,200}\b(?:checkout|switch)\b/i.test(command)||/\bgh\s+pr\s+checkout\b/i.test(command)),stderrMergeNormalizedCommand=command.replace(PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN,"").trim(),isCanonicalReviewCheckout=/^git\s+switch\s+--detach\s+[0-9a-f]{40,64}$/i.test(stderrMergeNormalizedCommand),detachedFeedbackSwitchMatch=command.match(/^git\s+switch\s+--detach\s+(\S+)$/i),isDetachedFeedbackCheckout=Boolean(detachedFeedbackSwitchMatch?.[1]&&isSafeGitRefToken(detachedFeedbackSwitchMatch[1]))||/^gh\s+pr\s+checkout\b.*\s--detach(?:\s|$)/i.test(command),containsGitCommitShell=isShellCommandRequiringVerification&&/\bgit\b(?:(?![;&|]).){0,200}\bcommit\b/i.test(command),isStandaloneGitCommitShell=containsGitCommitShell&&isSafeStandaloneGitCommit(command),isPublicationShell=isShellCommandRequiringVerification&&(/\bgit\b(?:(?![;&|]).){0,200}\bpush\b/i.test(command)||/\bgh\s+(?:api|pr|issue|run)\b/i.test(command)),isPublicationTool=!isInternalWorkflowTool&&isRemoteMutationTool,isCoderTask=isDirectAgentTask&&requestedRoles.length>0&&requestedRoles.every((role)=>role==="coder"),blockedShellDiagnosis=isShellTool&&command&&!isReadOnlyShell&&shellPermissionEnvelope?` ${describeBlockedPrReviewShellCommand(command,shellPermissionEnvelope)}`:"";if(state.mode==="PR_REVIEW"){if(!(isInternalWorkflowTool||isNamedReadOnlyTool||isReadOnlyShell&&(!isShellCheckout||isCanonicalReviewCheckout))||Boolean(state.prHeadSha)&&(isRemoteCheckoutTool||isShellCheckout)){if(!state.prHeadSha&&isShellCheckout)throw Error("BLOCKED: PR_REVIEW checkout must use standalone commands: fetch the PR head, verify the full commit object with `git cat-file -e <full_pr_head_sha>^{commit}`, then run `git switch --detach <full_pr_head_sha>` and bind that exact head before dispatching explorer lanes. Do not use `--track FETCH_HEAD`."+blockedShellDiagnosis);throw Error("BLOCKED: PR_REVIEW is read-only and fail-closed; only controller tools and positively classified observation tools are allowed, and every agent lane requires structured dispatch_lanes_async"+describePrWorkflowControllerToolNames(state.mode)+blockedShellDiagnosis)}return}if(isDirectAgentTask&&!isCoderTask)throw Error("BLOCKED: PR_FEEDBACK reviewer, test, critic, explorer, and unknown agent lanes require structured dispatch_lanes_async provenance");if(!isInternalWorkflowTool&&!isDirectAgentTask&&!isDirectWrite&&!isShellTool&&!isNamedReadOnlyTool)throw Error("BLOCKED: PR_FEEDBACK rejects unclassified plugin/MCP tools; use positively classified observation tools, built-in structured write tools after verification, or the workflow controller"+describePrWorkflowControllerToolNames(state.mode));if(state.prHeadSha&&(isShellCheckout||isRemoteCheckoutTool))throw Error("BLOCKED: PR_FEEDBACK checkout is immutable after exact PR head binding");if(containsGitCommitShell&&state.prFeedbackReadyToPublish)throw Error("BLOCKED: PR_FEEDBACK is armed for publication; the approved commit is immutable");if((containsGitCommitShell||isPublicationShell)&&hasUnsafeShellControlSyntax(command))throw Error("BLOCKED: PR_FEEDBACK publication commands must be standalone shell commands without control, redirection, or command-substitution syntax");if(containsGitCommitShell&&!isStandaloneGitCommitShell)throw Error("BLOCKED: PR_FEEDBACK commit must use a standalone git commit command after every ordered local gate passes");if(state.prFeedbackReadyToPublish){if(normalizedTool==="complete_pr_workflow")return;if(isNamedReadOnlyTool)return;if((normalizedTool==="bash"||normalizedTool==="shell")&&command.length>0&&isAllowedPrWorkflowReadOnlyShell(command,{allowCheckout:!1,allowFetch:!1,allowTrackingFetch:!1}))return;if(normalizedTool==="bash"||normalizedTool==="shell"){let armed=(await assertPrFeedbackPublicationArmed(directory,sessionID)).prFeedbackReadyToPublish;if(isSafeExactBoundPush(command,armed))return;throw Error(`BLOCKED: PR_FEEDBACK is armed for publication; only the exact approved push is allowed: ${expectedBoundPushCommand(armed)}`)}throw Error("BLOCKED: PR_FEEDBACK is armed for publication; only read-only inspection, the exact approved push, and complete_pr_workflow are allowed")}if(!state.prHeadSha&&normalizedTool==="prepare_pr_workflow_checkout")return;if(!state.prHeadSha&&isDetachedFeedbackCheckout&&!isCanonicalReviewCheckout)throw Error("BLOCKED: PR_FEEDBACK checkout should use one exact local tracking branch, such as `gh pr checkout <number> --branch <local_branch>` or `git switch -c <local_branch> --track <remote>/<branch>`, before binding. If checkout is already detached at the authoritative full PR head SHA, bind it directly; the controller attaches one unambiguous exact tracking ref. Other detached refs are not accepted");if(!state.prHeadSha&&isCanonicalReviewCheckout)return;if(isStandaloneGitCommitShell){await assertPrFeedbackReadyToPublish(directory,sessionID);return}if(isPublicationShell||isPublicationTool)throw Error("BLOCKED: PR_FEEDBACK publication is not armed; finish every ordered gate, create the one approved commit, and call complete_pr_workflow before publishing");if(isShellCommandRequiringVerification){if(!state.prHeadSha&&isShellCheckout)throw Error("BLOCKED: PR_FEEDBACK checkout should use one exact local tracking branch, such as `gh pr checkout <number> --branch <local_branch>` or `git switch -c <local_branch> --track <remote>/<branch>`, before binding. If checkout is already detached at the authoritative full PR head SHA, bind it directly; the controller attaches one unambiguous exact tracking ref");throw Error("BLOCKED: PR_FEEDBACK shell commands fail closed unless they are explicit read-only intake or the one standalone approved git commit; use structured coder/write tools for fixes and run_pr_feedback_stage_a for validation")}if(!isDirectWrite&&!isShellCommandRequiringVerification&&!isRemoteMutationTool&&!isCoderTask&&normalizedTool!=="prepare_pr_feedback_scope")return;if(normalizedTool==="abort_pr_workflow")return;await assertPrFeedbackVerificationSettled(directory,sessionID)}async function completePrWorkflow(directory,sessionID,expectedMode,prHeadSha){let state=await requireBoundState(directory,sessionID,expectedMode),normalizedHead=normalizePrHeadSha(prHeadSha);if(state.prHeadSha!==normalizedHead)throw Error(`BLOCKED: cannot complete ${expectedMode} at PR head "${normalizedHead}"; workflow is bound to "${state.prHeadSha}"`);let open3=readDelegations(directory).filter((record2)=>record2.parentSessionId===state.sessionID&&record2.mode?.startsWith("swarm-pr-")&&(record2.status==="pending"||record2.status==="running"));if(open3.length>0)throw Error(`BLOCKED: ${expectedMode} completion has ${open3.length} unsettled PR workflow lane(s)`);if(expectedMode==="PR_REVIEW"){let readyState=await assertPrReviewTerminalReady(directory,sessionID);if(workflowIdentity(readyState)!==workflowIdentity(state)||readyState.revision!==state.revision)throw Error("BLOCKED: PR_REVIEW state changed while checking terminal readiness; retry from current state")}else{let readyState=await assertPrFeedbackReadyToPublish(directory,sessionID),currentDigest=await currentPrFeedbackRevisionDigest(directory,readyState),armed=readyState.prFeedbackReadyToPublish;if(!armed){let localHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(!localHead)throw Error("BLOCKED: PR_FEEDBACK cannot arm publication without a verified local Git HEAD");if(await _test_exports.resolveCommitCountSinceAsync(directory,state.prHeadSha,localHead)!==1)throw Error("BLOCKED: PR_FEEDBACK publication requires exactly one descendant commit after the immutable intake head");if(await _test_exports.resolveIsExactSingleChildCommitAsync(directory,state.prHeadSha,localHead)!==!0)throw Error("BLOCKED: PR_FEEDBACK publication commit must be a non-merge direct child of the immutable intake head");if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error("BLOCKED: PR_FEEDBACK publication requires a clean index and working tree so all approved content is captured by the bound commit");let upstreamTarget=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory);if(!upstreamTarget)throw Error("BLOCKED: PR_FEEDBACK cannot arm publication without a current branch bound to an exact remote name, remote branch ref, and remote-tracking ref");return await persistState(directory,{...readyState,updatedAt:isoNow(),prFeedbackReadyToPublish:{revisionDigest:currentDigest,localHead,remoteName:upstreamTarget.remoteName,remoteBranchRef:upstreamTarget.remoteBranchRef,remoteRef:upstreamTarget.remoteTrackingRef,validatedAt:isoNow()}}),"ready-to-publish"}if(armed.revisionDigest!==currentDigest)throw Error("BLOCKED: PR_FEEDBACK publication revision differs from the independently approved content digest");let publishedHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim(),remoteRefs=publishedHead?await _test_exports.resolveRemoteRefsContainingHeadAsync(directory,publishedHead):null,remoteHead=await _test_exports.resolveExactRemoteBranchHeadAsync(directory,armed.remoteName,armed.remoteBranchRef);if(!publishedHead||publishedHead!==armed.localHead||!remoteRefs?.includes(armed.remoteRef)||remoteHead?.toLowerCase()!==armed.localHead.toLowerCase())throw Error(`BLOCKED: PR_FEEDBACK completion requires approved commit ${armed.localHead} at current Git HEAD and intended remote-tracking ref ${armed.remoteRef} at that exact commit`)}return await _test_exports.beforeTerminalClear?.(),await clearPrWorkflowGateState(directory,sessionID,state.revision),"completed"}async function requireAnyActiveState(directory,sessionID){let state=await readPrWorkflowGateState(directory,sessionID);if(!state)throw Error(`BLOCKED: no active PR workflow gate for session "${normalizeSessionID(sessionID)}". The gate is activated by running \`/swarm pr-review <pr-ref>\` (PR_REVIEW) or \`/swarm pr-feedback <pr-ref>\` (PR_FEEDBACK), or by the first dispatch_lanes_async call with mode "swarm-pr-review:*" / "swarm-pr-feedback:*".`);return state}async function requireBoundState(directory,sessionID,expectedMode){let state=await requireAnyActiveState(directory,sessionID);if(state.mode!==expectedMode)throw wrongModeError(state,expectedMode);if(!state.prHeadSha)throw Error(`BLOCKED: active ${expectedMode} workflow is not bound to a PR head`);if(expectedMode==="PR_REVIEW")await assertCurrentCheckoutHead(directory,state.prHeadSha,"PR_REVIEW"),await assertPrReviewCleanCheckout(directory);return state}function wrongModeError(state,expectedMode){return Error(`BLOCKED: session "${state.sessionID}" is active in ${state.mode}, not ${expectedMode}`)}function normalizeWorkflowLanes(lanes){if(!Array.isArray(lanes)||lanes.length===0)throw Error("BLOCKED: PR workflow lane validation requires at least one lane");let normalized=lanes.map((lane)=>{let workflowLane=lane.workflowLane?.trim(),laneId=lane.laneId?.trim()||workflowLane;if(!workflowLane||!laneId)throw Error("BLOCKED: PR workflow lane validation requires every lane to have non-empty laneId and workflow_lane values");let reviewItemIds=lane.reviewItemIds?.map((itemId)=>itemId.trim());if(reviewItemIds?.some((itemId)=>!itemId))throw Error("BLOCKED: PR workflow review_item_ids must not contain empty values");if(reviewItemIds)assertNoDuplicates(reviewItemIds,"review item ids within one lane");let ownedWorkflowLanes=lane.ownedWorkflowLanes?.map((owned)=>owned.trim());if(ownedWorkflowLanes){if(ownedWorkflowLanes.some((owned)=>!owned))throw Error("BLOCKED: PR workflow owned_workflow_lanes must not contain empty values");if(assertNoDuplicates(ownedWorkflowLanes,"owned workflow lanes within one lane"),!ownedWorkflowLanes.includes(workflowLane))throw Error(`BLOCKED: PR workflow lane "${laneId}" must include its own workflow_lane "${workflowLane}" in owned_workflow_lanes`)}return{laneId,workflowLane,...reviewItemIds?{reviewItemIds}:{},...ownedWorkflowLanes?{ownedWorkflowLanes}:{}}});return assertNoDuplicates(normalized.map((lane)=>lane.laneId),"lane ids"),assertNoDuplicates(normalized.map((lane)=>lane.workflowLane),"workflow lane ids"),assertNoDuplicates(normalized.flatMap((lane)=>lane.ownedWorkflowLanes??[lane.workflowLane]),"owned workflow lane ids across lanes"),normalized}function normalizeInventoryIds(inventoryIds){if(!Array.isArray(inventoryIds)||inventoryIds.length===0)throw Error("BLOCKED: PR_FEEDBACK inventory declaration requires at least one feedback item id");let normalized=inventoryIds.map((inventoryId)=>{let itemId=inventoryId.trim();if(!itemId)throw Error("BLOCKED: PR_FEEDBACK inventory declaration contains an empty item id");return itemId});return assertNoDuplicates(normalized,"inventory item ids"),normalized.sort()}function normalizeOwnership(ownership){if(!Array.isArray(ownership)||ownership.length===0)throw Error("BLOCKED: PR_FEEDBACK verification ownership requires at least one lane declaration");let normalized=ownership.map((lane)=>{let laneId=lane.laneId?.trim();if(!laneId)throw Error("BLOCKED: PR_FEEDBACK verification ownership requires every lane to have a non-empty laneId");let ownedItemIds=normalizeInventoryIds(lane.ownedItemIds);return{laneId,ownedItemIds}});return assertNoDuplicates(normalized.map((lane)=>lane.laneId),"PR_FEEDBACK verification lane ids"),normalized}function assertNoDuplicates(values,label){let seen=new Set;for(let value of values){if(seen.has(value))throw Error(`BLOCKED: duplicate ${label} are not allowed: ${value}`);seen.add(value)}}function containsProtectedWorkflowPath(value){return/(?:^|[^A-Za-z0-9_.-])\.swarm(?:[\\/]|$)/i.test(value.replace(/\\\\/g,"\\"))}function isPrWorkflowControllerTool(mode,toolName){if(PR_WORKFLOW_SHARED_CONTROLLER_TOOLS.has(toolName))return!0;return mode==="PR_REVIEW"?PR_REVIEW_CONTROLLER_TOOLS.has(toolName):PR_FEEDBACK_CONTROLLER_TOOLS.has(toolName)}function describePrWorkflowControllerToolNames(mode){let modeTools=mode==="PR_REVIEW"?PR_REVIEW_CONTROLLER_TOOLS:PR_FEEDBACK_CONTROLLER_TOOLS,names=[...PR_WORKFLOW_SHARED_CONTROLLER_TOOLS,...modeTools].sort((a,b)=>a.localeCompare(b));return` Allowed controller tools for ${mode}: ${names.join(", ")}. Observe current state read-only with the pr_workflow_status tool.`}function isTrustedPrWorkflowToolInvocationSafe(toolName,args2){if(toolName==="lint")return args2.mode==="check";if(toolName==="sast_scan")return args2.capture_baseline!==!0;return!0}function isAllowedPrReviewReadOnlyToolName(toolName){if(PR_REVIEW_READ_ONLY_TOOL_NAMES.has(toolName))return!0;let tokens=toolName.split(/[._:/-]+/).filter(Boolean);if(tokens.some((token)=>/^(?:add|alter|and|append|apply|approve|cancel|checkout|close|comment|commit|convert|create|delete|destroy|dismiss|drop|edit|execute|grant|insert|mark|merge|move|patch|prepend|publish|push|ready|remove|rename|replace|resolve|rerun|revoke|run|send|submit|then|transfer|truncate|unresolve|update|upload|write)$/i.test(token)))return!1;return tokens.some((token)=>/^(?:check|checks|diff|fetch|find|get|glob|grep|hover|inspect|list|lookup|open|read|references|scan|screenshot|search|show|status|symbols|tree|view)$/i.test(token))}function readOnlyToolArgumentsAreSafe(value,key="",depth=0){if(depth>8)return!1;let keyTokens=key.replace(/([a-z0-9])([A-Z])/g,"$1_$2").split(/[._:/-]+/).filter(Boolean);if(keyTokens.some((token)=>/^(?:append|body|content|create|data|delete|destination|destroy|edit|insert|mutation|output|patch|payload|prepend|remove|replace|save|set|truncate|update|upload|write)$/i.test(token)))return!1;if(keyTokens.some((token)=>/^(?:method|verb)$/i.test(token)))return typeof value==="string"&&/^(?:GET|HEAD)$/i.test(value.trim());if(keyTokens.length===1&&keyTokens.some((token)=>/^(?:action|operation)$/i.test(token)))return typeof value==="string"&&/^(?:check|diff|fetch|find|get|inspect|list|lookup|open|read|scan|search|show|status|view)$/i.test(value.trim());if(/^mode$/i.test(key)&&typeof value==="string")return/^(?:r|rb|read)$/i.test(value.trim());if(typeof value==="string"){if(keyTokens.some((token)=>/^(?:query|request|sql|statement)$/i.test(token))&&/(?:\b(?:alter|call|comment|create|delete|drop|exec(?:ute)?|grant|insert|merge|mutation|replace|revoke|truncate|update|upsert)\b|\bselect\b[\s\S]{0,4000}\binto\s+[A-Za-z_"'`])/i.test(value))return!1;return!/(?:^(?:POST|PUT|PATCH|DELETE|CONNECT|TRACE|write|edit|patch|create|delete|destroy|remove|replace|truncate|update|upload)$|(?:^|[\r\n])\s*(?:POST|PUT|PATCH|DELETE|CONNECT|TRACE)\s+\S+(?:\s+HTTP\/\d(?:\.\d)?)?|\bmutation\b|\b(?:create|drop|alter|truncate)\s+(?:or\s+replace\s+)?(?:table|database|schema|index|view|function|procedure|trigger|sequence)\b|\b(?:delete\s+from|insert\s+into|merge\s+into|replace\s+into|upsert\s+into)\b|\bupdate\s+[A-Za-z0-9_."'`-]+(?:\s+(?:AS\s+)?[A-Za-z0-9_"'`-]+)?\s+set\b|\b(?:grant|revoke)\s+\S+\s+(?:on|from|to)\b|\b(?:call|exec(?:ute)?)\s+[A-Za-z0-9_."'`-]+|\b(?:rm|rmdir|del|remove-item|move-item|set-content|add-content)\b)/i.test(value)}if(value===null||value===void 0||typeof value==="number"||typeof value==="boolean")return!0;if(Array.isArray(value))return value.every((entry)=>readOnlyToolArgumentsAreSafe(entry,key,depth+1));if(typeof value==="object")return Object.entries(value).every(([childKey,childValue])=>readOnlyToolArgumentsAreSafe(childValue,childKey,depth+1));return!1}function normalizePrWorkflowShellCommand(command){let normalized=command.trim(),withoutTrailingMerge=normalized.replace(PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN,"");if(withoutTrailingMerge!==normalized)normalized=withoutTrailingMerge.trim();let strippedCdPrefix=!1;for(let index=0;index<PR_WORKFLOW_MAX_CD_PREFIX_STRIPS;index+=1){let next=normalized.replace(PR_WORKFLOW_CD_PREFIX_PATTERN,"");if(next===normalized)break;normalized=next.trim(),strippedCdPrefix=!0}return{normalized,strippedCdPrefix}}function isAllowedPrWorkflowReadOnlyShell(command,options){let{normalized:inner,strippedCdPrefix}=normalizePrWorkflowShellCommand(command),normalized=inner.replace(/\s+/g," ");if(!normalized)return!1;if(/[\r\n;&|<>`]/.test(inner)||/\$\(|@\(/.test(inner))return!1;if(strippedCdPrefix&&(/^git (?:fetch|checkout|switch|branch)(?:\s|$)/i.test(normalized)||/^gh pr checkout(?:\s|$)/i.test(normalized)))return!1;let gitMatch=normalized.match(PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN);if(gitMatch?.[1]){if(PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN.test(normalized)&&/^(?:fetch|checkout|switch|branch)(?:\s|$)/i.test(gitMatch[1]))return!1;return isAllowedPrWorkflowGitIntake(gitMatch[1],options)}if(/^gh /i.test(normalized))return isAllowedPrFeedbackGhIntake(normalized);if(/^rg\b/i.test(normalized)&&/\s--pre(?:-glob)?(?:\s|=|$)/i.test(normalized))return!1;return/^(?:rg|grep|cat|Get-Content|Select-String|Test-Path|Get-ChildItem|ls|dir|pwd|which|where)(?:\s|$)/i.test(normalized)}function describeBlockedPrReviewShellCommand(command,options){let{normalized:inner,strippedCdPrefix}=normalizePrWorkflowShellCommand(command),normalized=inner.replace(/\s+/g," "),gitMatch=normalized.match(PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN),pointer=" Observe HEAD/branch/dirty/remotes/gate state read-only with the pr_workflow_status tool.",detail;if(/[\r\n;&|<>`]/.test(inner)||/\$\(|@\(/.test(inner))detail="Reason: compound-syntax (;, &&, |, <, >, backtick, or $()/@()). Run ONE command per call; a single leading `cd <dir> &&` and a trailing `2>&1` are tolerated for reads only.";else if(strippedCdPrefix&&(/^git (?:fetch|checkout|switch|branch)(?:\s|$)/i.test(normalized)||/^gh pr checkout(?:\s|$)/i.test(normalized)))detail="Reason: cd-prefix-on-checkout-verb. Run fetch/checkout/switch/branch or `gh pr checkout` bare, with no `cd <dir> &&` prefix.";else if(PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN.test(normalized)&&gitMatch?.[1]&&/^(?:fetch|checkout|switch|branch)(?:\s|$)/i.test(gitMatch[1]))detail="Reason: git -C on a state transition. Run fetch/checkout/switch/branch from the target directory, not via `git -C <dir>`.";else if(!options.allowFetch&&gitMatch?.[1]&&/^fetch(?:\s|$)/i.test(gitMatch[1]))detail=options.allowTrackingFetch?"Reason: bound-fetch-restriction. After the PR head is bound only the exact bound remote-tracking fetch is allowed; read remote state via gh_evidence otherwise.":"Reason: bound-fetch-restriction. Fetch is not permitted in this bound state; read remote state via gh_evidence instead.";else if(gitMatch?.[1]||/^git(?:\s|$)/i.test(normalized))detail="Reason: unlisted git verb. Allowed git reads: status/log/show/diff/rev-parse/merge-base/ls-files/grep/blame/cat-file/for-each-ref, `branch` with listing flags only, `stash list`, `worktree list`, `remote -v`, `config --get`.";else if(/^gh(?:\s|$)/i.test(normalized))detail="Reason: unlisted gh form. Allowed gh reads: pr view/diff/checks/status/list, run view/list/watch, issue view/list, search, api GET. If gh is missing, fetch the api.github.com REST URL with the web fetch tool.";else detail="Reason: unlisted binary. Allowed: rg/grep/cat/ls/dir/pwd/which/where plus read-only git/gh intake.";return detail+" Observe HEAD/branch/dirty/remotes/gate state read-only with the pr_workflow_status tool."}function hasUnsafeShellControlSyntax(command){return/[;&|<>`\r\n]/.test(command)||/\$\(/.test(command)}function isSafeStandaloneGitCommit(command){if(hasUnsafeShellControlSyntax(command))return!1;if(/(?:^|\s)--(?:allow-empty|amend)(?:\s|=|$)/i.test(command))return!1;return/^[Gg][Ii][Tt](?:\s+-C(?:=|\s+)(?:"[^"\r\n]+"|'[^'\r\n]+'|[^\s;&|<>`]+))?\s+commit(?:\s+(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s;&|<>`]+))*\s*$/.test(command.trim())}function boundPushTarget(armed){let remote=armed.remoteName,branch=armed.remoteBranchRef.slice(11);if(!armed.remoteBranchRef.startsWith("refs/heads/")||!branch)return null;if(/\s|[;&|<>`]/.test(remote)||/\s|[;&|<>`]/.test(branch))return null;return{remote,branch}}function expectedBoundPushCommand(armed){let target=boundPushTarget(armed);return target?`git push ${target.remote} ${armed.localHead}:refs/heads/${target.branch}`:"(invalid bound remote-tracking ref; restart the workflow)"}function isSafeExactBoundPush(command,armed){if(hasUnsafeShellControlSyntax(command))return!1;let target=boundPushTarget(armed);if(!target)return!1;let match=command.trim().match(/^git\s+push\s+([^\s;&|<>`]+)\s+([^\s;&|<>`]+)\s*$/i);if(!match)return!1;return match[1]===target.remote&&match[2]===`${armed.localHead}:refs/heads/${target.branch}`}function isAllowedPrWorkflowGitIntake(gitArgs,options){if(/(?:--ext-diff|--textconv|--open-files-in-pager|--output(?:=|\s)|--upload-pack(?:=|\s)|--exec(?:=|\s))/i.test(gitArgs))return!1;if(/^(?:status|log|show|diff|rev-parse|merge-base|ls-files|grep|blame|cat-file|for-each-ref|--version|version)(?:\s|$)/i.test(gitArgs))return!0;if(isAllowedReadOnlyGitBranchListing(gitArgs))return!0;if(isAllowedReadOnlyGitStashListing(gitArgs))return!0;if(isAllowedReadOnlyGitWorktreeListing(gitArgs))return!0;if(options.allowFetch&&/^fetch(?:\s|$)/i.test(gitArgs))return!0;if(options.allowTrackingFetch&&isAllowedBoundRemoteTrackingFetch(gitArgs,options.trackingFetchTarget))return!0;if(/^remote(?:\s+-v)?$/i.test(gitArgs))return!0;if(options.allowCheckout&&isAllowedPreBindBranchSetup(gitArgs))return!0;if(options.allowCheckout&&/^(?:checkout|switch)\s+(?:--detach\s+)?[^\s-][^\s]*$/i.test(gitArgs))return!0;return/^config\s+(?:(?:--show-origin|--show-scope|--global|--local|--system|--worktree)\s+)*(?:--list|--get(?:-all)?\s+\S+)$/i.test(gitArgs)}function isAllowedBoundRemoteTrackingFetch(gitArgs,target){if(!target?.remoteName||!target.remoteBranchRef.startsWith("refs/heads/"))return!1;let tokens=gitArgs.trim().split(/\s+/);if(tokens.length!==3||tokens[0].toLowerCase()!=="fetch")return!1;let[,remote,remoteBranch]=tokens,expectedBranch=target.remoteBranchRef.slice(11);return isSafeGitRefToken(remote)&&!remote.includes("/")&&isSafeGitRefToken(remoteBranch)&&!remoteBranch.startsWith("-")&&!remoteBranch.includes(":")&&remote===target.remoteName&&remoteBranch===expectedBranch}function isAllowedPreBindBranchSetup(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length===5){let[verb,createFlag,localBranch,trackFlag,upstream]=tokens;return(verb==="checkout"||verb==="switch")&&(createFlag==="-b"||createFlag==="-c")&&trackFlag==="--track"&&isSafeGitRefToken(localBranch)&&isSafeGitRefToken(upstream)&&upstream.includes("/")}if(tokens.length===3&&tokens[0]==="branch"){let upstream=tokens[1].match(/^--set-upstream-to=(.+)$/)?.[1];return Boolean(upstream&&isSafeGitRefToken(upstream)&&upstream.includes("/")&&isSafeGitRefToken(tokens[2]))}return!1}function isAllowedReadOnlyGitBranchListing(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length===0||tokens[0].toLowerCase()!=="branch")return!1;let listingSelectorInEffect=!1;for(let index=1;index<tokens.length;index+=1){let token=tokens[index];if(/^(?:--list|--contains|--merged|--no-merged|--points-at)$/i.test(token)){listingSelectorInEffect=!0;continue}if(/^(?:-a|--all|-r|--remotes|-v|-vv|--verbose|--show-current|--color|--no-color|--column|--no-column|-i|--ignore-case)$/i.test(token)||/^--(?:sort|format|color)=/i.test(token))continue;if(token.startsWith("-"))return!1;if(!listingSelectorInEffect)return!1}return!0}function isAllowedReadOnlyGitStashListing(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length<2||tokens[0].toLowerCase()!=="stash")return!1;if(tokens[1].toLowerCase()!=="list")return!1;for(let index=2;index<tokens.length;index+=1){let token=tokens[index];if(/^(?:-v|--oneline|--patch|-p|--stat|--color|--no-color)$/i.test(token))continue;if(/^--(?:format|pretty)=/i.test(token))continue;return!1}return!0}function isAllowedReadOnlyGitWorktreeListing(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length<2||tokens[0].toLowerCase()!=="worktree")return!1;if(tokens[1].toLowerCase()!=="list")return!1;for(let index=2;index<tokens.length;index+=1){let token=tokens[index];if(/^(?:-v|--verbose|--porcelain|-z)$/i.test(token))continue;return!1}return!0}function isSafeGitRefToken(value){return/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(value)&&!value.includes("..")&&!value.includes("//")&&!value.includes("@{")&&!value.endsWith("/")&&!value.endsWith(".")&&!value.endsWith(".lock")}function isAllowedPrFeedbackGhIntake(command){if(/^gh\s+pr\s+checkout(?:\s|$)/i.test(command))return isAllowedSafeGhPrCheckout(command);if(/^gh\s+--version$/i.test(command)||/^gh\s+pr\s+(?:view|diff|checks|status|list)(?:\s|$)/i.test(command)||/^gh\s+run\s+(?:view|list|watch)(?:\s|$)/i.test(command)||/^gh\s+issue\s+(?:view|list)(?:\s|$)/i.test(command)||/^gh\s+search\s+(?:code|commits|issues|prs|repos)(?:\s|$)/i.test(command)||/^gh\s+auth\s+status(?:\s|$)/i.test(command))return!0;if(!/^gh\s+api(?:\s|$)/i.test(command))return!1;if(/\bmutation\b/i.test(command))return!1;let method=command.match(/\s(?:--method(?:\s+|=)|-X(?:\s+|=)?)([A-Z]+)/i)?.[1];if(method&&method.toUpperCase()!=="GET")return!1;if(/\s(?:--input|--raw-field)(?:\s|=)/i.test(command)||/\s-F(?:\s|=|\S)/.test(command))return!1;return!/\s(?:--field|-f)(?:\s|=)(?!query=)/i.test(command)}function isAllowedSafeGhPrCheckout(command){if(/\s--(?:force|recurse-submodules)(?:\s|=|$)/i.test(command))return!1;let tokens=command.trim().split(/\s+/);if(tokens.length<4||tokens[0]!=="gh"||tokens[1]!=="pr"||tokens[2]!=="checkout")return!1;let target=tokens[3];if(!/^\d+$/.test(target)&&!/^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/\d+$/.test(target))return!1;for(let index=4;index<tokens.length;index+=1){let token=tokens[index],repoEquals=token.match(/^--repo=(.+)$/)?.[1];if(repoEquals){if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repoEquals))return!1;continue}let branchEquals=token.match(/^--branch=(.+)$/)?.[1];if(branchEquals){if(!isSafeGitRefToken(branchEquals))return!1;continue}if(token==="--repo"||token==="-R"){let repo=tokens[++index];if(!repo||!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo))return!1;continue}if(token==="--branch"||token==="-b"){let branch=tokens[++index];if(!branch||!isSafeGitRefToken(branch))return!1;continue}return!1}return!0}function normalizePrHeadSha(prHeadSha){let normalized=prHeadSha.trim();if(!normalized)throw Error("BLOCKED: PR workflow requires a non-empty pr_head_sha");return normalized}async function currentPrFeedbackRevisionDigest(directory,state){if(!state.prHeadSha)throw Error("BLOCKED: PR_FEEDBACK revision binding requires pr_head_sha");let digest2=await resolvePrWorkflowRevisionDigestForGate(directory,state.prHeadSha);if(!digest2)throw Error("BLOCKED: PR_FEEDBACK could not compute a bounded current-revision digest");return digest2}async function resolvePrWorkflowRevisionDigestForGate(directory,baseHeadSha){if(_test_exports.resolvePrWorkflowRevisionDigest!==resolvePrWorkflowRevisionDigest)return _test_exports.resolvePrWorkflowRevisionDigest(directory,baseHeadSha);return resolvePrWorkflowRevisionDigestAsync(directory,baseHeadSha)}function normalizeBatchId(batchId){let normalized=batchId.trim();if(!normalized)throw Error("BLOCKED: PR workflow requires a non-empty batch id");return normalized}function sameStringArray(left,right){return left.length===right.length&&left.every((value,index)=>value===right[index])}function assertExactStringSet(actual,expected,label){let actualSet=new Set(actual),expectedSet=new Set(expected),missing=[...expectedSet].filter((value)=>!actualSet.has(value)),extra=[...actualSet].filter((value)=>!expectedSet.has(value));if(actual.length!==actualSet.size||actualSet.size!==expectedSet.size||missing.length>0||extra.length>0)throw Error(`BLOCKED: ${label} must exactly cover the mechanically derived inventory; missing: ${missing.join(", ")||"(none)"}; extra: ${extra.join(", ")||"(none)"}`)}function derivePrReviewCandidateInventory(directory,state){let sources=[],baseDimensionSources=new Map,baseSourceCreditedDimensions=new Map,baseSourceFullOwnershipCount=new Map;for(let batch of[...state.prReviewBaseDispatches??[]].reverse()){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:base",batch.validatedAt);for(let lane of batch.lanes){let ownedDimensions=lane.ownedWorkflowLanes?.length?lane.ownedWorkflowLanes:[lane.workflowLane];if(!ownedDimensions.every((dimension)=>successful.has(dimension)))continue;let key=`${batch.batchId}\x00${lane.laneId}`;baseSourceFullOwnershipCount.set(key,ownedDimensions.length);for(let dimension of ownedDimensions)if(!baseDimensionSources.has(dimension)){baseDimensionSources.set(dimension,{batchId:batch.batchId,laneId:lane.laneId});let credited=baseSourceCreditedDimensions.get(key);if(credited)credited.push(dimension);else baseSourceCreditedDimensions.set(key,[dimension])}}}let seenBaseSourceKeys=new Set;for(let{batchId,laneId}of baseDimensionSources.values()){let key=`${batchId}\x00${laneId}`;if(seenBaseSourceKeys.has(key))continue;seenBaseSourceKeys.add(key);let credited=baseSourceCreditedDimensions.get(key),fullOwnershipCount=baseSourceFullOwnershipCount.get(key)??0;sources.push({batchId,laneId,mode:"swarm-pr-review:base",creditedLanes:credited&&credited.length<fullOwnershipCount?credited:void 0})}let selectedCouncilLanes=new Set;for(let batch of[...state.prReviewValidationBatches??[]].reverse()){if(batch.phase!=="council")continue;let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:council",batch.validatedAt);for(let lane of batch.lanes)if(successful.has(lane.workflowLane)&&!selectedCouncilLanes.has(lane.workflowLane))sources.push({batchId:batch.batchId,laneId:lane.laneId,mode:"swarm-pr-review:council"}),selectedCouncilLanes.add(lane.workflowLane)}if(state.prReviewTriggerEvalPath){let triggerPath=validateSwarmPath(directory,state.prReviewTriggerEvalPath),triggerArtifact;try{triggerArtifact=JSON.parse(readFileSync6(triggerPath,"utf-8"))}catch{throw Error("BLOCKED: PR_REVIEW trigger evaluation artifact is missing or invalid")}let receipt;try{receipt=parsePrReviewTriggerReceipt(triggerArtifact)}catch(error49){throw Error(`BLOCKED: PR_REVIEW trigger evaluation is invalid: ${error49 instanceof Error?error49.message:String(error49)}`)}for(let row of receipt.matchedRows)sources.push({batchId:row.source_batch_id,laneId:row.source_lane_id,mode:"swarm-pr-review:micro",workflowLane:row.trigger_id})}let candidateIds=[],extractedLaneKeys=new Set;for(let source of sources){let resolvedArtifact=!1;for(let record2 of findByBatchId(directory,source.batchId,{parentSessionId:state.sessionID})){if(record2.laneId!==source.laneId||record2.mode!==source.mode||record2.status!=="completed"||record2.workspace?.prHeadSha!==state.prHeadSha||record2.workspace?.gitHead!==state.prHeadSha||record2.result?.outputDegraded===!0||record2.result?.transcriptIncomplete===!0||record2.result?.truncated===!0)continue;let ref=record2.result?.outputRef?.trim(),artifact=ref?readLaneOutput(directory,ref)?.artifact:void 0,recordOwnedLanes=record2.ownedWorkflowLanes?.length?record2.ownedWorkflowLanes:record2.workflowLane?[record2.workflowLane]:void 0;if(!artifact||!workflowArtifactHasContractMarker(directory,state,record2,source.mode,record2.workflowLane??source.workflowLane??source.laneId,void 0,void 0,recordOwnedLanes))continue;if(source.workflowLane&&(!recordOwnedLanes?.includes(source.workflowLane)||!prReviewDiscoveryArtifactCoversLane(artifact.text,source.workflowLane,recordOwnedLanes)))continue;resolvedArtifact=!0;let laneKey=`${source.batchId}\x00${source.laneId}`;if(!extractedLaneKeys.has(laneKey))extractedLaneKeys.add(laneKey),candidateIds.push(...extractCandidateIds(artifact.text,source.mode==="swarm-pr-review:micro"?"micro_lane":"base_explorer",source.creditedLanes))}if(source.mode==="swarm-pr-review:micro"&&!resolvedArtifact)throw Error(`BLOCKED: PR_REVIEW mandatory micro-lane provenance is missing or invalid for ${source.workflowLane??source.laneId}`)}return assertNoDuplicates(candidateIds,"PR_REVIEW discovery candidate ids"),candidateIds.length>0?candidateIds.sort():["CLEAN-REVIEW"]}function appendBoundedCandidateIssue(issues,message){if(issues.length<MAX_CANDIDATE_ISSUES_PER_ARTIFACT-1){issues.push(message.slice(0,MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS));return}if(issues.length===MAX_CANDIDATE_ISSUES_PER_ARTIFACT-1)issues.push("additional malformed candidate diagnostics omitted")}function parseCanonicalCandidateRows(text,fallbackFamily){let rows=[],issues=[],headerFamily=null;for(let[index,line]of removeCandidateCodeFences(text).split(/\r?\n/).entries()){let fields=splitPipeFields(line).map((field)=>field.trim()),detectedHeaderFamily=candidateHeaderFamily(fields);if(detectedHeaderFamily){headerFamily=detectedHeaderFamily;continue}let explicitMarker=fields[0]==="[CANDIDATE]",markerlessRow=headerFamily!==null&&Boolean(fields[0])&&!fields[0].startsWith("[");if(!explicitMarker&&!markerlessRow)continue;if(explicitMarker&&headerFamily===null){appendBoundedCandidateIssue(issues,`row ${index+1} field header: candidate output must begin with one exact canonical base or micro [CANDIDATE] header`);continue}let family=headerFamily??fallbackFamily,candidateFields=explicitMarker?fields.slice(1):fields,analysis=analyzeCandidateFields(candidateFields,family);if(!analysis.valid){for(let issue2 of analysis.issues)appendBoundedCandidateIssue(issues,`row ${index+1} field ${issue2.field}: ${issue2.message}`);continue}if(!analysis.candidateId||!analysis.workflowLane)continue;rows.push({candidateId:analysis.candidateId,workflowLane:analysis.workflowLane,evidence:candidateFields.slice(2).join("\x00"),lineNumber:index+1})}return{rows,issues}}function extractCandidateIds(text,fallbackFamily,scopeToLanes){let inScope=(lane)=>!scopeToLanes||lane!==void 0&&scopeToLanes.includes(lane);return parseCanonicalCandidateRows(text,fallbackFamily).rows.filter((row)=>inScope(row.workflowLane)).map((row)=>row.candidateId)}function derivePrReviewCriticInventory(directory,state){return[...deriveLatestPrReviewReviewerVerdicts(directory,state).entries()].filter(([,verdict])=>verdict.classification==="CONFIRMED"&&["CRITICAL","HIGH","MEDIUM"].includes(verdict.severity)).map(([itemId])=>itemId).sort()}function deriveLatestPrReviewCriticVerdicts(directory,state){let reviewerVerdicts=deriveLatestPrReviewReviewerVerdicts(directory,state),criticBatches=(state.prReviewValidationBatches??[]).filter((batch)=>batch.phase==="critic");for(let batch of[...criticBatches].reverse()){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:critic",batch.validatedAt);if(batch.lanes.some((lane)=>!successful.has(lane.workflowLane))||successful.size!==batch.lanes.length)continue;let required2=batch.lanes.flatMap((lane)=>lane.reviewItemIds??[]),verdicts=new Map;for(let lane of batch.lanes){let ref=findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===lane.laneId)?.result?.outputRef?.trim(),artifact=ref?readLaneOutput(directory,ref)?.artifact:void 0;if(!artifact)continue;for(let itemId of lane.reviewItemIds??[]){let verdict=parseCriticVerdict(artifact.text,itemId,reviewerVerdicts.get(itemId)?.severity);if(verdict)verdicts.set(itemId,verdict)}}if(required2.every((itemId)=>verdicts.has(itemId)))return verdicts}return new Map}function deriveLatestPrReviewReviewerVerdicts(directory,state){let reviewerBatches=(state.prReviewValidationBatches??[]).filter((batch)=>batch.phase==="reviewer");for(let batch of[...reviewerBatches].reverse()){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:reviewer",batch.validatedAt);if(batch.lanes.some((lane)=>!successful.has(lane.workflowLane))||successful.size!==batch.lanes.length)continue;let required2=batch.lanes.flatMap((lane)=>lane.reviewItemIds??[]),verdicts=new Map;for(let lane of batch.lanes){let ref=findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===lane.laneId)?.result?.outputRef?.trim(),artifact=ref?readLaneOutput(directory,ref)?.artifact:void 0;if(!artifact)continue;for(let itemId of lane.reviewItemIds??[]){let verdict=parseReviewerVerdict(artifact.text,itemId);if(verdict)verdicts.set(itemId,verdict)}}if(required2.every((itemId)=>verdicts.has(itemId)))return verdicts}return new Map}function successfulObligationsFromExactBatch(directory,state,batchId,expectedLanes,expectedMode,validatedAt,checkWorkflowLane=!0,forbiddenSubagentSessionIds=new Set,expectedRevisionDigest,diagnostics){let records=findByBatchId(directory,batchId,{parentSessionId:state.sessionID}),successful=new Set,validatedAtMs=Date.parse(validatedAt);if(!Number.isFinite(validatedAtMs))return successful;let expectedByLaneId=new Map(expectedLanes.map((lane)=>[lane.laneId,lane]));if(expectedByLaneId.size!==expectedLanes.length)return successful;let recordCountByLaneId=new Map,recordCountBySubagentSessionId=new Map;for(let record2 of records){if(!record2.laneId||!expectedByLaneId.has(record2.laneId))continue;recordCountByLaneId.set(record2.laneId,(recordCountByLaneId.get(record2.laneId)??0)+1);let subagentSessionId=record2.subagentSessionId?.trim();if(subagentSessionId)recordCountBySubagentSessionId.set(subagentSessionId,(recordCountBySubagentSessionId.get(subagentSessionId)??0)+1)}for(let record2 of records){let expectedLane=record2.laneId?expectedByLaneId.get(record2.laneId):void 0,expectedWorkflowLane=expectedLane?.workflowLane,expectedOwnedLanes=expectedLane?.ownedWorkflowLanes?.length?expectedLane.ownedWorkflowLanes:expectedWorkflowLane!==void 0?[expectedWorkflowLane]:void 0,subagentSessionId=record2.subagentSessionId?.trim();if(expectedWorkflowLane!==void 0&&expectedOwnedLanes!==void 0&&record2.laneId!==void 0&&recordCountByLaneId.get(record2.laneId)===1&&Boolean(subagentSessionId)&&recordCountBySubagentSessionId.get(subagentSessionId)===1&&!forbiddenSubagentSessionIds.has(subagentSessionId)&&record2.createdAt>=validatedAtMs&&(!checkWorkflowLane||record2.workflowLane===expectedWorkflowLane)&&(!checkWorkflowLane||ownedLaneSetsEqual(record2.ownedWorkflowLanes,expectedOwnedLanes))&&record2.mode===expectedMode&&record2.workspace?.prHeadSha===state.prHeadSha&&record2.workspace?.gitHead===state.prHeadSha&&record2.status==="completed"&&record2.result?.outputDegraded!==!0&&record2.result?.transcriptIncomplete!==!0&&record2.result?.truncated!==!0&&(record2.result?.chars??0)>0&&Boolean(record2.result?.digest?.trim())&&Boolean(record2.result?.outputRef?.trim())&&workflowArtifactHasContractMarker(directory,state,record2,expectedMode,expectedWorkflowLane,expectedLane?.reviewItemIds,expectedRevisionDigest,expectedOwnedLanes,diagnostics))for(let obligation of expectedOwnedLanes)successful.add(obligation)}return successful}function ownedLaneSetsEqual(recordOwned,expectedOwned){if(!recordOwned||recordOwned.length===0)return expectedOwned.length===1;let recordSet=new Set(recordOwned),expectedSet=new Set(expectedOwned);if(recordSet.size!==recordOwned.length||recordSet.size!==expectedSet.size)return!1;return recordOwned.every((owned)=>expectedSet.has(owned))}function workflowArtifactHasContractMarker(directory,state,record2,expectedMode,expectedWorkflowLane,reviewItemIds,expectedRevisionDigest,ownedWorkflowLanes,diagnostics){let ref=record2.result?.outputRef?.trim();if(!ref)return!1;let loaded=readLaneOutput(directory,ref);if(!loaded)return!1;let artifact=loaded.artifact,recordPrHeadSha=record2.workspace?.prHeadSha,recordGitHead=record2.workspace?.gitHead,resolvedRevisionDigest=expectedRevisionDigest??(recordPrHeadSha?_test_exports.resolvePrWorkflowRevisionDigest(directory,recordPrHeadSha):null),expectedReviewScope=state.mode==="PR_REVIEW"&&state.prReviewBaseSha&&state.prHeadSha?`complete PR diff ${state.prReviewBaseSha}...${state.prHeadSha}`:void 0;if(artifact.batchId!==record2.batchId||artifact.laneId!==record2.laneId||artifact.mode!==expectedMode||artifact.sessionId!==record2.subagentSessionId||artifact.parentSessionId!==record2.parentSessionId||artifact.agent!==record2.swarmPrefixedAgent||artifact.role!==record2.normalizedAgent||artifact.source!=="collect_lane_results"||artifact.workflowLane!==record2.workflowLane||artifact.workflowLane!==expectedWorkflowLane||!recordPrHeadSha||artifact.prHeadSha!==recordPrHeadSha||!recordGitHead||artifact.gitHead!==recordGitHead||!resolvedRevisionDigest||artifact.revisionDigest!==resolvedRevisionDigest||expectedReviewScope!==void 0&&(record2.workspace?.scope!==expectedReviewScope||artifact.scope!==expectedReviewScope)||artifact.digest!==record2.result?.digest||artifact.chars!==record2.result?.chars)return!1;if(expectedMode==="swarm-pr-review:reviewer")return Boolean(reviewItemIds?.length&&reviewItemIds.every((itemId)=>Boolean(parseReviewerVerdict(artifact.text,itemId))));if(expectedMode==="swarm-pr-review:critic"){let reviewerVerdicts=deriveLatestPrReviewReviewerVerdicts(directory,state);return Boolean(reviewItemIds?.length&&reviewItemIds.every((itemId)=>Boolean(parseCriticVerdict(artifact.text,itemId,reviewerVerdicts.get(itemId)?.severity))))}if(expectedMode==="swarm-pr-feedback:verification")return/^\[FEEDBACK-VERIFIED\]\s*\|/m.test(artifact.text);let feedbackVerdict={"swarm-pr-feedback:stage-b-reviewer":["[STAGE-B-REVIEW]","APPROVE"],"swarm-pr-feedback:stage-b-test":["[STAGE-B-TEST]","PASS"],"swarm-pr-feedback:closeout-reviewer":["[CLOSEOUT-REVIEW]","APPROVE"],"swarm-pr-feedback:closeout-critic":["[CLOSEOUT-CRITIC]","APPROVE"]}[expectedMode];if(feedbackVerdict)return Boolean(reviewItemIds?.length&&reviewItemIds.every((itemId)=>artifactHasExactPositiveVerdictRow(artifact.text,feedbackVerdict[0],itemId,feedbackVerdict[1])));let coveredLanes=ownedWorkflowLanes?.length?ownedWorkflowLanes:[expectedWorkflowLane],coverageAnalyses=coveredLanes.map((coveredLane)=>({coveredLane,analysis:analyzePrReviewDiscoveryArtifact(artifact.text,coveredLane,coveredLanes)}));if(coverageAnalyses.some(({analysis})=>!analysis.covered)){for(let{coveredLane,analysis}of coverageAnalyses){if(analysis.covered||analysis.issues.length===0)continue;if(diagnostics&&diagnostics.length<MAX_BASE_COVERAGE_DIAGNOSTICS){let diagnostic=`batch=${record2.batchId??"(missing)"} lane=${record2.laneId??"(missing)"} workflow_lane=${coveredLane} output_ref=${ref} digest=${record2.result?.digest??"(missing)"}: ${analysis.issues.join("; ")}`;diagnostics.push(diagnostic.slice(0,MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS))}}return!1}if(coveredLanes.length>1){let seenEvidence=new Map;for(let coveredLane of coveredLanes){let evidence2=extractLaneCoverageEvidenceText(artifact.text,coveredLane,coveredLanes);if(evidence2===null)continue;if(seenEvidence.get(evidence2))return!1;seenEvidence.set(evidence2,coveredLane)}}return!0}function analyzePrReviewDiscoveryArtifact(text,expectedWorkflowLane,ownedWorkflowLanes=[expectedWorkflowLane]){let fallbackFamily=PR_REVIEW_BASE_DIMENSION_IDS.includes(expectedWorkflowLane)?"base_explorer":"micro_lane",issues=[],canonicalText=removeCandidateCodeFences(text),firstTabularFields=canonicalText.split(/\r?\n/).map((line)=>splitPipeFields(line).map((field)=>field.trim())).find((fields)=>fields.length>=2&&fields.some((field)=>field.length>0));if((firstTabularFields?candidateHeaderFamily(firstTabularFields):null)!==fallbackFamily)return appendBoundedCandidateIssue(issues,`field header: expected one exact canonical ${fallbackFamily} [CANDIDATE] header before discovery rows`),{covered:!1,evidence:null,issues};let parsed=parseCandidates({output_ref:"pr-workflow:discovery-artifact",batchId:"pr-workflow",laneId:expectedWorkflowLane,agent:"explorer",role:"explorer",digest:"0".repeat(64),text:canonicalText,artifact_status:"ok",source:"collect_lane_results",produced_at:"1970-01-01T00:00:00.000Z"},{accept_partial:!1,accept_degraded:!1,degraded:!1,row_format_version:1,producer:"swarm-pr-review",expected_family:fallbackFamily,...fallbackFamily==="base_explorer"?{expected_lane:expectedWorkflowLane,expected_lanes:[...ownedWorkflowLanes]}:{expected_micro_lane:expectedWorkflowLane,expected_micro_lanes:[...ownedWorkflowLanes]}});if(parsed.error)appendBoundedCandidateIssue(issues,parsed.error);for(let detail of parsed.diagnostics.parse_error_details)appendBoundedCandidateIssue(issues,`row ${detail.row_index+1} field ${detail.field}: ${detail.message}`);if(parsed.error||parsed.diagnostics.parse_error_details.length>0)return{covered:!1,evidence:null,issues};let matchingCandidate=parsed.candidates.find((candidate)=>(candidate.lane??candidate.micro_lane)===expectedWorkflowLane);if(matchingCandidate)return{covered:!0,evidence:[matchingCandidate.severity,matchingCandidate.category,matchingCandidate.file_line,matchingCandidate.claim,matchingCandidate.evidence_summary,matchingCandidate.impact_context??matchingCandidate.invariant_violated,matchingCandidate.confidence].join("\x00"),issues};let clean=parsed.clean_attestation;if(clean&&(clean.row_format_family==="base_explorer"?clean.lane:clean.micro_lane)===expectedWorkflowLane)return{covered:!0,evidence:`${clean.coverage_scope}\x00${clean.evidence}`,issues};return{covered:!1,evidence:null,issues}}function prReviewDiscoveryArtifactCoversLane(text,expectedWorkflowLane,ownedWorkflowLanes=[expectedWorkflowLane]){return analyzePrReviewDiscoveryArtifact(text,expectedWorkflowLane,ownedWorkflowLanes).covered}function extractLaneCoverageEvidenceText(text,expectedWorkflowLane,ownedWorkflowLanes=[expectedWorkflowLane]){return analyzePrReviewDiscoveryArtifact(text,expectedWorkflowLane,ownedWorkflowLanes).evidence}function parseReviewerVerdict(text,itemId){let rows=text.split(/\r?\n/).map(pipeFields).filter((fields2)=>fields2[0]==="[REVIEWED]"&&fields2[1]===itemId);if(rows.length!==1)return null;let fields=rows[0];if(fields.length!==10||!fields.slice(1).every(Boolean))return null;let introduced=fields[5].replace(/^introduced_by_pr\s*:\s*/i,"").toUpperCase();if(!REVIEWER_CLASSIFICATIONS.has(fields[2])||!REVIEWER_EVIDENCE_TYPES.has(fields[3])||!REVIEW_SEVERITIES.has(fields[4])||!["YES","NO","UNKNOWN"].includes(introduced))return null;if(fields[7].length<8||fields[8].length<5||fields[9].length<3)return null;return{classification:fields[2],severity:fields[4]}}function parseCriticVerdict(text,itemId,reviewerSeverity){let rows=text.split(/\r?\n/).map(pipeFields).filter((fields2)=>fields2[0]==="[CRITIC]"&&fields2[1]===itemId);if(rows.length!==1)return null;let fields=rows[0];if(fields.length!==6||!fields.slice(1).every(Boolean)||!CRITIC_STATUSES.has(fields[2])||!REVIEW_SEVERITIES.has(fields[3]))return null;if(fields[2]==="NEEDS_MORE_EVIDENCE")return null;if(fields[2]==="DISPROVED"&&fields[3]!=="NONE")return null;if(fields[2]==="UPHELD"&&!["CRITICAL","HIGH","MEDIUM"].includes(fields[3]))return null;if(fields[2]==="DOWNGRADED"&&fields[3]==="CRITICAL")return null;if(reviewerSeverity){let severityRank=new Map([["NONE",0],["INFO",1],["LOW",2],["MEDIUM",3],["HIGH",4],["CRITICAL",5]]),reviewerRank=severityRank.get(reviewerSeverity),criticRank=severityRank.get(fields[3]);if(reviewerRank===void 0||criticRank===void 0)return null;if(fields[2]==="UPHELD"&&criticRank!==reviewerRank)return null;if(fields[2]==="DOWNGRADED"&&criticRank>=reviewerRank)return null}if(fields[4].length<6||fields[5].length<6)return null;return{status:fields[2],severity:fields[3]}}function artifactHasExactPositiveVerdictRow(text,marker,itemId,positiveVerdict){let rows=text.split(/\r?\n/).map(pipeFields).filter((fields)=>fields[0]===marker&&fields[1]===itemId);return rows.length===1&&rows[0].length>=4&&rows[0][2]===positiveVerdict&&rows[0].slice(1,4).every(Boolean)}function pipeFields(line){if(!line.includes("|"))return[];return line.split("|").map((field)=>field.trim())}function feedbackArtifactCoversItems(directory,state,batchId,laneId,itemIds){let ref=findByBatchId(directory,batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===laneId)?.result?.outputRef?.trim(),loaded=ref?readLaneOutput(directory,ref):null;if(!loaded)return!1;let rows=loaded.artifact.text.split(/\r?\n/).map(pipeFields).filter((fields)=>fields[0]==="[FEEDBACK-VERIFIED]");if(rows.length!==itemIds.length)return!1;return itemIds.every((itemId)=>{let matches=rows.filter((fields)=>fields[1]===itemId);return matches.length===1&&matches[0].length===4&&matches[0].slice(1,4).every(Boolean)&&FEEDBACK_CLASSIFICATIONS.has(matches[0][2])})}async function persistState(directory,state){let validated=PrWorkflowGateStateSchema.parse(state);await withSessionStateMutation(directory,validated.sessionID,async()=>{let nextState=await writeStateWhileLocked(directory,validated);Object.assign(state,nextState)})}async function writeStateWhileLocked(directory,state,options={}){let validated=PrWorkflowGateStateSchema.parse(state),current=await readPrWorkflowGateStateFromDisk(directory,validated.sessionID);if(current?current.revision!==validated.revision:validated.revision!==0)throw Error("BLOCKED: PR workflow gate state changed concurrently; reload the active session state before retrying");if(current?.workflowInstanceId&&validated.workflowInstanceId!==current.workflowInstanceId&&options.replaceWorkflowInstanceId!==current.workflowInstanceId)throw Error("BLOCKED: PR workflow gate state changed concurrently; reload the active session state before retrying");let nextState=PrWorkflowGateStateSchema.parse({...validated,revision:validated.revision+1}),filePath=workflowGateStatePath(directory,validated.sessionID);return await writeAtomicJson2(directory,filePath,nextState),rememberState(directory,nextState),nextState}function workflowCheckoutMutationLockRelativePath(){return path14.join(WORKFLOW_GATE_DIR,"checkout.lock")}function workflowCheckoutMutationLockPath(directory){return validateSwarmPath(directory,workflowCheckoutMutationLockRelativePath())}function openCheckoutLockFile(lockPath){return fsp3.open(lockPath,"wx")}function removeCheckoutLockFile(lockPath){return fsp3.rm(lockPath)}function checkoutMutationProjectKey(directory){return normalizeComparableFsPath(directory)}async function withCheckoutMutationDeadline(promise2,phase){let timeout;try{return await Promise.race([promise2,new Promise((resolve9)=>{timeout=setTimeout(()=>{resolve9({status:"timeout",error:new PrWorkflowCheckoutMutationTimeoutError(phase)})},_test_exports.checkoutMutationActionTimeoutMs)})])}finally{if(timeout)clearTimeout(timeout)}}async function withPrWorkflowCheckoutMutationLock(directory,action){let key=checkoutMutationProjectKey(directory),previous=pendingCheckoutMutationsByProject.get(key)??Promise.resolve(),release,current=new Promise((resolve9)=>{release=resolve9}),queued=previous.then(()=>current);pendingCheckoutMutationsByProject.set(key,queued);let previousResult=await withCheckoutMutationDeadline(previous.then(()=>({status:"ready"})),"queue");if(previousResult.status==="timeout")throw release(),queued.then(()=>{if(pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key)}),previousResult.error;let lock;try{lock=await acquireCheckoutMutationLock(directory)}catch(error49){if(release(),pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key);throw error49}let actionOutcome=Promise.resolve().then(action).then((value)=>({status:"fulfilled",value}),(error49)=>({status:"rejected",error:error49})),outcome=await withCheckoutMutationDeadline(actionOutcome,"action");if(outcome.status==="timeout")throw actionOutcome.then(async()=>{try{await releaseCheckoutMutationLock(lock)}catch{}finally{if(release(),pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key)}}),outcome.error;try{if(outcome.status==="rejected")throw outcome.error;return outcome.value}finally{try{await releaseCheckoutMutationLock(lock)}finally{if(release(),pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key)}}}async function acquireCheckoutMutationLock(directory){let lockPath=workflowCheckoutMutationLockPath(directory),verifiedParent=await ensurePrWorkflowSafeParentDirectory(directory,lockPath);for(let attempt=0;attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS;attempt++)try{let handle=await _test_exports.openCheckoutLock(lockPath),lock={ownerToken:randomUUID2(),pid:process.pid,createdAtMs:_test_exports.nowMs()},lockIdentity,writeError;try{let openedStat=await handle.stat({bigint:!0});lockIdentity={dev:openedStat.dev,ino:openedStat.ino},lockIdentity=await assertOpenedSwarmFileIdentity(directory,lockPath,handle,verifiedParent,"PR workflow checkout mutation lock"),await _test_exports.beforeCheckoutLockWrite?.(),await handle.writeFile(JSON.stringify(lock),"utf-8")}catch(error49){writeError=error49}finally{await handle.close().catch(()=>{return})}if(writeError){if(lockIdentity)await removeCheckoutMutationLockByIdentity(directory,lockPath,lockIdentity,verifiedParent);throw writeError}return{path:lockPath,ownerToken:lock.ownerToken}}catch(error49){if(error49.code!=="EEXIST")throw error49;if(await reclaimAbandonedCheckoutMutationLock(lockPath))continue;if(attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS-1)await delay(STATE_MUTATION_LOCK_RETRY_DELAY_MS)}throw Error("BLOCKED: PR workflow checkout mutation is being handled by another process; retry after that checkout settles")}async function releaseCheckoutMutationLock(lock){let lastError;for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES3;attempt++){try{if(await removeCheckoutMutationLockIfOwned(lock.path,lock.ownerToken)){completedCheckoutLockOwners.delete(lock.path);return}lastError=Error("PR workflow checkout mutation lock ownership changed before release")}catch(error49){lastError=error49}if(attempt<WINDOWS_RENAME_MAX_RETRIES3-1)await delay(RENAME_RETRY_DELAY_MS)}throw rememberCompletedCheckoutLockOwner(lock.path,lock.ownerToken),lastError instanceof Error?lastError:Error("PR workflow checkout mutation lock release failed")}async function reclaimAbandonedCheckoutMutationLock(lockPath){let lock=await readCheckoutMutationLock(lockPath);if(lock){if(lock.pid===process.pid&&completedCheckoutLockOwners.get(lockPath)===lock.ownerToken){let removed=await removeCheckoutMutationLockIfOwned(lockPath,lock.ownerToken);if(removed)completedCheckoutLockOwners.delete(lockPath);return removed}if(_test_exports.isProcessAlive(lock.pid))return!1;return removeCheckoutMutationLockIfOwned(lockPath,lock.ownerToken)}try{let stat6=await fsp3.stat(lockPath);if(_test_exports.nowMs()-stat6.mtimeMs<STATE_MUTATION_LOCK_UNINITIALIZED_STALE_MS)return!1;return await fsp3.rm(lockPath,{force:!0}),!0}catch(error49){if(error49.code==="ENOENT")return!0;throw error49}}async function readCheckoutMutationLock(lockPath){let raw;try{raw=await fsp3.readFile(lockPath,"utf-8")}catch(error49){if(error49.code==="ENOENT")return null;throw error49}try{let parsed=JSON.parse(raw);if(typeof parsed==="object"&&parsed!==null&&typeof parsed.ownerToken==="string"&&parsed.ownerToken.length>0&&typeof parsed.pid==="number"&&Number.isInteger(parsed.pid)&&parsed.pid>0&&typeof parsed.createdAtMs==="number"&&Number.isFinite(parsed.createdAtMs))return parsed}catch{}return null}async function removeCheckoutMutationLockIfOwned(lockPath,ownerToken){let lock=await readCheckoutMutationLock(lockPath);if(!lock||lock.ownerToken!==ownerToken)return!1;try{return await _test_exports.removeCheckoutLock(lockPath),!0}catch(error49){if(error49.code==="ENOENT")return!1;throw error49}}async function removeCheckoutMutationLockByIdentity(directory,lockPath,identity,verifiedParent){let lastError;for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES3;attempt++)try{await assertClosedSwarmFileIdentity(directory,lockPath,identity,verifiedParent,"PR workflow checkout mutation lock"),await _test_exports.removeCheckoutLock(lockPath);return}catch(error49){if(error49.code==="ENOENT")return;if(lastError=error49,attempt<WINDOWS_RENAME_MAX_RETRIES3-1)await delay(RENAME_RETRY_DELAY_MS)}throw lastError instanceof Error?lastError:Error("PR workflow checkout mutation lock cleanup failed")}function rememberCompletedCheckoutLockOwner(lockPath,ownerToken){completedCheckoutLockOwners.delete(lockPath),completedCheckoutLockOwners.set(lockPath,ownerToken);while(completedCheckoutLockOwners.size>MAX_COMPLETED_CHECKOUT_LOCK_OWNERS){let oldest=completedCheckoutLockOwners.keys().next().value;if(oldest===void 0)break;completedCheckoutLockOwners.delete(oldest)}}async function withSessionStateMutation(directory,sessionID,action){let key=stateCacheKey(directory,sessionID),previous=pendingStateMutationsByProjectSession.get(key)??Promise.resolve(),release,current=new Promise((resolve9)=>{release=resolve9}),queued=previous.then(()=>current);pendingStateMutationsByProjectSession.set(key,queued),await previous;try{let lock=await acquireSessionStateMutationLock(directory,sessionID);try{return await action()}finally{await releaseSessionStateMutationLock(lock)}}finally{if(release(),pendingStateMutationsByProjectSession.get(key)===queued)pendingStateMutationsByProjectSession.delete(key)}}async function acquireSessionStateMutationLock(directory,sessionID){let lockPath=workflowGateStateLockPath(directory,sessionID),verifiedParent=await ensurePrWorkflowSafeParentDirectory(directory,lockPath);for(let attempt=0;attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS;attempt++)try{let handle=await fsp3.open(lockPath,"wx"),lock={ownerToken:randomUUID2(),pid:process.pid,createdAtMs:_test_exports.nowMs()},writeError;try{await _test_exports.beforeSessionStateLockWrite?.(),await assertOpenedSwarmFileIdentity(directory,lockPath,handle,verifiedParent,"PR workflow state mutation lock"),await handle.writeFile(JSON.stringify(lock),"utf-8")}catch(error49){writeError=error49}finally{await handle.close().catch(()=>{return})}if(writeError)throw await removeSessionStateMutationLockIfOwned(lockPath,lock.ownerToken),writeError;return{path:lockPath,ownerToken:lock.ownerToken}}catch(error49){if(error49.code!=="EEXIST")throw error49;if(await reclaimAbandonedSessionStateMutationLock(lockPath))continue;if(attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS-1)await delay(STATE_MUTATION_LOCK_RETRY_DELAY_MS)}throw Error("BLOCKED: PR workflow gate state is being mutated by another process; retry after that session transition finishes")}async function releaseSessionStateMutationLock(lock){try{await removeSessionStateMutationLockIfOwned(lock.path,lock.ownerToken)}catch{}}async function reclaimAbandonedSessionStateMutationLock(lockPath){let lock=await readSessionStateMutationLock(lockPath);if(lock){if(_test_exports.isProcessAlive(lock.pid))return!1;return removeSessionStateMutationLockIfOwned(lockPath,lock.ownerToken)}try{let stat6=await fsp3.stat(lockPath);if(_test_exports.nowMs()-stat6.mtimeMs<STATE_MUTATION_LOCK_UNINITIALIZED_STALE_MS)return!1;return await fsp3.rm(lockPath,{force:!0}),!0}catch(error49){if(error49.code==="ENOENT")return!0;throw error49}}async function readSessionStateMutationLock(lockPath){let raw;try{raw=await fsp3.readFile(lockPath,"utf-8")}catch(error49){if(error49.code==="ENOENT")return null;throw error49}try{let parsed=JSON.parse(raw);if(typeof parsed==="object"&&parsed!==null&&typeof parsed.ownerToken==="string"&&parsed.ownerToken.length>0&&typeof parsed.pid==="number"&&Number.isInteger(parsed.pid)&&parsed.pid>0&&typeof parsed.createdAtMs==="number"&&Number.isFinite(parsed.createdAtMs))return parsed}catch{}return null}async function removeSessionStateMutationLockIfOwned(lockPath,ownerToken){let lock=await readSessionStateMutationLock(lockPath);if(!lock||lock.ownerToken!==ownerToken)return!1;try{return await fsp3.rm(lockPath),!0}catch(error49){if(error49.code==="ENOENT")return!1;throw error49}}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(error49){return error49.code!=="ESRCH"}}async function readPrWorkflowGateStateFromDisk(directory,sessionID){let filePath=workflowGateStatePath(directory,sessionID),raw;try{raw=await fsp3.readFile(filePath,"utf-8")}catch(error49){if(error49.code==="ENOENT")return null;throw error49}let parsedJson;try{parsedJson=JSON.parse(raw)}catch{throw Error(`BLOCKED: PR workflow gate state for session "${sessionID}" is not valid JSON`)}let parsed=PrWorkflowGateStateSchema.safeParse(parsedJson);if(!parsed.success)throw Error(`BLOCKED: PR workflow gate state for session "${sessionID}" is invalid`);return parsed.data}function rememberState(directory,state){let cacheKey=stateCacheKey(directory,state.sessionID);trackedStatesByProjectSession.delete(cacheKey),trackedStatesByProjectSession.set(cacheKey,state);while(trackedStatesByProjectSession.size>MAX_TRACKED_SESSIONS){let oldestKey=trackedStatesByProjectSession.keys().next().value;if(!oldestKey)break;trackedStatesByProjectSession.delete(oldestKey)}}function stateCacheKey(directory,sessionID){let resolved=path14.normalize(path14.resolve(directory));return`${process.platform==="win32"?resolved.toLowerCase():resolved}\x00${normalizeSessionID(sessionID)}`}function workflowGateStatePath(directory,sessionID){return validateSwarmPath(directory,workflowGateStateRelativePath(sessionID))}function workflowGateStateLockPath(directory,sessionID){return validateSwarmPath(directory,workflowGateStateLockRelativePath(sessionID))}function workflowGateStateLockRelativePath(sessionID){return path14.join(WORKFLOW_GATE_DIR,`${prWorkflowSessionFileStem(sessionID)}.lock`)}function workflowGateStateRelativePath(sessionID){return path14.join(WORKFLOW_GATE_DIR,`${prWorkflowSessionFileStem(sessionID)}.json`)}function prWorkflowSessionFileStem(sessionID){let normalized=normalizeSessionID(sessionID),slug=normalized.replace(/[^A-Za-z0-9_.-]/g,"_").slice(0,80)||"session",digest2=createHash7("sha256").update(normalized).digest("hex").slice(0,12);return`${slug}-${digest2}`}function normalizeSessionID(sessionID){let normalized=sessionID.trim();if(!normalized)throw Error("BLOCKED: PR workflow gate requires a non-empty sessionID");return normalized}async function ensurePrWorkflowSafeParentDirectory(directory,filePath){let swarmRoot=path14.resolve(directory,".swarm"),parentPath=path14.dirname(path14.resolve(filePath)),relativeParent=path14.relative(swarmRoot,parentPath);if(relativeParent===".."||relativeParent.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeParent))throw Error("BLOCKED: PR workflow atomic destination escapes the project .swarm directory");await fsp3.mkdir(swarmRoot,{recursive:!0});let currentPath=swarmRoot,currentIdentity=await assertSafeDirectory(currentPath,void 0);for(let segment of relativeParent.split(path14.sep).filter(Boolean)){let nextPath=path14.join(currentPath,segment);await _test_exports.beforeSafeDirectoryCreate?.(currentPath,nextPath),await assertSafeDirectory(currentPath,currentIdentity);try{await fsp3.mkdir(nextPath)}catch(error49){if(error49.code!=="EEXIST")throw error49}await assertSafeDirectory(currentPath,currentIdentity);let nextIdentity=await assertSafeDirectory(nextPath,void 0),[realCurrent,realNext]=await Promise.all([fsp3.realpath(currentPath),fsp3.realpath(nextPath)]);if(normalizeComparableFsPath(path14.dirname(realNext))!==normalizeComparableFsPath(realCurrent))throw Error("BLOCKED: PR workflow directory creation escaped the project .swarm tree");currentPath=nextPath,currentIdentity=nextIdentity}let realRoot=await fsp3.realpath(swarmRoot),realParent=await fsp3.realpath(parentPath),relativeRealParent=path14.relative(realRoot,realParent);if(relativeRealParent===".."||relativeRealParent.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeRealParent))throw Error("BLOCKED: PR workflow atomic parent escapes the project .swarm directory");return realParent}async function assertSafeDirectory(directoryPath,expectedIdentity){let stat6=await fsp3.lstat(directoryPath,{bigint:!0});if(stat6.isSymbolicLink()||!stat6.isDirectory()||expectedIdentity&&!sameBigIntFileIdentity(stat6,expectedIdentity))throw Error("BLOCKED: PR workflow .swarm path must be a real directory and must not change during the operation");return{dev:stat6.dev,ino:stat6.ino}}async function assertOpenedSwarmFileIdentity(directory,filePath,handle,expectedParent,label){let openedStat=await handle.stat({bigint:!0});if(!openedStat.isFile())throw Error(`BLOCKED: ${label} is not a file`);return await assertClosedSwarmFileIdentity(directory,filePath,openedStat,expectedParent,label),{dev:openedStat.dev,ino:openedStat.ino}}async function assertClosedSwarmFileIdentity(directory,filePath,expectedIdentity,expectedParent,label){if(!expectedIdentity)throw Error(`BLOCKED: ${label} has no identity`);let[stat6,realRoot,realFile,realParent]=await Promise.all([fsp3.lstat(filePath,{bigint:!0}),fsp3.realpath(path14.resolve(directory,".swarm")),fsp3.realpath(filePath),fsp3.realpath(path14.dirname(filePath))]),relativeFile=path14.relative(realRoot,realFile);if(stat6.isSymbolicLink()||!stat6.isFile()||!sameBigIntFileIdentity(stat6,expectedIdentity)||normalizeComparableFsPath(realParent)!==normalizeComparableFsPath(expectedParent)||relativeFile===""||relativeFile===".."||relativeFile.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeFile))throw Error(`BLOCKED: ${label} changed or escaped .swarm`)}async function writeAtomicJson2(directory,filePath,value){let safeParent=await ensurePrWorkflowSafeParentDirectory(directory,filePath),tempPath=`${filePath}.tmp.${process.pid}.${randomUUID2()}`,tempIdentity,lastError;try{let handle=await fsp3.open(tempPath,"wx");try{await _test_exports.beforeAtomicTempWrite?.(),tempIdentity=await assertOpenedSwarmFileIdentity(directory,tempPath,handle,safeParent,"PR workflow atomic temporary file"),await handle.writeFile(JSON.stringify(value,null,2),"utf-8"),await handle.sync()}finally{await handle.close()}await _test_exports.beforeAtomicRename?.(),await assertClosedSwarmFileIdentity(directory,tempPath,tempIdentity,safeParent,"PR workflow atomic temporary file");for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES3;attempt++)try{await _test_exports.rename(tempPath,filePath),lastError=void 0;break}catch(error49){lastError=error49;let code=error49.code;if(code!=="EEXIST"&&code!=="EPERM"&&code!=="EBUSY")break;if(attempt<WINDOWS_RENAME_MAX_RETRIES3-1)await delay(RENAME_RETRY_DELAY_MS)}if(lastError)throw lastError;await assertClosedSwarmFileIdentity(directory,filePath,tempIdentity,safeParent,"PR workflow atomic destination file")}finally{try{await fsp3.rm(tempPath,{force:!0})}catch{}}}async function writePrWorkflowAtomicJson(directory,filePath,value){await writeAtomicJson2(directory,filePath,value)}function isoNow(){return new Date().toISOString()}function delay(ms){return new Promise((resolve9)=>setTimeout(resolve9,ms))}var PR_REVIEW_BASE_DIMENSION_IDS,PR_REVIEW_REQUIRED_MICRO_LANE_IDS,PR_REVIEW_DEPTH_TIER_THRESHOLDS,PR_REVIEW_BASE_LANE_FLOORS,PR_REVIEW_MICRO_LANE_FLOORS,GATE_SCHEMA_VERSION=1,MAX_TRACKED_SESSIONS=200,MAX_WORKFLOW_BATCHES=128,WINDOWS_RENAME_MAX_RETRIES3=3,RENAME_RETRY_DELAY_MS=10,STATE_MUTATION_LOCK_MAX_ATTEMPTS=50,STATE_MUTATION_LOCK_RETRY_DELAY_MS=10,STATE_MUTATION_LOCK_UNINITIALIZED_STALE_MS=30000,MAX_COMPLETED_CHECKOUT_LOCK_OWNERS=64,CHECKOUT_MUTATION_ACTION_TIMEOUT_MS=300000,MAX_CANDIDATE_ISSUES_PER_ARTIFACT=8,MAX_BASE_COVERAGE_DIAGNOSTICS=8,MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS=1000,DISPATCH_TOOL_NAME="dispatch_lanes_async",BLOCKING_DISPATCH_TOOL_NAME="dispatch_lanes",WORKFLOW_GATE_DIR="pr-workflow-gates",trackedStatesByProjectSession,pendingStateMutationsByProjectSession,pendingCheckoutMutationsByProject,completedCheckoutLockOwners,PrReviewBaseDimensionIdSchema,PrReviewBaseDispatchRecordSchema,PrFeedbackLaneOwnershipSchema,PrFeedbackVerificationRecordSchema,PrFeedbackStageACheckReceiptSchema,PrFeedbackStageARecordSchema,PrFeedbackGateBatchRecordSchema,PrFeedbackReadyToPublishRecordSchema,PrReviewValidationBatchRecordSchema,PrFeedbackScopeDeclarationRecordSchema,PrWorkflowCheckoutRecoveryRecordSchema,PrFeedbackReviewHandoffRecordSchema,PrWorkflowGateStateSchema,PR_FEEDBACK_PHASE_ORDER,PR_FEEDBACK_PHASE_ROLE,PR_REVIEW_HANDOFF_RELATIVE_PATH_PATTERN,PR_REVIEW_HANDOFF_MAX_BYTES=131072,PR_REVIEW_FINDINGS_MAX_BYTES=10485760,PrReviewFeedbackHandoffArtifactSchema,PrReviewFindingProjectionSchema,_test_exports,PR_WORKFLOW_SHARED_CONTROLLER_TOOLS,PR_REVIEW_CONTROLLER_TOOLS,PR_FEEDBACK_CONTROLLER_TOOLS,PR_REVIEW_READ_ONLY_TOOL_NAMES,PR_WORKFLOW_CD_PREFIX_PATTERN,PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN,PR_WORKFLOW_MAX_CD_PREFIX_STRIPS=3,PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN,PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN,REVIEWER_CLASSIFICATIONS,REVIEWER_EVIDENCE_TYPES,REVIEW_SEVERITIES,CRITIC_STATUSES,FEEDBACK_CLASSIFICATIONS,PrWorkflowCheckoutMutationTimeoutError;var init_pr_workflow_gate=__esm(()=>{init_zod();init_candidate_contract();init_candidate_parser();init_lane_output_store();init_pending_delegations();init_pr_review_trigger_contract();init_workspace_snapshot();init_constants();init_schema();init_pr_workflow_state();init_tool_metadata();init_utils2();PR_REVIEW_BASE_DIMENSION_IDS=["intent-architecture","correctness-state","tests-falsifiability","security-trust","reliability-performance","compatibility-delivery"],PR_REVIEW_REQUIRED_MICRO_LANE_IDS=PR_REVIEW_REQUIRED_TRIGGER_IDS,PR_REVIEW_DEPTH_TIER_THRESHOLDS={smallMaxChangedLines:50,smallMaxChangedFiles:3,mediumMaxChangedLines:500,mediumMaxChangedFiles:20},PR_REVIEW_BASE_LANE_FLOORS={S:1,M:3,L:PR_REVIEW_BASE_DIMENSION_IDS.length},PR_REVIEW_MICRO_LANE_FLOORS={S:1,M:6,L:PR_REVIEW_REQUIRED_MICRO_LANE_IDS.length};trackedStatesByProjectSession=new Map,pendingStateMutationsByProjectSession=new Map,pendingCheckoutMutationsByProject=new Map,completedCheckoutLockOwners=new Map,PrReviewBaseDimensionIdSchema=exports_external.enum(["intent-architecture","correctness-state","tests-falsifiability","security-trust","reliability-performance","compatibility-delivery"]),PrReviewBaseDispatchRecordSchema=exports_external.object({batchId:exports_external.string().min(1),lanes:exports_external.array(exports_external.object({laneId:exports_external.string().min(1),workflowLane:PrReviewBaseDimensionIdSchema,ownedWorkflowLanes:exports_external.array(PrReviewBaseDimensionIdSchema).min(1).max(PR_REVIEW_BASE_DIMENSION_IDS.length).optional()}).strict()).min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackLaneOwnershipSchema=exports_external.object({laneId:exports_external.string().min(1),ownedItemIds:exports_external.array(exports_external.string().min(1)).min(1)}).strict(),PrFeedbackVerificationRecordSchema=exports_external.object({batchId:exports_external.string().min(1),ownership:exports_external.array(PrFeedbackLaneOwnershipSchema).min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackStageACheckReceiptSchema=exports_external.object({category:exports_external.enum(["build","typecheck","lint","diff-check","reproduction"]),workingDirectory:exports_external.string().min(1).optional(),obligationId:exports_external.string().min(1).optional(),validatorContract:exports_external.object({path:exports_external.string().min(1),id:exports_external.string().min(1)}).strict().optional(),command:exports_external.array(exports_external.string().min(1)).min(1),targets:exports_external.array(exports_external.string().min(1)).min(1).optional(),feedbackTargets:exports_external.array(exports_external.object({feedbackItemId:exports_external.string().min(1),target:exports_external.string().min(1),expectedBehavior:exports_external.string().min(8)}).strict()).min(1).optional(),durationMs:exports_external.number().nonnegative()}).strict(),PrFeedbackStageARecordSchema=exports_external.object({revisionDigest:exports_external.string().min(1),checks:exports_external.array(PrFeedbackStageACheckReceiptSchema).min(2).max(258),feedbackItemIds:exports_external.array(exports_external.string().min(1)).min(1).optional(),applicableCategories:exports_external.array(exports_external.enum(["build","typecheck","lint"])).max(3).optional(),applicableObligations:exports_external.array(exports_external.object({id:exports_external.string().min(1),category:exports_external.enum(["build","typecheck","lint"]),workingDirectory:exports_external.string().min(1),source:exports_external.string().min(1),validatorContract:exports_external.object({path:exports_external.string().min(1),id:exports_external.string().min(1)}).strict().optional()}).strict()).max(256).optional(),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackGateBatchRecordSchema=exports_external.object({batchId:exports_external.string().min(1),phase:exports_external.enum(["stage-b-reviewer","stage-b-test","closeout-reviewer","closeout-critic"]),laneId:exports_external.string().min(1),itemIds:exports_external.array(exports_external.string().min(1)).min(1),revisionDigest:exports_external.string().min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackReadyToPublishRecordSchema=exports_external.object({revisionDigest:exports_external.string().min(1),localHead:exports_external.string().min(1),remoteName:exports_external.string().min(1),remoteBranchRef:exports_external.string().startsWith("refs/heads/"),remoteRef:exports_external.string().startsWith("refs/remotes/"),validatedAt:exports_external.string().min(1)}).strict(),PrReviewValidationBatchRecordSchema=exports_external.object({batchId:exports_external.string().min(1),phase:exports_external.enum(["council","reviewer","critic"]),lanes:exports_external.array(exports_external.object({laneId:exports_external.string().min(1),workflowLane:exports_external.string().min(1),reviewItemIds:exports_external.array(exports_external.string().min(1)).min(1).optional()}).strict()).min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackScopeDeclarationRecordSchema=exports_external.object({taskId:exports_external.string().regex(/^\d+\.\d+(?:\.\d+)*$/),files:exports_external.array(exports_external.string().min(1)).min(1).max(1e4),revisionDigest:exports_external.string().min(1),declaredAt:exports_external.string().min(1),consumedByCallId:exports_external.string().min(1).optional()}).strict(),PrWorkflowCheckoutRecoveryRecordSchema=exports_external.object({code:exports_external.enum(["UNMERGED_INDEX","GIT_OPERATION_IN_PROGRESS","DIRTY_SUBMODULE","SWARM_STATE_TRACKING_ERROR","GIT_STATE_INDETERMINATE"]),retryable:exports_external.literal(!1),requiredAction:exports_external.string().min(1).max(2000),evidence:exports_external.object({worktreeRoot:exports_external.string().nullable(),gitDir:exports_external.string().nullable(),operations:exports_external.array(exports_external.string().min(1)).max(16),unmergedCodes:exports_external.array(exports_external.string().min(1)).max(16),paths:exports_external.array(exports_external.string()).max(20),trackedCount:exports_external.number().int().nonnegative(),untrackedCount:exports_external.number().int().nonnegative(),pathsTruncated:exports_external.boolean(),detail:exports_external.string().max(1000).optional()}).strict(),detectedAt:exports_external.string().min(1)}).strict(),PrFeedbackReviewHandoffRecordSchema=exports_external.object({path:exports_external.string().min(1).max(512),runId:exports_external.string().min(1).max(128),sourcePrHeadSha:exports_external.string().regex(/^[0-9a-f]{6,64}$/i),prUrl:exports_external.string().url().max(2000),findingIds:exports_external.array(exports_external.string().min(1).max(128)).min(1).max(1000),digest:exports_external.string().regex(/^[0-9a-f]{64}$/),sourceWorkflowInstanceId:exports_external.string().min(1).max(128),provenance:exports_external.enum(["active-review-v1","external-v1"])}).strict(),PrWorkflowGateStateSchema=exports_external.object({schemaVersion:exports_external.literal(GATE_SCHEMA_VERSION),revision:exports_external.number().int().nonnegative().default(0),workflowInstanceId:exports_external.string().min(1).max(128).optional(),sessionID:exports_external.string().min(1),mode:exports_external.enum(["PR_REVIEW","PR_FEEDBACK"]),activatedAt:exports_external.string().min(1),updatedAt:exports_external.string().min(1),prHeadSha:exports_external.string().min(1).optional(),prReviewBaseRef:exports_external.string().min(1).optional(),prReviewBaseSha:exports_external.string().min(1).optional(),prReviewDepthTier:exports_external.enum(["S","M","L"]).optional(),prReviewDiffStats:exports_external.object({changedLines:exports_external.number().int().nonnegative(),changedFiles:exports_external.number().int().nonnegative(),hasSubmoduleChange:exports_external.boolean().default(!1)}).strict().optional(),prReviewBaseDispatches:exports_external.array(PrReviewBaseDispatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prReviewBaseDispatch:PrReviewBaseDispatchRecordSchema.optional(),prReviewTriggerLedger:exports_external.array(PrReviewInlineTriggerRowSchema).length(PR_REVIEW_REQUIRED_TRIGGER_IDS.length).optional(),prReviewTriggerEvalPath:exports_external.string().min(1).optional(),prReviewValidationBatches:exports_external.array(PrReviewValidationBatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prReviewArtifactRunId:exports_external.string().min(1).optional(),prReviewFindingsPath:exports_external.string().min(1).optional(),prReviewArtifactBoundaries:exports_external.array(exports_external.enum(["post_explorer","post_reviewer","post_critic"])).max(3).optional(),prReviewHandoffPath:exports_external.string().min(1).optional(),prReviewHandoffRequired:exports_external.boolean().optional(),checkoutRecovery:PrWorkflowCheckoutRecoveryRecordSchema.optional(),prFeedbackTargetUrl:exports_external.string().url().max(2000).optional(),prFeedbackReviewHandoff:PrFeedbackReviewHandoffRecordSchema.optional(),prFeedbackInventory:exports_external.array(exports_external.string().min(1)).min(1).optional(),prFeedbackVerifications:exports_external.array(PrFeedbackVerificationRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prFeedbackVerification:PrFeedbackVerificationRecordSchema.optional(),prFeedbackStageA:PrFeedbackStageARecordSchema.optional(),prFeedbackGateBatches:exports_external.array(PrFeedbackGateBatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prFeedbackReadyToPublish:PrFeedbackReadyToPublishRecordSchema.optional(),prFeedbackScopes:exports_external.array(PrFeedbackScopeDeclarationRecordSchema).max(MAX_WORKFLOW_BATCHES).optional()}).passthrough();PR_FEEDBACK_PHASE_ORDER=["stage-b-reviewer","stage-b-test","closeout-reviewer","closeout-critic"];PR_FEEDBACK_PHASE_ROLE={"stage-b-reviewer":"reviewer","stage-b-test":"test_engineer","closeout-reviewer":"reviewer","closeout-critic":"critic"};PR_REVIEW_HANDOFF_RELATIVE_PATH_PATTERN=/^pr-review\/([A-Za-z0-9][A-Za-z0-9._-]{0,127})\/feedback-handoff\.json$/,PrReviewFeedbackHandoffArtifactSchema=exports_external.object({schema_version:exports_external.literal(1),run_id:exports_external.string().min(1).max(128),pr_head_sha:exports_external.string().regex(/^[0-9a-f]{6,64}$/i),created_at:exports_external.string().datetime(),pr_url:exports_external.string().url().max(2000),finding_ids:exports_external.array(exports_external.string().min(1).max(128)).min(1).max(1000),summary:exports_external.string().min(1).max(20000),provenance:exports_external.array(exports_external.string().min(1).max(4000)).min(1).max(1000)}).strict();PrReviewFindingProjectionSchema=exports_external.object({finding_id:exports_external.string().min(1).max(128),status:exports_external.enum(["PENDING","CONFIRMED","DISPROVED","PRE_EXISTING"]),next_action:exports_external.enum(["route_to_reviewer","route_to_critic","report","suppress_with_reason","handoff_to_feedback"])}).passthrough();_test_exports={workflowGateStateRelativePath,workflowGateStateLockRelativePath,workflowCheckoutMutationLockRelativePath,withPrWorkflowCheckoutMutationLock,resetTrackedStateCache:()=>{trackedStatesByProjectSession.clear(),pendingStateMutationsByProjectSession.clear(),pendingCheckoutMutationsByProject.clear(),completedCheckoutLockOwners.clear(),_test_exports.beforeTerminalClear=void 0,_test_exports.beforePrFeedbackTransitionLock=void 0,_test_exports.beforePrFeedbackTrackingSwitch=void 0,_test_exports.afterPrFeedbackTrackingSwitch=void 0,_test_exports.beforePrFeedbackTrackingPersist=void 0,_test_exports.beforeBoundedSwarmFileOpen=void 0,_test_exports.beforeSessionStateLockWrite=void 0,_test_exports.beforeCheckoutLockWrite=void 0,_test_exports.beforeSafeDirectoryCreate=void 0,_test_exports.beforeAtomicTempWrite=void 0,_test_exports.beforeAtomicRename=void 0,_test_exports.openCheckoutLock=openCheckoutLockFile,_test_exports.removeCheckoutLock=removeCheckoutLockFile,_test_exports.checkoutMutationActionTimeoutMs=CHECKOUT_MUTATION_ACTION_TIMEOUT_MS},beforeTerminalClear:void 0,beforePrFeedbackTransitionLock:void 0,beforePrFeedbackTrackingSwitch:void 0,afterPrFeedbackTrackingSwitch:void 0,beforePrFeedbackTrackingPersist:void 0,beforeBoundedSwarmFileOpen:void 0,beforeSessionStateLockWrite:void 0,beforeCheckoutLockWrite:void 0,beforeSafeDirectoryCreate:void 0,beforeAtomicTempWrite:void 0,beforeAtomicRename:void 0,openCheckoutLock:openCheckoutLockFile,removeCheckoutLock:removeCheckoutLockFile,checkoutMutationActionTimeoutMs:CHECKOUT_MUTATION_ACTION_TIMEOUT_MS,resolveCurrentGitHead,resolveCurrentGitHeadAsync,resolveCurrentUpstreamPushTarget,resolveCurrentUpstreamPushTargetAsync,resolveCurrentUpstreamRemoteRef,resolveExactRemoteBranchHead,resolveExactRemoteBranchHeadAsync,resolveCommitCountSince,resolveCommitCountSinceAsync,resolveIsWorkingTreeClean,resolveIsWorkingTreeCleanAsync,resolveIsExactSingleChildCommit,resolveIsExactSingleChildCommitAsync,resolvePrReviewDiffStats,resolvePrReviewDiffStatsAsync,resolvePrWorkflowRevisionDigest,resolveRemoteRefsContainingHead,resolveRemoteRefsContainingHeadAsync,parseCriticVerdict,isProcessAlive,isSafeStandaloneGitCommit,rename:fsp3.rename,nowMs:()=>Date.now()};PR_WORKFLOW_SHARED_CONTROLLER_TOOLS=new Set(["abort_pr_workflow","collect_lane_results","complete_pr_workflow","dispatch_lanes_async","prepare_pr_workflow_checkout"]),PR_REVIEW_CONTROLLER_TOOLS=new Set(["parse_lane_candidates","write_pr_review_artifact","write_pr_review_trigger_eval"]),PR_FEEDBACK_CONTROLLER_TOOLS=new Set(["prepare_pr_feedback_scope","run_pr_feedback_stage_a"]);PR_REVIEW_READ_ONLY_TOOL_NAMES=new Set(["ast_grep_search","codesearch","glob","grep","list","lsp","open","read","search","skill","tree","view","web_fetch","web_search","webfetch","websearch"]);PR_WORKFLOW_CD_PREFIX_PATTERN=/^cd\s+(?:\/d\s+)?(?:"[A-Za-z0-9 _.\\/:~+-]+"|'[A-Za-z0-9 _.\\/:~+-]+'|[A-Za-z0-9_.\\/:~+-]+)\s*&&\s*/i,PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN=/\s+2>&1\s*$/,PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN=/^[Gg][Ii][Tt](?: -C (?:"[^"]+"|'[^']+'|\S+))* (.+)$/,PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN=/^[Gg][Ii][Tt] -C /;REVIEWER_CLASSIFICATIONS=new Set(["CONFIRMED","DISPROVED","UNVERIFIED","PRE_EXISTING"]),REVIEWER_EVIDENCE_TYPES=new Set(["STRUCTURALLY_PROVEN","EXECUTION_PROVEN","STATIC_TRACE_PROVEN","PLAUSIBLE_BUT_UNVERIFIED"]),REVIEW_SEVERITIES=new Set(["CRITICAL","HIGH","MEDIUM","LOW","INFO","NONE"]),CRITIC_STATUSES=new Set(["UPHELD","DOWNGRADED","DISPROVED","NEEDS_MORE_EVIDENCE"]),FEEDBACK_CLASSIFICATIONS=new Set(["CONFIRMED","PARTIAL","DISPROVED","PRE_EXISTING","NEEDS_MORE_EVIDENCE","NEEDS_USER_DECISION"]);PrWorkflowCheckoutMutationTimeoutError=class PrWorkflowCheckoutMutationTimeoutError extends Error{phase;code="PR_WORKFLOW_CHECKOUT_MUTATION_TIMEOUT";retryable=!1;constructor(phase){super(phase==="queue"?"BLOCKED: timed out waiting for the active PR workflow checkout mutation; the existing owner still holds serialization and must settle before retrying":"BLOCKED: PR workflow checkout mutation exceeded its execution deadline; serialization remains held until the in-flight action actually settles");this.phase=phase;this.name="PrWorkflowCheckoutMutationTimeoutError"}}});async function handleAbortPrWorkflowCommand(directory,args2,sessionID){let tokens=(args2??[]).filter((token)=>token.trim().length>0),modeToken=tokens[0]?.toUpperCase(),knownMode=modeToken&&KNOWN_MODES.has(modeToken)?modeToken:void 0,reasonStartIndex=knownMode?1:0,reason=tokens.slice(reasonStartIndex).join(" ").trim().slice(0,500)||void 0;if(modeToken&&!knownMode)return`Error: Unknown mode "${modeToken}". Expected PR_REVIEW or PR_FEEDBACK.
|
|
185
|
+
`,"utf-8")}catch{}return await clearPrWorkflowGateState(directory,sessionID,state.revision),{mode:state.mode,...state.prHeadSha?{prHeadSha:state.prHeadSha}:{},openLanes:openLanes.length}}async function bindPrWorkflowHead(directory,sessionID,prHeadSha){let normalizedHead=normalizePrHeadSha(prHeadSha);return withPrWorkflowCheckoutMutationLock(directory,async()=>withSessionStateMutation(directory,normalizeSessionID(sessionID),async()=>{let state=await readPrWorkflowGateStateFromDisk(directory,normalizeSessionID(sessionID));if(!state)throw Error(`BLOCKED: no active PR workflow gate for session "${normalizeSessionID(sessionID)}". The gate must be activated before the PR head can be bound.`);if(await assertCurrentCheckoutHead(directory,normalizedHead,state.mode),state.prHeadSha&&state.prHeadSha!==normalizedHead)throw Error(`BLOCKED: active ${state.mode} workflow is bound to PR head "${state.prHeadSha}"; received "${normalizedHead}"`);if(!state.prHeadSha)await assertPrReviewCleanCheckout(directory,state.mode);if(!state.prHeadSha&&state.mode==="PR_FEEDBACK")await assertPrFeedbackTrackingCheckout(directory,normalizedHead);if(state.prHeadSha===normalizedHead){if(state.mode==="PR_FEEDBACK")await assertPrFeedbackTrackingCheckout(directory,normalizedHead);return state}let nextState={...state,prHeadSha:normalizedHead,updatedAt:isoNow()};return await _test_exports.beforePrFeedbackTrackingPersist?.(),writeStateWhileLocked(directory,nextState)}))}async function bindPrReviewBase(directory,sessionID,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_REVIEW")throw Error("BLOCKED: only PR_REVIEW can bind a review merge base");let baseRef=options.baseRef.trim(),baseSha=normalizePrHeadSha(options.baseSha).toLowerCase();if(!baseRef)throw Error("BLOCKED: PR_REVIEW base_ref must not be empty");if(state.prReviewBaseRef&&state.prReviewBaseRef!==baseRef||state.prReviewBaseSha&&state.prReviewBaseSha!==baseSha)throw Error(`BLOCKED: active PR_REVIEW is bound to merge-base scope "${state.prReviewBaseRef??"(unbound)"}" at "${state.prReviewBaseSha??"(unbound)"}"; received "${baseRef}" at "${baseSha}"`);if(state.prReviewBaseRef===baseRef&&state.prReviewBaseSha===baseSha)return state;let prHeadSha=normalizePrHeadSha(options.prHeadSha).toLowerCase(),diffStats=await _test_exports.resolvePrReviewDiffStatsAsync(directory,baseSha,prHeadSha);return state={...state,prReviewBaseRef:baseRef,prReviewBaseSha:baseSha,prReviewDepthTier:computePrReviewDepthTier(diffStats),...diffStats?{prReviewDiffStats:diffStats}:{},updatedAt:isoNow()},await persistState(directory,state),state}async function assertCurrentCheckoutHead(directory,expectedHead,mode="PR_REVIEW"){let normalizedExpected=normalizePrHeadSha(expectedHead),currentHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(!currentHead)throw Error(`BLOCKED: cannot resolve the current Git HEAD in "${directory}" to verify against PR head "${normalizedExpected}". This means Git could not resolve HEAD (the working directory may not be a Git repository, HEAD may be unborn, the commit object may be missing in a shallow clone, the Git binary may not be on PATH, or the bounded Git invocation may have timed out). Verify with: git -C "${directory}" rev-parse --verify HEAD^{commit}`);if(currentHead.toLowerCase()!==normalizedExpected.toLowerCase()){let remediation=mode==="PR_FEEDBACK"?"Check out the intended local tracking branch at that exact head (for example with a safe standalone `gh pr checkout <number-or-url>` or `git switch -c <local> --track <remote>/<branch>`), then retry the bind. Do not create a new detached feedback checkout.":`Run these bare, standalone commands from that directory: if the commit is not present locally, \`git fetch origin <pr-head-ref>\`; then \`git switch --detach ${normalizedExpected}\`. Do not prefix the switch with \`git -C\`; the read-only shell classifier refuses \`git -C ... switch\`.`;throw Error(`BLOCKED: current checkout HEAD "${currentHead}" does not match PR head "${normalizedExpected}" (working directory: "${directory}"). ${remediation}`)}return normalizedExpected}async function assertPrReviewCleanCheckout(directory,mode="PR_REVIEW"){if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error(`BLOCKED: ${mode} requires a clean index and working tree at the exact PR head`)}async function assertPrFeedbackTrackingCheckout(directory,prHeadSha){let currentHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(!currentHead)throw Error("BLOCKED: PR_FEEDBACK requires a resolved exact Git HEAD before first head bind");if(currentHead.toLowerCase()!==prHeadSha.toLowerCase())throw Error(`BLOCKED: PR_FEEDBACK exact head changed before attach; expected ${prHeadSha}, received ${currentHead}`);let currentUpstream=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory),matchingRemoteRefs=await _test_exports.resolveRemoteRefsContainingHeadAsync(directory,prHeadSha);if(currentUpstream){if(matchingRemoteRefs===null)throw Error("BLOCKED: PR_FEEDBACK could not verify the current upstream against the exact intake PR head; the bounded Git query failed or timed out");if(matchingRemoteRefs.includes(currentUpstream.remoteTrackingRef))return;throw Error(`BLOCKED: PR_FEEDBACK current upstream "${currentUpstream.remoteTrackingRef}" must point to the exact intake PR head "${prHeadSha}"; refusing to replace an existing tracking relationship`)}let candidates=await resolvePrFeedbackTrackingCandidatesAsync(directory,prHeadSha);if(!candidates)throw Error(`BLOCKED: PR_FEEDBACK could not inspect tracked branches for exact PR head "${prHeadSha}"; the bounded Git query failed or timed out`);let{local:localCandidates,remote:remoteCandidates}=candidates;if(localCandidates.length===1){if(await _test_exports.beforePrFeedbackTrackingSwitch?.(),!await switchPrFeedbackTrackingCandidateAsync(directory,localCandidates[0]))throw Error(`BLOCKED: PR_FEEDBACK could not attach exact local tracked branch "${localCandidates[0].branchName}"; it may be checked out in another linked worktree or the bounded Git switch failed`)}else if(localCandidates.length>1)throw Error(`BLOCKED: PR_FEEDBACK exact head "${prHeadSha}" matches multiple local tracked branches: ${localCandidates.map((candidate)=>candidate.branchName).join(", ")}`);else if(remoteCandidates.length===1){if(await _test_exports.beforePrFeedbackTrackingSwitch?.(),!await switchPrFeedbackTrackingCandidateAsync(directory,remoteCandidates[0]))throw Error(`BLOCKED: PR_FEEDBACK could not attach exact remote-tracking branch "${remoteCandidates[0].remoteTrackingRef}"; the bounded Git switch failed or timed out`)}else if(remoteCandidates.length>1)throw Error(`BLOCKED: PR_FEEDBACK exact head "${prHeadSha}" matches multiple remote-tracking refs: ${remoteCandidates.map((candidate)=>candidate.remoteTrackingRef).join(", ")}`);else throw Error("BLOCKED: PR_FEEDBACK requires a current local branch or exact remote-tracking ref that points to the intake PR head before the first bind");await _test_exports.afterPrFeedbackTrackingSwitch?.();let attachedHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(attachedHead?.toLowerCase()!==prHeadSha.toLowerCase())throw Error(`BLOCKED: PR_FEEDBACK exact head changed after attach; expected ${prHeadSha}, received ${attachedHead??"(unresolved)"}`);if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error("BLOCKED: PR_FEEDBACK requires a clean working tree after checkout attachment");let attachedUpstream=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory);if(!attachedUpstream)throw Error("BLOCKED: PR_FEEDBACK could not resolve the attached branch upstream after checkout promotion");if(!(await _test_exports.resolveRemoteRefsContainingHeadAsync(directory,prHeadSha))?.includes(attachedUpstream.remoteTrackingRef))throw Error(`BLOCKED: PR_FEEDBACK upstream "${attachedUpstream.remoteTrackingRef}" must point to the exact intake PR head "${prHeadSha}" before the first head bind`)}async function enforcePrWorkflowDispatchLanesAsync(directory,sessionID,toolName){let state=await readPrWorkflowGateState(directory,sessionID);if(!state)return null;if(toolName===DISPATCH_TOOL_NAME)return state;if(toolName===BLOCKING_DISPATCH_TOOL_NAME)throw Error(`BLOCKED: active ${state.mode} workflow for session "${state.sessionID}" requires ${DISPATCH_TOOL_NAME}; ${BLOCKING_DISPATCH_TOOL_NAME} is not allowed`);return state}async function enforcePrReviewBaseDimensions(directory,sessionID,lanes,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_REVIEW")throw wrongModeError(state,"PR_REVIEW");let normalizedLanes=normalizeWorkflowLanes(lanes),claimedDimensionIds=normalizedLanes.flatMap((lane)=>lane.ownedWorkflowLanes??[lane.workflowLane]);if(claimedDimensionIds.filter((laneId)=>!PR_REVIEW_BASE_DIMENSION_IDS.includes(laneId)).length>0){let expected=PR_REVIEW_BASE_DIMENSION_IDS.join(", "),received=claimedDimensionIds.join(", ")||"(none)";throw Error(`BLOCKED: PR_REVIEW base dispatch lane ids must be drawn from: ${expected}. Received: ${received}`)}if((state.prReviewDepthTier??"L")==="L"&&normalizedLanes.some((lane)=>(lane.ownedWorkflowLanes?.length??1)!==1))throw Error("BLOCKED: PR_REVIEW base dispatch at depth tier L requires one dedicated lane per dimension; consolidated owned_workflow_lanes are allowed only at tiers S and M");let batchId=normalizeBatchId(options.batchId),previous=state.prReviewBaseDispatches??[];if(previous.some((record3)=>record3.batchId===batchId))throw Error(`BLOCKED: PR_REVIEW base batch id "${batchId}" is already recorded`);if(previous.length>=MAX_WORKFLOW_BATCHES)throw Error("BLOCKED: PR_REVIEW base batch limit reached");let record2={batchId,lanes:normalizedLanes.map((lane)=>({laneId:lane.laneId,workflowLane:lane.workflowLane,...lane.ownedWorkflowLanes?{ownedWorkflowLanes:lane.ownedWorkflowLanes}:{}})),validatedAt:isoNow()},nextState={...state,updatedAt:isoNow(),prReviewBaseDispatches:[...previous,record2],prReviewBaseDispatch:record2};return await persistState(directory,nextState),nextState}async function assertPrReviewBaseCoverageSettled(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_REVIEW"),batches=state.prReviewBaseDispatches??[];if(batches.length===0)throw Error("BLOCKED: PR_REVIEW requires at least one base batch");let covered=new Set,malformedDiagnostics=[];for(let batch of batches){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:base",batch.validatedAt,!0,new Set,void 0,malformedDiagnostics);for(let obligation of successful)covered.add(obligation)}let missing=PR_REVIEW_BASE_DIMENSION_IDS.filter((dimension)=>!covered.has(dimension));if(missing.length>0||covered.size!==PR_REVIEW_BASE_DIMENSION_IDS.length)throw Error(`BLOCKED: PR_REVIEW base coverage is incomplete; missing dimensions: ${missing.join(", ")||"(none)"}${malformedDiagnostics.length>0?`; malformed candidate diagnostics: ${malformedDiagnostics.join(" | ")}`:""}`);return state}async function recordPrReviewValidationBatch(directory,sessionID,phase,lanes,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_REVIEW")throw wrongModeError(state,"PR_REVIEW");if(!state.prReviewTriggerEvalPath)throw Error("BLOCKED: PR_REVIEW validation dispatch requires a completed trigger evaluation");if(phase==="reviewer"&&(state.prReviewValidationBatches??[]).some((batch)=>batch.phase==="council"))state=await assertPrReviewValidationSettled(directory,sessionID,"council");else if(phase==="critic")state=await assertPrReviewValidationSettled(directory,sessionID,"reviewer");let normalizedLanes=normalizeWorkflowLanes(lanes);if((phase==="reviewer"||phase==="critic")&&normalizedLanes.some((lane)=>!lane.reviewItemIds?.length))throw Error(`BLOCKED: PR_REVIEW ${phase} lanes require non-empty review_item_ids ownership`);if(phase==="reviewer"||phase==="critic"){assertNoDuplicates(normalizedLanes.flatMap((lane)=>lane.reviewItemIds??[]),`PR_REVIEW ${phase} review item ownership`);let assigned=normalizedLanes.flatMap((lane)=>lane.reviewItemIds??[]),required2=phase==="reviewer"?derivePrReviewCandidateInventory(directory,state):derivePrReviewCriticInventory(directory,state);assertExactStringSet(assigned,required2,`PR_REVIEW ${phase} ownership`)}let batchId=normalizeBatchId(options.batchId),previous=state.prReviewValidationBatches??[];if(previous.some((batch)=>batch.batchId===batchId))throw Error(`BLOCKED: PR_REVIEW validation batch id "${batchId}" is already recorded`);if(previous.length>=MAX_WORKFLOW_BATCHES)throw Error("BLOCKED: PR_REVIEW validation batch limit reached");let record2={batchId,phase,lanes:normalizedLanes,validatedAt:isoNow()},retained=phase==="reviewer"?previous.filter((batch)=>batch.phase!=="critic"):previous,nextState={...state,updatedAt:isoNow(),prReviewValidationBatches:[...retained,record2]};return await persistState(directory,nextState),nextState}async function assertPrReviewValidationSettled(directory,sessionID,phase){let state=await requireBoundState(directory,sessionID,"PR_REVIEW"),declaredPhases=new Set((state.prReviewValidationBatches??[]).map((batch)=>batch.phase)),phases=phase?[phase]:["council","reviewer","critic"].filter((candidate)=>declaredPhases.has(candidate));for(let requiredPhase of phases){let validationBatches=state.prReviewValidationBatches??[],forbiddenSubagentSessionIds=new Set;if(requiredPhase==="critic")for(let reviewerBatch of validationBatches.filter((batch)=>batch.phase==="reviewer"))for(let record2 of findByBatchId(directory,reviewerBatch.batchId,{parentSessionId:state.sessionID})){let subagentSessionId=record2.subagentSessionId?.trim();if(subagentSessionId)forbiddenSubagentSessionIds.add(subagentSessionId)}let batches=validationBatches.filter((batch)=>batch.phase===requiredPhase);if(requiredPhase==="reviewer"){let latestCouncilIndex=-1;for(let index=0;index<validationBatches.length;index++)if(validationBatches[index]?.phase==="council")latestCouncilIndex=index;if(latestCouncilIndex>=0)batches=validationBatches.slice(latestCouncilIndex+1).filter((batch)=>batch.phase==="reviewer")}if(batches.length===0)throw Error(requiredPhase==="reviewer"&&declaredPhases.has("council")?"BLOCKED: PR_REVIEW requires at least one reviewer batch after the latest council batch":`BLOCKED: PR_REVIEW requires at least one ${requiredPhase} batch`);let allObligations=new Set(batches.flatMap((batch)=>batch.lanes.map((lane)=>lane.workflowLane))),settled=new Set,hasFullySuccessfulExactBatch=!1;for(let batch of batches){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,`swarm-pr-review:${requiredPhase}`,batch.validatedAt,!0,forbiddenSubagentSessionIds);if(successful.size===batch.lanes.length&&batch.lanes.every((lane)=>successful.has(lane.workflowLane)))hasFullySuccessfulExactBatch=!0;for(let obligation of successful)settled.add(obligation)}if((requiredPhase==="reviewer"||requiredPhase==="critic")&&!hasFullySuccessfulExactBatch)throw Error(`BLOCKED: PR_REVIEW ${requiredPhase} requires one fully successful exact batch; complementary partial retries are not a coherent verdict set`);let missing=[...allObligations].filter((obligation)=>!settled.has(obligation));if(missing.length>0)throw Error(`BLOCKED: PR_REVIEW ${requiredPhase} obligations lack successful exact artifacts: ${missing.join(", ")}`)}return state}async function declarePrFeedbackInventory(directory,sessionID,inventoryIds,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_FEEDBACK")throw wrongModeError(state,"PR_FEEDBACK");let normalizedInventory=normalizeInventoryIds(inventoryIds),requiredHandoffIds=state.prFeedbackReviewHandoff?.findingIds??[],inventorySet=new Set(normalizedInventory),missingHandoffIds=requiredHandoffIds.filter((findingId)=>!inventorySet.has(findingId));if(missingHandoffIds.length>0)throw Error(`BLOCKED: PR_FEEDBACK inventory must include every continued review finding: ${missingHandoffIds.join(", ")}`);if(state.prFeedbackInventory){if(!sameStringArray(state.prFeedbackInventory,normalizedInventory))throw Error("BLOCKED: PR_FEEDBACK inventory is immutable after declaration");return state}let nextState={...state,updatedAt:isoNow(),prFeedbackInventory:normalizedInventory,prFeedbackVerifications:[]};return await persistState(directory,nextState),nextState}async function enforcePrFeedbackVerificationOwnership(directory,sessionID,ownership,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_FEEDBACK")throw wrongModeError(state,"PR_FEEDBACK");let inventory=state.prFeedbackInventory;if(!inventory||inventory.length===0)throw Error(`BLOCKED: PR_FEEDBACK verification for session "${state.sessionID}" requires a declared feedback inventory before dispatch`);let normalizedOwnership=normalizeOwnership(ownership),inventorySet=new Set(inventory),claimedByItemId=new Map,previous=state.prFeedbackVerifications??[],batchId=normalizeBatchId(options.batchId);if(previous.some((record3)=>record3.batchId===batchId))throw Error(`BLOCKED: PR_FEEDBACK verification batch id "${batchId}" is already recorded`);if(previous.length>=MAX_WORKFLOW_BATCHES)throw Error("BLOCKED: PR_FEEDBACK verification batch limit reached");for(let record3 of previous)for(let lane of record3.ownership)for(let itemId of lane.ownedItemIds)claimedByItemId.set(itemId,lane.laneId);for(let lane of normalizedOwnership)for(let itemId of lane.ownedItemIds){if(!inventorySet.has(itemId))throw Error(`BLOCKED: PR_FEEDBACK verification lane "${lane.laneId}" owns undeclared item "${itemId}"`);let previousLane=claimedByItemId.get(itemId);if(previousLane&&previousLane!==lane.laneId)throw Error(`BLOCKED: PR_FEEDBACK verification item "${itemId}" is owned by both "${previousLane}" and "${lane.laneId}"`);claimedByItemId.set(itemId,lane.laneId)}let record2={batchId,ownership:normalizedOwnership,validatedAt:isoNow()},nextState={...state,updatedAt:isoNow(),prFeedbackVerifications:[...previous,record2],prFeedbackVerification:record2};return await persistState(directory,nextState),nextState}async function assertPrFeedbackVerificationSettled(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),currentDigest=await currentPrFeedbackRevisionDigest(directory,state),inventory=state.prFeedbackInventory,batches=state.prFeedbackVerifications??[];if(!inventory||batches.length===0)throw Error("BLOCKED: PR_FEEDBACK requires an immutable inventory and verification batches");let covered=new Set;for(let batch of batches){let successfulLaneIds=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.ownership.map((lane)=>({laneId:lane.laneId,workflowLane:lane.laneId})),"swarm-pr-feedback:verification",batch.validatedAt,!1,new Set,currentDigest);for(let lane of batch.ownership){if(!successfulLaneIds.has(lane.laneId))continue;if(!feedbackArtifactCoversItems(directory,state,batch.batchId,lane.laneId,lane.ownedItemIds))continue;for(let itemId of lane.ownedItemIds)covered.add(itemId)}}let missing=inventory.filter((itemId)=>!covered.has(itemId));if(missing.length>0||covered.size!==inventory.length)throw Error(`BLOCKED: PR_FEEDBACK verification ownership is incomplete; missing inventory items: ${missing.join(", ")||"(none)"}`);return state}async function recordPrFeedbackStageA(directory,sessionID,revisionDigest,checks3,options={}){let state=await assertPrFeedbackVerificationSettled(directory,sessionID),currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(revisionDigest!==currentDigest)throw Error("BLOCKED: PR_FEEDBACK Stage A receipt is stale because the working-tree revision changed during validation");if(checks3.length<2||checks3.length>258)throw Error("BLOCKED: PR_FEEDBACK Stage A requires two to 258 controller-created check receipts");let optionalCategoryOrder=["build","typecheck","lint"],applicableCategories=options.applicableCategories??optionalCategoryOrder.filter((category)=>checks3.some((check2)=>check2.category===category));if(assertNoDuplicates(applicableCategories,"PR_FEEDBACK Stage A applicable categories"),applicableCategories.some((category)=>!optionalCategoryOrder.includes(category)))throw Error("BLOCKED: PR_FEEDBACK Stage A applicability may contain only build, typecheck, and lint");let required2=new Set(["diff-check","reproduction",...applicableCategories]),singletonSeen=new Set,applicableObligations=[...options.applicableObligations??[]];assertNoDuplicates(applicableObligations.map(({id})=>id),"PR_FEEDBACK Stage A applicable obligations");let requiredObligationIds=new Set(applicableObligations.map(({id})=>id)),commandDigests=new Set,reproductionFeedbackItemIds=[];for(let check2 of checks3){if(["diff-check","reproduction"].includes(check2.category)&&singletonSeen.has(check2.category))throw Error(`BLOCKED: PR_FEEDBACK Stage A contains duplicate category "${check2.category}"`);if(singletonSeen.add(check2.category),required2.delete(check2.category),check2.obligationId){let obligation=applicableObligations.find((candidate)=>candidate.id===check2.obligationId);if(!obligation||obligation.category!==check2.category||obligation.workingDirectory!==(check2.workingDirectory??".")||!requiredObligationIds.delete(check2.obligationId))throw Error(`BLOCKED: PR_FEEDBACK Stage A receipt does not match one exact applicable obligation: ${check2.obligationId}`);let sourceContract=obligation.source.includes(".pr-validation.json#")?{path:obligation.source.slice(0,obligation.source.lastIndexOf("#")),id:obligation.source.slice(obligation.source.lastIndexOf("#")+1)}:void 0,requiredContract=obligation.validatorContract??sourceContract;if(requiredContract&&(check2.validatorContract?.path!==requiredContract.path||check2.validatorContract.id!==requiredContract.id))throw Error(`BLOCKED: PR_FEEDBACK Stage A obligation ${obligation.id} requires exact validator contract provenance`)}let commandDigest=createHash7("sha256").update(`${check2.obligationId??check2.category}\x00${check2.workingDirectory??"."}\x00${check2.command.join("\x00")}`).digest("hex");if(commandDigests.has(commandDigest))throw Error("BLOCKED: PR_FEEDBACK Stage A cannot reuse one command as multiple check receipts");if(commandDigests.add(commandDigest),check2.category==="diff-check"&&!sameStringArray(check2.command,["git","diff","--check"]))throw Error("BLOCKED: PR_FEEDBACK Stage A diff-check receipt is not the exact git diff --check command");if(check2.category==="reproduction"&&(!check2.targets?.length||!check2.feedbackTargets?.length||check2.targets.some((target)=>!check2.command.join(" ").includes(target))))throw Error("BLOCKED: PR_FEEDBACK Stage A reproduction receipt requires exact selected targets");if(check2.category==="reproduction"){if(reproductionFeedbackItemIds=check2.feedbackTargets.map((mapping)=>mapping.feedbackItemId),assertNoDuplicates(reproductionFeedbackItemIds,"PR_FEEDBACK Stage A reproduction feedback item mappings"),check2.feedbackTargets.some((mapping)=>!check2.targets.includes(mapping.target)))throw Error("BLOCKED: PR_FEEDBACK Stage A feedback mappings must reference exact executed reproduction targets")}}if(required2.size>0)throw Error(`BLOCKED: PR_FEEDBACK Stage A is missing required checks: ${[...required2].join(", ")}`);if(requiredObligationIds.size>0)throw Error(`BLOCKED: PR_FEEDBACK Stage A is missing applicable workspace obligations: ${[...requiredObligationIds].join(", ")}`);if(!sameStringArray(reproductionFeedbackItemIds,state.prFeedbackInventory??[]))throw Error("BLOCKED: PR_FEEDBACK Stage A reproduction must map every immutable feedback item exactly once and in declared order");let nextState={...state,updatedAt:isoNow(),prFeedbackStageA:{revisionDigest:currentDigest,checks:[...checks3],feedbackItemIds:reproductionFeedbackItemIds,applicableCategories:optionalCategoryOrder.filter((category)=>applicableCategories.includes(category)),applicableObligations,validatedAt:isoNow()},prFeedbackGateBatches:[],prFeedbackReadyToPublish:void 0};return await persistState(directory,nextState),nextState}async function recordPrFeedbackGateBatch(directory,sessionID,phase,lane,options){let state=await bindPrWorkflowHead(directory,sessionID,options.prHeadSha);if(state.mode!=="PR_FEEDBACK")throw wrongModeError(state,"PR_FEEDBACK");let inventory=state.prFeedbackInventory;if(!inventory?.length)throw Error("BLOCKED: PR_FEEDBACK ordered gates require an immutable feedback inventory");let normalized=normalizeOwnership([lane])[0];if(!sameStringArray(normalized.ownedItemIds,inventory))throw Error(`BLOCKED: PR_FEEDBACK ${phase} must own every inventory item exactly once and in declared order`);let phaseIndex=PR_FEEDBACK_PHASE_ORDER.indexOf(phase),prerequisite=PR_FEEDBACK_PHASE_ORDER[phaseIndex-1];if(prerequisite)state=await assertPrFeedbackGatePhaseSettled(directory,sessionID,prerequisite);let{prFeedbackStageA:stageA,prFeedbackInventory:refreshedInventory}=state,currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(!stageA||!refreshedInventory||stageA.revisionDigest!==currentDigest||!sameStringArray(stageA.feedbackItemIds??[],refreshedInventory)||options.revisionDigest!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} requires fresh Stage A checks on the current revision`);let batchId=normalizeBatchId(options.batchId),previous=state.prFeedbackGateBatches??[];if(previous.some((batch)=>batch.batchId===batchId))throw Error(`BLOCKED: PR_FEEDBACK gate batch id "${batchId}" is already recorded`);let retained=previous.filter((batch)=>PR_FEEDBACK_PHASE_ORDER.indexOf(batch.phase)<phaseIndex),record2={batchId,phase,laneId:normalized.laneId,itemIds:normalized.ownedItemIds,revisionDigest:currentDigest,validatedAt:isoNow()},nextState={...state,updatedAt:isoNow(),prFeedbackGateBatches:[...retained,record2]};return await persistState(directory,nextState),nextState}async function assertPrFeedbackGatePhaseSettled(directory,sessionID,phase){let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(state.prFeedbackStageA?.revisionDigest!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} cannot use stale Stage A evidence`);if(!sameStringArray(state.prFeedbackStageA?.feedbackItemIds??[],state.prFeedbackInventory??[]))throw Error(`BLOCKED: PR_FEEDBACK ${phase} Stage A reproduction is not bound to the exact immutable feedback inventory`);let batch=[...state.prFeedbackGateBatches??[]].reverse().find((candidate)=>candidate.phase===phase);if(!batch||batch.revisionDigest!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} has no validation batch on the current revision`);if(!successfulObligationsFromExactBatch(directory,state,batch.batchId,[{laneId:batch.laneId,workflowLane:phase,reviewItemIds:batch.itemIds}],`swarm-pr-feedback:${phase}`,batch.validatedAt,!0,new Set,currentDigest).has(phase))throw Error(`BLOCKED: PR_FEEDBACK ${phase} requires one complete, non-degraded positive verdict row per inventory item`);if(findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===batch.laneId)?.workspace?.dirtyHash!==currentDigest)throw Error(`BLOCKED: PR_FEEDBACK ${phase} artifact is not bound to the current revision digest`);return assertIndependentFeedbackGateSessions(directory,state,phase),state}function assertIndependentFeedbackGateSessions(directory,state,throughPhase){let throughIndex=PR_FEEDBACK_PHASE_ORDER.indexOf(throughPhase),batches=(state.prFeedbackGateBatches??[]).filter((batch)=>PR_FEEDBACK_PHASE_ORDER.indexOf(batch.phase)<=throughIndex),seenSessions=new Set;for(let batch of batches){let matching=findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).filter((record3)=>record3.laneId===batch.laneId);if(matching.length!==1)throw Error(`BLOCKED: PR_FEEDBACK ${batch.phase} must resolve from exactly one durable child session`);let record2=matching[0],expectedRole=PR_FEEDBACK_PHASE_ROLE[batch.phase];if(!(record2.normalizedAgent===expectedRole||expectedRole==="critic"&&record2.normalizedAgent.startsWith("critic_")))throw Error(`BLOCKED: PR_FEEDBACK ${batch.phase} requires role ${expectedRole}, received ${record2.normalizedAgent||"(unknown)"}`);if(seenSessions.has(record2.subagentSessionId))throw Error(`BLOCKED: PR_FEEDBACK independent phases reused child session "${record2.subagentSessionId}"`);seenSessions.add(record2.subagentSessionId)}}async function assertPrFeedbackReadyToPublish(directory,sessionID){let state=await assertPrFeedbackVerificationSettled(directory,sessionID);for(let phase of PR_FEEDBACK_PHASE_ORDER)state=await assertPrFeedbackGatePhaseSettled(directory,sessionID,phase);return state}async function assertPrFeedbackPublicationArmed(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),armed=state.prFeedbackReadyToPublish;if(!armed)throw Error("BLOCKED: PR_FEEDBACK publication is not armed; call complete_pr_workflow once after every ordered gate passes");let currentDigest=await currentPrFeedbackRevisionDigest(directory,state);if(armed.revisionDigest!==currentDigest)throw Error("BLOCKED: PR_FEEDBACK changed after publication was armed; rerun Stage A and every independent gate");if((await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim()!==armed.localHead)throw Error("BLOCKED: PR_FEEDBACK current Git HEAD changed after publication was armed");if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error("BLOCKED: PR_FEEDBACK working tree changed after publication was armed");let currentTarget=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory);if(!currentTarget||currentTarget.remoteName!==armed.remoteName||currentTarget.remoteBranchRef!==armed.remoteBranchRef||currentTarget.remoteTrackingRef!==armed.remoteRef)throw Error("BLOCKED: PR_FEEDBACK upstream publication target changed after publication was armed");return state}async function markPrReviewTriggerEvaluationComplete(directory,sessionID,artifactPath){let state=await assertPrReviewBaseCoverageSettled(directory,sessionID),normalizedPath=artifactPath.trim();if(!normalizedPath)throw Error("BLOCKED: PR_REVIEW trigger artifact path is required");let nextState={...state,updatedAt:isoNow(),prReviewTriggerEvalPath:normalizedPath};return await persistState(directory,nextState),nextState}async function bindPrReviewTriggerLedger(directory,sessionID,input){let ledger;try{ledger=validatePrReviewInlineTriggerLedger(input)}catch(error49){throw Error(`BLOCKED: invalid PR_REVIEW trigger_evaluation: ${error49 instanceof Error?error49.message:String(error49)}`)}let state=await assertPrReviewBaseCoverageSettled(directory,sessionID);if(state.prReviewTriggerLedger){let frozen;try{frozen=validatePrReviewInlineTriggerLedger(state.prReviewTriggerLedger)}catch(error49){throw Error(`BLOCKED: persisted PR_REVIEW trigger ledger is invalid: ${error49 instanceof Error?error49.message:String(error49)}`)}if(prReviewTriggerLedgerDigest(frozen.rows)!==prReviewTriggerLedgerDigest(ledger.rows))throw Error("BLOCKED: PR_REVIEW trigger_evaluation must remain exactly identical across every micro dispatch and the final receipt");return state}let nextState={...state,updatedAt:isoNow(),prReviewTriggerLedger:ledger.rows};return await persistState(directory,nextState),nextState}async function assertPrReviewArtifactBoundary(directory,sessionID,runId,boundary,findingIds){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");if(!state.prReviewTriggerEvalPath)throw Error("BLOCKED: PR_REVIEW findings persistence requires the trigger evaluation artifact");let persistedBoundaries=state.prReviewArtifactBoundaries??[],boundaryOrder=["post_explorer","post_reviewer","post_critic"],boundaryIndex=boundaryOrder.indexOf(boundary),requiredPriorBoundary=boundaryOrder[boundaryIndex-1];if(requiredPriorBoundary&&!persistedBoundaries.includes(requiredPriorBoundary))throw Error(`BLOCKED: PR_REVIEW ${boundary} findings require the prior ${requiredPriorBoundary} checkpoint`);if(persistedBoundaries.some((persisted)=>boundaryOrder.indexOf(persisted)>boundaryIndex))throw Error(`BLOCKED: PR_REVIEW ${boundary} findings cannot be persisted after a later checkpoint`);if(boundary==="post_reviewer")state=await assertPrReviewValidationSettled(directory,sessionID,"reviewer");else if(boundary==="post_critic"){if(await assertPrReviewValidationSettled(directory,sessionID,"reviewer"),derivePrReviewCriticInventory(directory,state).length>0)state=await assertPrReviewValidationSettled(directory,sessionID,"critic")}if(state.prReviewArtifactRunId&&state.prReviewArtifactRunId!==runId)throw Error(`BLOCKED: PR_REVIEW artifacts are already bound to run "${state.prReviewArtifactRunId}"`);let expectedFindingIds=derivePrReviewCandidateInventory(directory,state),normalizedFindingIds=[...new Set(findingIds)].sort();if(normalizedFindingIds.length!==findingIds.length||JSON.stringify(normalizedFindingIds)!==JSON.stringify([...expectedFindingIds].sort()))throw Error(`BLOCKED: PR_REVIEW ${boundary} findings must exactly cover the discovered candidate inventory`);return state}async function assertPrReviewArtifactRecordsMatchAuthoritativeVerdicts(directory,sessionID,boundary,records){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");if(boundary==="post_explorer"){for(let record2 of records)if(record2.status!=="PENDING"||record2.next_action!=="route_to_reviewer")throw Error(`BLOCKED: PR_REVIEW post_explorer record ${record2.finding_id} must remain PENDING and route_to_reviewer`);return}let reviewerVerdicts=deriveLatestPrReviewReviewerVerdicts(directory,state),criticVerdicts=boundary==="post_critic"?deriveLatestPrReviewCriticVerdicts(directory,state):void 0;for(let record2 of records){let reviewer=reviewerVerdicts.get(record2.finding_id);if(!reviewer)throw Error(`BLOCKED: PR_REVIEW ${boundary} record ${record2.finding_id} has no authoritative reviewer verdict`);if(record2.severity&&record2.severity!==reviewer.severity)throw Error(`BLOCKED: PR_REVIEW ${boundary} record ${record2.finding_id} severity differs from its reviewer verdict`);let requiresCritic=reviewer.classification==="CONFIRMED"&&["CRITICAL","HIGH","MEDIUM"].includes(reviewer.severity);if(boundary==="post_reviewer"){let expectedStatus=reviewer.classification==="UNVERIFIED"?"PENDING":reviewer.classification;if(record2.status!==expectedStatus)throw Error(`BLOCKED: PR_REVIEW post_reviewer record ${record2.finding_id} status differs from its reviewer verdict`);let expectedAction=requiresCritic?"route_to_critic":reviewer.classification==="CONFIRMED"||reviewer.classification==="PRE_EXISTING"?"report":reviewer.classification==="DISPROVED"?"suppress_with_reason":"route_to_reviewer";if(record2.next_action!==expectedAction)throw Error(`BLOCKED: PR_REVIEW post_reviewer record ${record2.finding_id} action does not match reviewer disposition`);continue}if(!requiresCritic){let expectedStatus=reviewer.classification==="UNVERIFIED"?"PENDING":reviewer.classification,expectedAction=reviewer.classification==="CONFIRMED"||reviewer.classification==="PRE_EXISTING"?"report":reviewer.classification==="DISPROVED"?"suppress_with_reason":"route_to_reviewer";if(record2.status!==expectedStatus||record2.next_action!==expectedAction)throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} cannot override its non-critic reviewer disposition`);continue}let critic=criticVerdicts?.get(record2.finding_id);if(!critic)throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} has no authoritative critic verdict`);if(record2.severity&&record2.severity!==critic.severity)throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} severity differs from its critic verdict`);if(critic.status==="DISPROVED"){if(record2.status!=="DISPROVED"||record2.next_action!=="suppress_with_reason")throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} must preserve the critic DISPROVED disposition`)}else if(record2.status!=="CONFIRMED"||!["report","handoff_to_feedback"].includes(record2.next_action))throw Error(`BLOCKED: PR_REVIEW post_critic record ${record2.finding_id} action does not match its critic verdict`)}}async function markPrReviewArtifactBoundary(directory,sessionID,runId,boundary,artifactPath,findingIds,handoffRequired){let state=await assertPrReviewArtifactBoundary(directory,sessionID,runId,boundary,findingIds),boundaries=new Set(state.prReviewArtifactBoundaries??[]);boundaries.add(boundary);let nextState={...state,updatedAt:isoNow(),prReviewArtifactRunId:runId,prReviewFindingsPath:artifactPath,prReviewArtifactBoundaries:[...boundaries],prReviewHandoffRequired:handoffRequired};return await persistState(directory,nextState),nextState}async function markPrReviewHandoffComplete(directory,sessionID,runId,artifactPath){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");if(state.prReviewArtifactRunId!==runId||!(state.prReviewArtifactBoundaries??[]).includes("post_critic"))throw Error("BLOCKED: PR_REVIEW handoff requires the final findings boundary for the same run");let nextState={...state,updatedAt:isoNow(),prReviewHandoffPath:artifactPath};return await persistState(directory,nextState),nextState}function normalizePrReviewFeedbackHandoffPath(handoffPath){let normalized=handoffPath.trim().replace(/\\/g,"/"),relative4=normalized.startsWith(".swarm/")?normalized.slice(7):normalized,matched=relative4.match(PR_REVIEW_HANDOFF_RELATIVE_PATH_PATTERN);if(!matched)return null;return{runId:matched[1],relativePath:relative4}}async function readBoundedSwarmRegularFile(directory,relativePath,maxBytes,label){let absPath=validateSwarmPath(directory,relativePath),swarmRoot=path14.resolve(directory,".swarm"),rootStat,artifactStat;try{rootStat=await fsp3.lstat(swarmRoot,{bigint:!0}),artifactStat=await fsp3.lstat(absPath,{bigint:!0})}catch(error49){if(error49.code==="ENOENT")throw Error(`BLOCKED: ${label} "${relativePath}" does not exist`);throw error49}if(rootStat.isSymbolicLink()||!rootStat.isDirectory())throw Error(`BLOCKED: ${label} root must be a real project .swarm directory`);if(artifactStat.isSymbolicLink()||!artifactStat.isFile())throw Error(`BLOCKED: ${label} must be a bounded regular file`);if(artifactStat.size>BigInt(maxBytes))throw Error(`BLOCKED: ${label} exceeds ${maxBytes} bytes`);let[realRoot,realArtifact]=await Promise.all([fsp3.realpath(swarmRoot),fsp3.realpath(absPath)]),relativeRealPath=path14.relative(realRoot,realArtifact);if(relativeRealPath===""||relativeRealPath===".."||relativeRealPath.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeRealPath))throw Error(`BLOCKED: ${label} escapes the project .swarm directory`);await _test_exports.beforeBoundedSwarmFileOpen?.();let handle=await fsp3.open(realArtifact,"r");try{let openedStat=await handle.stat({bigint:!0});if(!openedStat.isFile()||openedStat.size>BigInt(maxBytes)||!sameBigIntFileIdentity(artifactStat,openedStat))throw Error(`BLOCKED: ${label} changed during its bounded read`);let[postRootStat,postArtifactStat,postRealRoot,postRealArtifact]=await Promise.all([fsp3.lstat(swarmRoot,{bigint:!0}),fsp3.lstat(absPath,{bigint:!0}),fsp3.realpath(swarmRoot),fsp3.realpath(absPath)]),postRelativeRealPath=path14.relative(postRealRoot,postRealArtifact);if(postRootStat.isSymbolicLink()||!postRootStat.isDirectory()||!sameBigIntFileIdentity(rootStat,postRootStat)||postArtifactStat.isSymbolicLink()||!postArtifactStat.isFile()||!sameBigIntFileIdentity(artifactStat,postArtifactStat)||!sameBigIntFileIdentity(openedStat,postArtifactStat)||normalizeComparableFsPath(realRoot)!==normalizeComparableFsPath(postRealRoot)||normalizeComparableFsPath(realArtifact)!==normalizeComparableFsPath(postRealArtifact)||postRelativeRealPath===""||postRelativeRealPath===".."||postRelativeRealPath.startsWith(`..${path14.sep}`)||path14.isAbsolute(postRelativeRealPath))throw Error(`BLOCKED: ${label} changed or escaped during its bounded read`);let buffer=Buffer.allocUnsafe(maxBytes+1),{bytesRead}=await handle.read(buffer,0,maxBytes+1,0);if(bytesRead>maxBytes)throw Error(`BLOCKED: ${label} exceeds ${maxBytes} bytes`);return buffer.subarray(0,bytesRead).toString("utf8")}finally{await handle.close()}}function sameBigIntFileIdentity(left,right){return left.dev===right.dev&&left.ino===right.ino}function normalizeComparableFsPath(value){let normalized=path14.normalize(path14.resolve(value));return process.platform==="win32"?normalized.toLowerCase():normalized}async function readPrReviewFeedbackHandoffArtifact(directory,relativePath){let raw=await readBoundedSwarmRegularFile(directory,relativePath,PR_REVIEW_HANDOFF_MAX_BYTES,"PR_REVIEW feedback handoff artifact"),parsedJson;try{parsedJson=JSON.parse(raw)}catch{throw Error("BLOCKED: PR_REVIEW feedback handoff artifact is not valid JSON")}let parsed=PrReviewFeedbackHandoffArtifactSchema.safeParse(parsedJson);if(!parsed.success)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact is invalid");if(new Set(parsed.data.finding_ids).size!==parsed.data.finding_ids.length)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact contains duplicate finding IDs");return{artifact:parsed.data,digest:createHash7("sha256").update(raw,"utf8").digest("hex")}}async function readActionableReviewFindingIds(directory,state,runId){let expectedPath=`pr-review/${runId}/findings.jsonl`;if(state.prReviewFindingsPath!==expectedPath)throw Error(`BLOCKED: PR_REVIEW transition requires the exact final findings artifact "${expectedPath}"`);let raw=await readBoundedSwarmRegularFile(directory,expectedPath,PR_REVIEW_FINDINGS_MAX_BYTES,"PR_REVIEW final findings artifact"),latest=new Map;for(let[index,line]of raw.split(/\r?\n/).entries()){if(!line.trim())continue;let value;try{value=JSON.parse(line)}catch{throw Error(`BLOCKED: PR_REVIEW final findings artifact contains invalid JSON at line ${index+1}`)}let parsed=PrReviewFindingProjectionSchema.safeParse(value);if(!parsed.success)throw Error(`BLOCKED: PR_REVIEW final findings artifact contains an invalid record at line ${index+1}`);latest.set(parsed.data.finding_id,parsed.data)}return[...latest.values()].filter((record2)=>record2.status==="CONFIRMED"&&record2.next_action==="handoff_to_feedback").map((record2)=>record2.finding_id).sort()}function canonicalGitHubPrUrl(value){try{let url2=new URL(value);if(url2.protocol!=="https:"||url2.hostname.toLowerCase()!=="github.com")return null;let matched=url2.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(!matched)return null;let prNumber=Number(matched[3]);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return`github.com/${matched[1].toLowerCase()}/${matched[2].toLowerCase()}/pull/${prNumber}`}catch{return null}}function workflowIdentity(state){return state.workflowInstanceId??`legacy-${createHash7("sha256").update(`${state.sessionID}\x00${state.mode}\x00${state.activatedAt}`).digest("hex").slice(0,32)}`}function sameHandoffIds(left,right){let normalizedLeft=[...new Set(left)].sort(),normalizedRight=[...new Set(right)].sort();return sameStringArray(normalizedLeft,normalizedRight)}function assertSamePrFeedbackHandoff(state,relativePath,read,requestedPrUrl){let existing=state.prFeedbackReviewHandoff;if(!existing)throw Error(`BLOCKED: session "${state.sessionID}" is already active in PR_FEEDBACK without persisted review handoff provenance`);let artifactPr=canonicalGitHubPrUrl(read.artifact.pr_url),requestedPr=requestedPrUrl?canonicalGitHubPrUrl(requestedPrUrl):artifactPr;if(!artifactPr||requestedPrUrl&&requestedPr!==artifactPr||existing.path!==relativePath||existing.runId!==read.artifact.run_id||existing.digest!==read.digest||existing.sourcePrHeadSha.toLowerCase()!==read.artifact.pr_head_sha.toLowerCase()||canonicalGitHubPrUrl(existing.prUrl)!==artifactPr||!sameHandoffIds(existing.findingIds,read.artifact.finding_ids))throw Error(`BLOCKED: session "${state.sessionID}" is already active in PR_FEEDBACK for a different handoff or PR`)}async function assertPrReviewTerminalReady(directory,sessionID){let state=await requireBoundState(directory,sessionID,"PR_REVIEW");await assertPrReviewCleanCheckout(directory,"PR_REVIEW");let open3=readDelegations(directory).filter((record2)=>record2.parentSessionId===state.sessionID&&record2.mode?.startsWith("swarm-pr-")&&(record2.status==="pending"||record2.status==="running"));if(open3.length>0)throw Error(`BLOCKED: PR_REVIEW transition has ${open3.length} unsettled PR workflow lane(s)`);if(await assertPrReviewBaseCoverageSettled(directory,sessionID),!state.prReviewTriggerEvalPath)throw Error("BLOCKED: PR_REVIEW transition requires a persisted trigger evaluation artifact");if((state.prReviewValidationBatches??[]).some((batch)=>batch.phase==="council"))await assertPrReviewValidationSettled(directory,sessionID,"council");await assertPrReviewValidationSettled(directory,sessionID,"reviewer");let criticInventory=derivePrReviewCriticInventory(directory,state);if(criticInventory.length>0){if(!(state.prReviewValidationBatches??[]).some((batch)=>batch.phase==="critic"))throw Error(`BLOCKED: PR_REVIEW reviewer verdicts require critic coverage for: ${criticInventory.join(", ")}`);await assertPrReviewValidationSettled(directory,sessionID,"critic")}let requiredBoundaries=["post_explorer","post_reviewer","post_critic"],persistedBoundaries=new Set(state.prReviewArtifactBoundaries??[]),missing=requiredBoundaries.filter((boundary)=>!persistedBoundaries.has(boundary));if(!state.prReviewFindingsPath||missing.length>0)throw Error(`BLOCKED: PR_REVIEW transition requires durable findings checkpoints; missing: ${missing.join(", ")||"findings path"}`);if(state.prReviewHandoffRequired&&!state.prReviewHandoffPath)throw Error("BLOCKED: PR_REVIEW actionable findings require a persisted feedback handoff artifact");return state}async function transitionPrReviewToFeedback(directory,sessionID,request){let normalizedSessionID=normalizeSessionID(sessionID),normalizedHandoff=normalizePrReviewFeedbackHandoffPath(request.handoffPath);if(!normalizedHandoff||normalizedHandoff.runId!==request.runId)throw Error("BLOCKED: PR-feedback continuation must use .swarm/pr-review/<run_id>/feedback-handoff.json");let preliminaryRead=await readPrReviewFeedbackHandoffArtifact(directory,normalizedHandoff.relativePath),artifact=preliminaryRead.artifact,artifactPr=canonicalGitHubPrUrl(artifact.pr_url),requestedPr=request.prUrl?canonicalGitHubPrUrl(request.prUrl):null;if(!artifactPr||request.prUrl&&requestedPr!==artifactPr)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact does not match the requested GitHub PR URL");if(artifact.run_id!==request.runId)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact does not match the requested review run");let preliminary=await readPrWorkflowGateState(directory,normalizedSessionID);if(preliminary?.mode==="PR_FEEDBACK")return assertSamePrFeedbackHandoff(preliminary,normalizedHandoff.relativePath,preliminaryRead,request.prUrl),preliminary;let sourceIdentity,sourceRevision=0,provenance;if(preliminary){if(preliminary.mode!=="PR_REVIEW")throw wrongModeError(preliminary,"PR_REVIEW");let ready=await assertPrReviewTerminalReady(directory,normalizedSessionID);if(workflowIdentity(ready)!==workflowIdentity(preliminary)||ready.revision!==preliminary.revision||ready.mode!=="PR_REVIEW"||ready.prReviewHandoffPath!==normalizedHandoff.relativePath||ready.prReviewArtifactRunId!==request.runId||!ready.prHeadSha||ready.prHeadSha.toLowerCase()!==artifact.pr_head_sha.toLowerCase()||canonicalGitHubPrUrl(artifact.pr_url)!==canonicalGitHubPrUrl(request.prUrl??artifact.pr_url))throw Error("BLOCKED: PR_REVIEW feedback handoff does not match the terminal active review state");let actionableIds=await readActionableReviewFindingIds(directory,ready,request.runId);if(!sameHandoffIds(actionableIds,artifact.finding_ids))throw Error("BLOCKED: PR_REVIEW feedback handoff finding IDs do not match the authoritative final findings ledger");sourceIdentity=workflowIdentity(ready),sourceRevision=ready.revision,provenance="active-review-v1"}else{if(!request.prUrl)throw Error("BLOCKED: continuing a completed PR_REVIEW requires an explicit GitHub PR URL");sourceIdentity=`external-${preliminaryRead.digest.slice(0,32)}`,provenance="external-v1"}return await _test_exports.beforePrFeedbackTransitionLock?.(),withSessionStateMutation(directory,normalizedSessionID,async()=>{let current=await readPrWorkflowGateStateFromDisk(directory,normalizedSessionID);if(current?.mode==="PR_FEEDBACK")return assertSamePrFeedbackHandoff(current,normalizedHandoff.relativePath,preliminaryRead,request.prUrl),current;if(provenance==="active-review-v1"){if(!current||current.mode!=="PR_REVIEW"||workflowIdentity(current)!==sourceIdentity||current.revision!==sourceRevision||current.prHeadSha?.toLowerCase()!==artifact.pr_head_sha.toLowerCase()||current.prReviewArtifactRunId!==request.runId||current.prReviewHandoffPath!==normalizedHandoff.relativePath)throw Error("BLOCKED: PR_REVIEW state changed while validating the feedback handoff; retry from current state")}else if(current)throw Error("BLOCKED: another PR workflow became active while validating the external handoff");let lockedRead=await readPrReviewFeedbackHandoffArtifact(directory,normalizedHandoff.relativePath);if(lockedRead.digest!==preliminaryRead.digest)throw Error("BLOCKED: PR_REVIEW feedback handoff artifact changed during transition");if(artifactPr!==canonicalGitHubPrUrl(lockedRead.artifact.pr_url)||lockedRead.artifact.run_id!==request.runId||lockedRead.artifact.pr_head_sha.toLowerCase()!==artifact.pr_head_sha.toLowerCase()||!sameHandoffIds(lockedRead.artifact.finding_ids,artifact.finding_ids))throw Error("BLOCKED: PR_REVIEW feedback handoff artifact changed during transition");let timestamp=isoNow(),nextState={schemaVersion:GATE_SCHEMA_VERSION,revision:sourceRevision,workflowInstanceId:randomUUID2(),sessionID:normalizedSessionID,mode:"PR_FEEDBACK",activatedAt:timestamp,updatedAt:timestamp,prFeedbackReviewHandoff:{path:normalizedHandoff.relativePath,runId:lockedRead.artifact.run_id,sourcePrHeadSha:lockedRead.artifact.pr_head_sha.toLowerCase(),prUrl:lockedRead.artifact.pr_url,findingIds:[...new Set(lockedRead.artifact.finding_ids)].sort(),digest:preliminaryRead.digest,sourceWorkflowInstanceId:sourceIdentity,provenance},prFeedbackTargetUrl:artifact.pr_url};return writeStateWhileLocked(directory,nextState,{replaceWorkflowInstanceId:provenance==="active-review-v1"?current?.workflowInstanceId:void 0})})}async function declarePrFeedbackScope(directory,sessionID,taskId,files){let state=await assertPrFeedbackVerificationSettled(directory,sessionID),revisionDigest=await currentPrFeedbackRevisionDigest(directory,state),previous=state.prFeedbackScopes??[];if(previous.find((entry)=>entry.taskId===taskId)?.consumedByCallId)throw Error(`SCOPE_NOT_DECLARED: PR-feedback scope ${taskId} was already consumed; use a fresh task_id for any retry`);let record2={taskId,files,revisionDigest,declaredAt:isoNow()},nextState={...state,updatedAt:isoNow(),prFeedbackScopes:[...previous.filter((entry)=>entry.taskId!==taskId),record2]};return await persistState(directory,nextState),nextState}async function resolvePrFeedbackScopeDeclaration(directory,sessionID,taskId){let state=await readPrWorkflowGateState(directory,sessionID);if(state?.mode!=="PR_FEEDBACK")return null;let declaration=(state.prFeedbackScopes??[]).find((entry)=>entry.taskId===taskId);if(!declaration)return null;return await assertPrFeedbackVerificationSettled(directory,sessionID),await currentPrFeedbackRevisionDigest(directory,state)===declaration.revisionDigest?declaration:null}async function consumePrFeedbackScopeDeclaration(directory,sessionID,taskId,callID){let declaration=await resolvePrFeedbackScopeDeclaration(directory,sessionID,taskId);if(!declaration)return null;if(declaration.consumedByCallId&&declaration.consumedByCallId!==callID)throw Error(`SCOPE_NOT_DECLARED: PR-feedback scope ${taskId} was already consumed by another Task call`);if(declaration.consumedByCallId===callID)return declaration;let state=await requireBoundState(directory,sessionID,"PR_FEEDBACK"),nextState={...state,updatedAt:isoNow(),prFeedbackScopes:(state.prFeedbackScopes??[]).map((entry)=>entry.taskId===taskId?{...entry,consumedByCallId:callID}:entry)};return await persistState(directory,nextState),{...declaration,consumedByCallId:callID}}async function validatePrFeedbackScopeBinding(directory,binding){if(!binding.workflowSessionId||!binding.workflowRevisionDigest)return!1;let declaration=await resolvePrFeedbackScopeDeclaration(directory,binding.workflowSessionId,binding.taskId);return Boolean(declaration&&declaration.consumedByCallId===binding.dispatchCallId&&declaration.revisionDigest===binding.workflowRevisionDigest&&JSON.stringify(declaration.files)===JSON.stringify(binding.files))}async function enforcePrWorkflowToolBefore(directory,sessionID,toolName,args2,generatedAgentNames=[]){let state=await readPrWorkflowGateState(directory,sessionID);if(!state)return;let normalizedTool=toolName.toLowerCase(),isDirectAgentTask=normalizedTool==="task"||normalizedTool==="run_agent",requestedRoles=["subagent_type","agent"].filter((field)=>Object.hasOwn(args2??{},field)).map((field)=>{let value=args2?.[field];if(typeof value!=="string"||!value.trim())return"";return resolveGeneratedAgentRole(value.trim(),generatedAgentNames)}),isDirectWrite=WRITE_TOOL_NAMES.includes(normalizedTool),command=typeof args2?.command==="string"?args2.command.trim():"",serializedArgs=JSON.stringify(args2??{}),referencesProtectedWorkflowEvidence=containsProtectedWorkflowPath(command||serializedArgs),isInternalWorkflowTool=isPrWorkflowControllerTool(state.mode,normalizedTool),isShellTool=normalizedTool==="bash"||normalizedTool==="shell",isReadOnlyShell=!1,shellPermissionEnvelope=null;if(isShellTool&&command.length>0){let trackingFetchTarget=state.prHeadSha?await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory):null;shellPermissionEnvelope={allowCheckout:!state.prHeadSha,allowFetch:!state.prHeadSha,allowTrackingFetch:Boolean(state.prHeadSha),trackingFetchTarget},isReadOnlyShell=isAllowedPrWorkflowReadOnlyShell(command,shellPermissionEnvelope)}let trustedCapability=getPrWorkflowToolCapability(normalizedTool,state.mode),isNamedReadOnlyTool=trustedCapability!==null&&isTrustedPrWorkflowToolInvocationSafe(normalizedTool,args2??{})||normalizedTool!=="build_check"&&isAllowedPrReviewReadOnlyToolName(normalizedTool)&&readOnlyToolArgumentsAreSafe(args2??{}),isRecoverySafeEvidenceTool=trustedCapability==="observe"&&isTrustedPrWorkflowToolInvocationSafe(normalizedTool,args2??{})||normalizedTool!=="build_check"&&isAllowedPrReviewReadOnlyToolName(normalizedTool)&&readOnlyToolArgumentsAreSafe(args2??{});if(state.checkoutRecovery){if(isRecoverySafeEvidenceTool||isReadOnlyShell||normalizedTool==="abort_pr_workflow"||normalizedTool==="pr_workflow_status"||normalizedTool==="prepare_pr_workflow_checkout")return;throw Error(`BLOCKED: ${state.mode} requires manual Git recovery before controller work can continue. code=${state.checkoutRecovery.code} retryable=false required_action=${state.checkoutRecovery.requiredAction}`)}if(referencesProtectedWorkflowEvidence&&!isInternalWorkflowTool&&!isNamedReadOnlyTool&&!isReadOnlyShell)throw Error(`BLOCKED: active ${state.mode} workflow evidence under .swarm is controller-owned and cannot be modified directly`);let isShellCommandRequiringVerification=isShellTool&&command.length>0&&!isReadOnlyShell,isRemoteReviewTool=/(?:git|github|pull|(?:^|[_-])pr(?:[_-]|$)|issue|review)/i.test(normalizedTool),hasRemoteMutationVerb=/(?:^|[_-])(?:add|approve|cancel|close|comment|commit|convert|create|delete|dismiss|edit|mark|merge|push|ready|reopen|rerun|resolve|submit|transfer|unresolve|update)(?:[_-]|$)/i.test(normalizedTool),hasRemoteReadVerb=/(?:^|[_-])(?:github|git)[_-]+(?:check|checks|checkout|diff|fetch|get|inspect|list|read|search|status|view)(?:[_-]|$)/i.test(normalizedTool)||/(?:^|[_-])(?:github|git)[_-]+(?:pull[_-]+request|pr|issue|review[_-]+thread)[_-]+(?:check|checks|checkout|diff|fetch|get|inspect|list|read|search|status|view)(?:[_-]|$)/i.test(normalizedTool),isRemoteMutationTool=isRemoteReviewTool&&(hasRemoteMutationVerb||!hasRemoteReadVerb),isRemoteCheckoutTool=/(?:^|[_-])(?:github|git)[_-]+checkout(?:[_-]|$)/i.test(normalizedTool),isShellCheckout=(normalizedTool==="bash"||normalizedTool==="shell")&&(/\bgit\b(?:(?![;&|]).){0,200}\b(?:checkout|switch)\b/i.test(command)||/\bgh\s+pr\s+checkout\b/i.test(command)),stderrMergeNormalizedCommand=command.replace(PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN,"").trim(),isCanonicalReviewCheckout=/^git\s+switch\s+--detach\s+[0-9a-f]{40,64}$/i.test(stderrMergeNormalizedCommand),detachedFeedbackSwitchMatch=command.match(/^git\s+switch\s+--detach\s+(\S+)$/i),isDetachedFeedbackCheckout=Boolean(detachedFeedbackSwitchMatch?.[1]&&isSafeGitRefToken(detachedFeedbackSwitchMatch[1]))||/^gh\s+pr\s+checkout\b.*\s--detach(?:\s|$)/i.test(command),containsGitCommitShell=isShellCommandRequiringVerification&&/\bgit\b(?:(?![;&|]).){0,200}\bcommit\b/i.test(command),isStandaloneGitCommitShell=containsGitCommitShell&&isSafeStandaloneGitCommit(command),isPublicationShell=isShellCommandRequiringVerification&&(/\bgit\b(?:(?![;&|]).){0,200}\bpush\b/i.test(command)||/\bgh\s+(?:api|pr|issue|run)\b/i.test(command)),isPublicationTool=!isInternalWorkflowTool&&isRemoteMutationTool,isCoderTask=isDirectAgentTask&&requestedRoles.length>0&&requestedRoles.every((role)=>role==="coder"),blockedShellDiagnosis=isShellTool&&command&&!isReadOnlyShell&&shellPermissionEnvelope?` ${describeBlockedPrReviewShellCommand(command,shellPermissionEnvelope)}`:"";if(state.mode==="PR_REVIEW"){if(!(isInternalWorkflowTool||isNamedReadOnlyTool||isReadOnlyShell&&(!isShellCheckout||isCanonicalReviewCheckout))||Boolean(state.prHeadSha)&&(isRemoteCheckoutTool||isShellCheckout)){if(!state.prHeadSha&&isShellCheckout)throw Error("BLOCKED: PR_REVIEW checkout must use standalone commands: fetch the PR head, verify the full commit object with `git cat-file -e <full_pr_head_sha>^{commit}`, then run `git switch --detach <full_pr_head_sha>` and bind that exact head before dispatching explorer lanes. Do not use `--track FETCH_HEAD`."+blockedShellDiagnosis);throw Error("BLOCKED: PR_REVIEW is read-only and fail-closed; only controller tools and positively classified observation tools are allowed, and every agent lane requires structured dispatch_lanes_async"+describePrWorkflowControllerToolNames(state.mode)+blockedShellDiagnosis)}return}if(isDirectAgentTask&&!isCoderTask)throw Error("BLOCKED: PR_FEEDBACK reviewer, test, critic, explorer, and unknown agent lanes require structured dispatch_lanes_async provenance");if(!isInternalWorkflowTool&&!isDirectAgentTask&&!isDirectWrite&&!isShellTool&&!isNamedReadOnlyTool)throw Error("BLOCKED: PR_FEEDBACK rejects unclassified plugin/MCP tools; use positively classified observation tools, built-in structured write tools after verification, or the workflow controller"+describePrWorkflowControllerToolNames(state.mode));if(state.prHeadSha&&(isShellCheckout||isRemoteCheckoutTool))throw Error("BLOCKED: PR_FEEDBACK checkout is immutable after exact PR head binding");if(containsGitCommitShell&&state.prFeedbackReadyToPublish)throw Error("BLOCKED: PR_FEEDBACK is armed for publication; the approved commit is immutable");if((containsGitCommitShell||isPublicationShell)&&hasUnsafeShellControlSyntax(command))throw Error("BLOCKED: PR_FEEDBACK publication commands must be standalone shell commands without control, redirection, or command-substitution syntax");if(containsGitCommitShell&&!isStandaloneGitCommitShell)throw Error("BLOCKED: PR_FEEDBACK commit must use a standalone git commit command after every ordered local gate passes");if(state.prFeedbackReadyToPublish){if(normalizedTool==="complete_pr_workflow")return;if(isNamedReadOnlyTool)return;if((normalizedTool==="bash"||normalizedTool==="shell")&&command.length>0&&isAllowedPrWorkflowReadOnlyShell(command,{allowCheckout:!1,allowFetch:!1,allowTrackingFetch:!1}))return;if(normalizedTool==="bash"||normalizedTool==="shell"){let armed=(await assertPrFeedbackPublicationArmed(directory,sessionID)).prFeedbackReadyToPublish;if(isSafeExactBoundPush(command,armed))return;throw Error(`BLOCKED: PR_FEEDBACK is armed for publication; only the exact approved push is allowed: ${expectedBoundPushCommand(armed)}`)}throw Error("BLOCKED: PR_FEEDBACK is armed for publication; only read-only inspection, the exact approved push, and complete_pr_workflow are allowed")}if(!state.prHeadSha&&normalizedTool==="prepare_pr_workflow_checkout")return;if(!state.prHeadSha&&isDetachedFeedbackCheckout&&!isCanonicalReviewCheckout)throw Error("BLOCKED: PR_FEEDBACK checkout should use one exact local tracking branch, such as `gh pr checkout <number> --branch <local_branch>` or `git switch -c <local_branch> --track <remote>/<branch>`, before binding. If checkout is already detached at the authoritative full PR head SHA, bind it directly; the controller attaches one unambiguous exact tracking ref. Other detached refs are not accepted");if(!state.prHeadSha&&isCanonicalReviewCheckout)return;if(isStandaloneGitCommitShell){await assertPrFeedbackReadyToPublish(directory,sessionID);return}if(isPublicationShell||isPublicationTool)throw Error("BLOCKED: PR_FEEDBACK publication is not armed; finish every ordered gate, create the one approved commit, and call complete_pr_workflow before publishing");if(isShellCommandRequiringVerification){if(!state.prHeadSha&&isShellCheckout)throw Error("BLOCKED: PR_FEEDBACK checkout should use one exact local tracking branch, such as `gh pr checkout <number> --branch <local_branch>` or `git switch -c <local_branch> --track <remote>/<branch>`, before binding. If checkout is already detached at the authoritative full PR head SHA, bind it directly; the controller attaches one unambiguous exact tracking ref");throw Error("BLOCKED: PR_FEEDBACK shell commands fail closed unless they are explicit read-only intake or the one standalone approved git commit; use structured coder/write tools for fixes and run_pr_feedback_stage_a for validation")}if(!isDirectWrite&&!isShellCommandRequiringVerification&&!isRemoteMutationTool&&!isCoderTask&&normalizedTool!=="prepare_pr_feedback_scope")return;if(normalizedTool==="abort_pr_workflow")return;await assertPrFeedbackVerificationSettled(directory,sessionID)}async function completePrWorkflow(directory,sessionID,expectedMode,prHeadSha){let state=await requireBoundState(directory,sessionID,expectedMode),normalizedHead=normalizePrHeadSha(prHeadSha);if(state.prHeadSha!==normalizedHead)throw Error(`BLOCKED: cannot complete ${expectedMode} at PR head "${normalizedHead}"; workflow is bound to "${state.prHeadSha}"`);let open3=readDelegations(directory).filter((record2)=>record2.parentSessionId===state.sessionID&&record2.mode?.startsWith("swarm-pr-")&&(record2.status==="pending"||record2.status==="running"));if(open3.length>0)throw Error(`BLOCKED: ${expectedMode} completion has ${open3.length} unsettled PR workflow lane(s)`);if(expectedMode==="PR_REVIEW"){let readyState=await assertPrReviewTerminalReady(directory,sessionID);if(workflowIdentity(readyState)!==workflowIdentity(state)||readyState.revision!==state.revision)throw Error("BLOCKED: PR_REVIEW state changed while checking terminal readiness; retry from current state")}else{let readyState=await assertPrFeedbackReadyToPublish(directory,sessionID),currentDigest=await currentPrFeedbackRevisionDigest(directory,readyState),armed=readyState.prFeedbackReadyToPublish;if(!armed){let localHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim();if(!localHead)throw Error("BLOCKED: PR_FEEDBACK cannot arm publication without a verified local Git HEAD");if(await _test_exports.resolveCommitCountSinceAsync(directory,state.prHeadSha,localHead)!==1)throw Error("BLOCKED: PR_FEEDBACK publication requires exactly one descendant commit after the immutable intake head");if(await _test_exports.resolveIsExactSingleChildCommitAsync(directory,state.prHeadSha,localHead)!==!0)throw Error("BLOCKED: PR_FEEDBACK publication commit must be a non-merge direct child of the immutable intake head");if(await _test_exports.resolveIsWorkingTreeCleanAsync(directory)!==!0)throw Error("BLOCKED: PR_FEEDBACK publication requires a clean index and working tree so all approved content is captured by the bound commit");let upstreamTarget=await _test_exports.resolveCurrentUpstreamPushTargetAsync(directory);if(!upstreamTarget)throw Error("BLOCKED: PR_FEEDBACK cannot arm publication without a current branch bound to an exact remote name, remote branch ref, and remote-tracking ref");return await persistState(directory,{...readyState,updatedAt:isoNow(),prFeedbackReadyToPublish:{revisionDigest:currentDigest,localHead,remoteName:upstreamTarget.remoteName,remoteBranchRef:upstreamTarget.remoteBranchRef,remoteRef:upstreamTarget.remoteTrackingRef,validatedAt:isoNow()}}),"ready-to-publish"}if(armed.revisionDigest!==currentDigest)throw Error("BLOCKED: PR_FEEDBACK publication revision differs from the independently approved content digest");let publishedHead=(await _test_exports.resolveCurrentGitHeadAsync(directory))?.trim(),remoteRefs=publishedHead?await _test_exports.resolveRemoteRefsContainingHeadAsync(directory,publishedHead):null,remoteHead=await _test_exports.resolveExactRemoteBranchHeadAsync(directory,armed.remoteName,armed.remoteBranchRef);if(!publishedHead||publishedHead!==armed.localHead||!remoteRefs?.includes(armed.remoteRef)||remoteHead?.toLowerCase()!==armed.localHead.toLowerCase())throw Error(`BLOCKED: PR_FEEDBACK completion requires approved commit ${armed.localHead} at current Git HEAD and intended remote-tracking ref ${armed.remoteRef} at that exact commit`)}return await _test_exports.beforeTerminalClear?.(),await clearPrWorkflowGateState(directory,sessionID,state.revision),"completed"}async function requireAnyActiveState(directory,sessionID){let state=await readPrWorkflowGateState(directory,sessionID);if(!state)throw Error(`BLOCKED: no active PR workflow gate for session "${normalizeSessionID(sessionID)}". The gate is activated by running \`/swarm pr-review <pr-ref>\` (PR_REVIEW) or \`/swarm pr-feedback <pr-ref>\` (PR_FEEDBACK), or by the first dispatch_lanes_async call with mode "swarm-pr-review:*" / "swarm-pr-feedback:*".`);return state}async function requireBoundState(directory,sessionID,expectedMode){let state=await requireAnyActiveState(directory,sessionID);if(state.mode!==expectedMode)throw wrongModeError(state,expectedMode);if(!state.prHeadSha)throw Error(`BLOCKED: active ${expectedMode} workflow is not bound to a PR head`);if(expectedMode==="PR_REVIEW")await assertCurrentCheckoutHead(directory,state.prHeadSha,"PR_REVIEW"),await assertPrReviewCleanCheckout(directory);return state}function wrongModeError(state,expectedMode){return Error(`BLOCKED: session "${state.sessionID}" is active in ${state.mode}, not ${expectedMode}`)}function normalizeWorkflowLanes(lanes){if(!Array.isArray(lanes)||lanes.length===0)throw Error("BLOCKED: PR workflow lane validation requires at least one lane");let normalized=lanes.map((lane)=>{let workflowLane=lane.workflowLane?.trim(),laneId=lane.laneId?.trim()||workflowLane;if(!workflowLane||!laneId)throw Error("BLOCKED: PR workflow lane validation requires every lane to have non-empty laneId and workflow_lane values");let reviewItemIds=lane.reviewItemIds?.map((itemId)=>itemId.trim());if(reviewItemIds?.some((itemId)=>!itemId))throw Error("BLOCKED: PR workflow review_item_ids must not contain empty values");if(reviewItemIds)assertNoDuplicates(reviewItemIds,"review item ids within one lane");let ownedWorkflowLanes=lane.ownedWorkflowLanes?.map((owned)=>owned.trim());if(ownedWorkflowLanes){if(ownedWorkflowLanes.some((owned)=>!owned))throw Error("BLOCKED: PR workflow owned_workflow_lanes must not contain empty values");if(assertNoDuplicates(ownedWorkflowLanes,"owned workflow lanes within one lane"),!ownedWorkflowLanes.includes(workflowLane))throw Error(`BLOCKED: PR workflow lane "${laneId}" must include its own workflow_lane "${workflowLane}" in owned_workflow_lanes`)}return{laneId,workflowLane,...reviewItemIds?{reviewItemIds}:{},...ownedWorkflowLanes?{ownedWorkflowLanes}:{}}});return assertNoDuplicates(normalized.map((lane)=>lane.laneId),"lane ids"),assertNoDuplicates(normalized.map((lane)=>lane.workflowLane),"workflow lane ids"),assertNoDuplicates(normalized.flatMap((lane)=>lane.ownedWorkflowLanes??[lane.workflowLane]),"owned workflow lane ids across lanes"),normalized}function normalizeInventoryIds(inventoryIds){if(!Array.isArray(inventoryIds)||inventoryIds.length===0)throw Error("BLOCKED: PR_FEEDBACK inventory declaration requires at least one feedback item id");let normalized=inventoryIds.map((inventoryId)=>{let itemId=inventoryId.trim();if(!itemId)throw Error("BLOCKED: PR_FEEDBACK inventory declaration contains an empty item id");return itemId});return assertNoDuplicates(normalized,"inventory item ids"),normalized.sort()}function normalizeOwnership(ownership){if(!Array.isArray(ownership)||ownership.length===0)throw Error("BLOCKED: PR_FEEDBACK verification ownership requires at least one lane declaration");let normalized=ownership.map((lane)=>{let laneId=lane.laneId?.trim();if(!laneId)throw Error("BLOCKED: PR_FEEDBACK verification ownership requires every lane to have a non-empty laneId");let ownedItemIds=normalizeInventoryIds(lane.ownedItemIds);return{laneId,ownedItemIds}});return assertNoDuplicates(normalized.map((lane)=>lane.laneId),"PR_FEEDBACK verification lane ids"),normalized}function assertNoDuplicates(values,label){let seen=new Set;for(let value of values){if(seen.has(value))throw Error(`BLOCKED: duplicate ${label} are not allowed: ${value}`);seen.add(value)}}function containsProtectedWorkflowPath(value){return/(?:^|[^A-Za-z0-9_.-])\.swarm(?:[\\/]|$)/i.test(value.replace(/\\\\/g,"\\"))}function isPrWorkflowControllerTool(mode,toolName){if(PR_WORKFLOW_SHARED_CONTROLLER_TOOLS.has(toolName))return!0;return mode==="PR_REVIEW"?PR_REVIEW_CONTROLLER_TOOLS.has(toolName):PR_FEEDBACK_CONTROLLER_TOOLS.has(toolName)}function describePrWorkflowControllerToolNames(mode){let modeTools=mode==="PR_REVIEW"?PR_REVIEW_CONTROLLER_TOOLS:PR_FEEDBACK_CONTROLLER_TOOLS,names=[...PR_WORKFLOW_SHARED_CONTROLLER_TOOLS,...modeTools].sort((a,b)=>a.localeCompare(b));return` Allowed controller tools for ${mode}: ${names.join(", ")}. Observe current state read-only with the pr_workflow_status tool.`}function isTrustedPrWorkflowToolInvocationSafe(toolName,args2){if(toolName==="lint")return args2.mode==="check";if(toolName==="sast_scan")return args2.capture_baseline!==!0;return!0}function isAllowedPrReviewReadOnlyToolName(toolName){if(PR_REVIEW_READ_ONLY_TOOL_NAMES.has(toolName))return!0;let tokens=toolName.split(/[._:/-]+/).filter(Boolean);if(tokens.some((token)=>/^(?:add|alter|and|append|apply|approve|cancel|checkout|close|comment|commit|convert|create|delete|destroy|dismiss|drop|edit|execute|grant|insert|mark|merge|move|patch|prepend|publish|push|ready|remove|rename|replace|resolve|rerun|revoke|run|send|submit|then|transfer|truncate|unresolve|update|upload|write)$/i.test(token)))return!1;return tokens.some((token)=>/^(?:check|checks|diff|fetch|find|get|glob|grep|hover|inspect|list|lookup|open|read|references|scan|screenshot|search|show|status|symbols|tree|view)$/i.test(token))}function readOnlyToolArgumentsAreSafe(value,key="",depth=0){if(depth>8)return!1;let keyTokens=key.replace(/([a-z0-9])([A-Z])/g,"$1_$2").split(/[._:/-]+/).filter(Boolean);if(keyTokens.some((token)=>/^(?:append|body|content|create|data|delete|destination|destroy|edit|insert|mutation|output|patch|payload|prepend|remove|replace|save|set|truncate|update|upload|write)$/i.test(token)))return!1;if(keyTokens.some((token)=>/^(?:method|verb)$/i.test(token)))return typeof value==="string"&&/^(?:GET|HEAD)$/i.test(value.trim());if(keyTokens.length===1&&keyTokens.some((token)=>/^(?:action|operation)$/i.test(token)))return typeof value==="string"&&/^(?:check|diff|fetch|find|get|inspect|list|lookup|open|read|scan|search|show|status|view)$/i.test(value.trim());if(/^mode$/i.test(key)&&typeof value==="string")return/^(?:r|rb|read)$/i.test(value.trim());if(typeof value==="string"){if(keyTokens.some((token)=>/^(?:query|request|sql|statement)$/i.test(token))&&/(?:\b(?:alter|call|comment|create|delete|drop|exec(?:ute)?|grant|insert|merge|mutation|replace|revoke|truncate|update|upsert)\b|\bselect\b[\s\S]{0,4000}\binto\s+[A-Za-z_"'`])/i.test(value))return!1;return!/(?:^(?:POST|PUT|PATCH|DELETE|CONNECT|TRACE|write|edit|patch|create|delete|destroy|remove|replace|truncate|update|upload)$|(?:^|[\r\n])\s*(?:POST|PUT|PATCH|DELETE|CONNECT|TRACE)\s+\S+(?:\s+HTTP\/\d(?:\.\d)?)?|\bmutation\b|\b(?:create|drop|alter|truncate)\s+(?:or\s+replace\s+)?(?:table|database|schema|index|view|function|procedure|trigger|sequence)\b|\b(?:delete\s+from|insert\s+into|merge\s+into|replace\s+into|upsert\s+into)\b|\bupdate\s+[A-Za-z0-9_."'`-]+(?:\s+(?:AS\s+)?[A-Za-z0-9_"'`-]+)?\s+set\b|\b(?:grant|revoke)\s+\S+\s+(?:on|from|to)\b|\b(?:call|exec(?:ute)?)\s+[A-Za-z0-9_."'`-]+|\b(?:rm|rmdir|del|remove-item|move-item|set-content|add-content)\b)/i.test(value)}if(value===null||value===void 0||typeof value==="number"||typeof value==="boolean")return!0;if(Array.isArray(value))return value.every((entry)=>readOnlyToolArgumentsAreSafe(entry,key,depth+1));if(typeof value==="object")return Object.entries(value).every(([childKey,childValue])=>readOnlyToolArgumentsAreSafe(childValue,childKey,depth+1));return!1}function normalizePrWorkflowShellCommand(command){let normalized=command.trim(),withoutTrailingMerge=normalized.replace(PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN,"");if(withoutTrailingMerge!==normalized)normalized=withoutTrailingMerge.trim();let strippedCdPrefix=!1;for(let index=0;index<PR_WORKFLOW_MAX_CD_PREFIX_STRIPS;index+=1){let next=normalized.replace(PR_WORKFLOW_CD_PREFIX_PATTERN,"");if(next===normalized)break;normalized=next.trim(),strippedCdPrefix=!0}return{normalized,strippedCdPrefix}}function isAllowedPrWorkflowReadOnlyShell(command,options){let{normalized:inner,strippedCdPrefix}=normalizePrWorkflowShellCommand(command),normalized=inner.replace(/\s+/g," ");if(!normalized)return!1;if(/[\r\n;&|<>`]/.test(inner)||/\$\(|@\(/.test(inner))return!1;if(strippedCdPrefix&&(/^git (?:fetch|checkout|switch|branch)(?:\s|$)/i.test(normalized)||/^gh pr checkout(?:\s|$)/i.test(normalized)))return!1;let gitMatch=normalized.match(PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN);if(gitMatch?.[1]){if(PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN.test(normalized)&&/^(?:fetch|checkout|switch|branch)(?:\s|$)/i.test(gitMatch[1]))return!1;return isAllowedPrWorkflowGitIntake(gitMatch[1],options)}if(/^gh /i.test(normalized))return isAllowedPrFeedbackGhIntake(normalized);if(/^rg\b/i.test(normalized)&&/\s--pre(?:-glob)?(?:\s|=|$)/i.test(normalized))return!1;return/^(?:rg|grep|cat|Get-Content|Select-String|Test-Path|Get-ChildItem|ls|dir|pwd|which|where)(?:\s|$)/i.test(normalized)}function describeBlockedPrReviewShellCommand(command,options){let{normalized:inner,strippedCdPrefix}=normalizePrWorkflowShellCommand(command),normalized=inner.replace(/\s+/g," "),gitMatch=normalized.match(PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN),pointer=" Observe HEAD/branch/dirty/remotes/gate state read-only with the pr_workflow_status tool.",detail;if(/[\r\n;&|<>`]/.test(inner)||/\$\(|@\(/.test(inner))detail="Reason: compound-syntax (;, &&, |, <, >, backtick, or $()/@()). Run ONE command per call; a single leading `cd <dir> &&` and a trailing `2>&1` are tolerated for reads only.";else if(strippedCdPrefix&&(/^git (?:fetch|checkout|switch|branch)(?:\s|$)/i.test(normalized)||/^gh pr checkout(?:\s|$)/i.test(normalized)))detail="Reason: cd-prefix-on-checkout-verb. Run fetch/checkout/switch/branch or `gh pr checkout` bare, with no `cd <dir> &&` prefix.";else if(PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN.test(normalized)&&gitMatch?.[1]&&/^(?:fetch|checkout|switch|branch)(?:\s|$)/i.test(gitMatch[1]))detail="Reason: git -C on a state transition. Run fetch/checkout/switch/branch from the target directory, not via `git -C <dir>`.";else if(!options.allowFetch&&gitMatch?.[1]&&/^fetch(?:\s|$)/i.test(gitMatch[1]))detail=options.allowTrackingFetch?"Reason: bound-fetch-restriction. After the PR head is bound only the exact bound remote-tracking fetch is allowed; read remote state via gh_evidence otherwise.":"Reason: bound-fetch-restriction. Fetch is not permitted in this bound state; read remote state via gh_evidence instead.";else if(gitMatch?.[1]||/^git(?:\s|$)/i.test(normalized))detail="Reason: unlisted git verb. Allowed git reads: status/log/show/diff/rev-parse/merge-base/ls-files/grep/blame/cat-file/for-each-ref, `branch` with listing flags only, `stash list`, `worktree list`, `remote -v`, `config --get`.";else if(/^gh(?:\s|$)/i.test(normalized))detail="Reason: unlisted gh form. Allowed gh reads: pr view/diff/checks/status/list, run view/list/watch, issue view/list, search, api GET. If gh is missing, fetch the api.github.com REST URL with the web fetch tool.";else detail="Reason: unlisted binary. Allowed: rg/grep/cat/ls/dir/pwd/which/where plus read-only git/gh intake.";return detail+" Observe HEAD/branch/dirty/remotes/gate state read-only with the pr_workflow_status tool."}function hasUnsafeShellControlSyntax(command){return/[;&|<>`\r\n]/.test(command)||/\$\(/.test(command)}function isSafeStandaloneGitCommit(command){if(hasUnsafeShellControlSyntax(command))return!1;if(/(?:^|\s)--(?:allow-empty|amend)(?:\s|=|$)/i.test(command))return!1;return/^[Gg][Ii][Tt](?:\s+-C(?:=|\s+)(?:"[^"\r\n]+"|'[^'\r\n]+'|[^\s;&|<>`]+))?\s+commit(?:\s+(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s;&|<>`]+))*\s*$/.test(command.trim())}function boundPushTarget(armed){let remote=armed.remoteName,branch=armed.remoteBranchRef.slice(11);if(!armed.remoteBranchRef.startsWith("refs/heads/")||!branch)return null;if(/\s|[;&|<>`]/.test(remote)||/\s|[;&|<>`]/.test(branch))return null;return{remote,branch}}function expectedBoundPushCommand(armed){let target=boundPushTarget(armed);return target?`git push ${target.remote} ${armed.localHead}:refs/heads/${target.branch}`:"(invalid bound remote-tracking ref; restart the workflow)"}function isSafeExactBoundPush(command,armed){if(hasUnsafeShellControlSyntax(command))return!1;let target=boundPushTarget(armed);if(!target)return!1;let match=command.trim().match(/^git\s+push\s+([^\s;&|<>`]+)\s+([^\s;&|<>`]+)\s*$/i);if(!match)return!1;return match[1]===target.remote&&match[2]===`${armed.localHead}:refs/heads/${target.branch}`}function isAllowedPrWorkflowGitIntake(gitArgs,options){if(/(?:--ext-diff|--textconv|--open-files-in-pager|--output(?:=|\s)|--upload-pack(?:=|\s)|--exec(?:=|\s))/i.test(gitArgs))return!1;if(/^(?:status|log|show|diff|rev-parse|merge-base|ls-files|grep|blame|cat-file|for-each-ref|--version|version)(?:\s|$)/i.test(gitArgs))return!0;if(isAllowedReadOnlyGitBranchListing(gitArgs))return!0;if(isAllowedReadOnlyGitStashListing(gitArgs))return!0;if(isAllowedReadOnlyGitWorktreeListing(gitArgs))return!0;if(options.allowFetch&&/^fetch(?:\s|$)/i.test(gitArgs))return!0;if(options.allowTrackingFetch&&isAllowedBoundRemoteTrackingFetch(gitArgs,options.trackingFetchTarget))return!0;if(/^remote(?:\s+-v)?$/i.test(gitArgs))return!0;if(options.allowCheckout&&isAllowedPreBindBranchSetup(gitArgs))return!0;if(options.allowCheckout&&/^(?:checkout|switch)\s+(?:--detach\s+)?[^\s-][^\s]*$/i.test(gitArgs))return!0;return/^config\s+(?:(?:--show-origin|--show-scope|--global|--local|--system|--worktree)\s+)*(?:--list|--get(?:-all)?\s+\S+)$/i.test(gitArgs)}function isAllowedBoundRemoteTrackingFetch(gitArgs,target){if(!target?.remoteName||!target.remoteBranchRef.startsWith("refs/heads/"))return!1;let tokens=gitArgs.trim().split(/\s+/);if(tokens.length!==3||tokens[0].toLowerCase()!=="fetch")return!1;let[,remote,remoteBranch]=tokens,expectedBranch=target.remoteBranchRef.slice(11);return isSafeGitRefToken(remote)&&!remote.includes("/")&&isSafeGitRefToken(remoteBranch)&&!remoteBranch.startsWith("-")&&!remoteBranch.includes(":")&&remote===target.remoteName&&remoteBranch===expectedBranch}function isAllowedPreBindBranchSetup(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length===5){let[verb,createFlag,localBranch,trackFlag,upstream]=tokens;return(verb==="checkout"||verb==="switch")&&(createFlag==="-b"||createFlag==="-c")&&trackFlag==="--track"&&isSafeGitRefToken(localBranch)&&isSafeGitRefToken(upstream)&&upstream.includes("/")}if(tokens.length===3&&tokens[0]==="branch"){let upstream=tokens[1].match(/^--set-upstream-to=(.+)$/)?.[1];return Boolean(upstream&&isSafeGitRefToken(upstream)&&upstream.includes("/")&&isSafeGitRefToken(tokens[2]))}return!1}function isAllowedReadOnlyGitBranchListing(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length===0||tokens[0].toLowerCase()!=="branch")return!1;let listingSelectorInEffect=!1;for(let index=1;index<tokens.length;index+=1){let token=tokens[index];if(/^(?:--list|--contains|--merged|--no-merged|--points-at)$/i.test(token)){listingSelectorInEffect=!0;continue}if(/^(?:-a|--all|-r|--remotes|-v|-vv|--verbose|--show-current|--color|--no-color|--column|--no-column|-i|--ignore-case)$/i.test(token)||/^--(?:sort|format|color)=/i.test(token))continue;if(token.startsWith("-"))return!1;if(!listingSelectorInEffect)return!1}return!0}function isAllowedReadOnlyGitStashListing(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length<2||tokens[0].toLowerCase()!=="stash")return!1;if(tokens[1].toLowerCase()!=="list")return!1;for(let index=2;index<tokens.length;index+=1){let token=tokens[index];if(/^(?:-v|--oneline|--patch|-p|--stat|--color|--no-color)$/i.test(token))continue;if(/^--(?:format|pretty)=/i.test(token))continue;return!1}return!0}function isAllowedReadOnlyGitWorktreeListing(gitArgs){let tokens=gitArgs.trim().split(/\s+/);if(tokens.length<2||tokens[0].toLowerCase()!=="worktree")return!1;if(tokens[1].toLowerCase()!=="list")return!1;for(let index=2;index<tokens.length;index+=1){let token=tokens[index];if(/^(?:-v|--verbose|--porcelain|-z)$/i.test(token))continue;return!1}return!0}function isSafeGitRefToken(value){return/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(value)&&!value.includes("..")&&!value.includes("//")&&!value.includes("@{")&&!value.endsWith("/")&&!value.endsWith(".")&&!value.endsWith(".lock")}function isAllowedPrFeedbackGhIntake(command){if(/^gh\s+pr\s+checkout(?:\s|$)/i.test(command))return isAllowedSafeGhPrCheckout(command);if(/^gh\s+--version$/i.test(command)||/^gh\s+pr\s+(?:view|diff|checks|status|list)(?:\s|$)/i.test(command)||/^gh\s+run\s+(?:view|list|watch)(?:\s|$)/i.test(command)||/^gh\s+issue\s+(?:view|list)(?:\s|$)/i.test(command)||/^gh\s+search\s+(?:code|commits|issues|prs|repos)(?:\s|$)/i.test(command)||/^gh\s+auth\s+status(?:\s|$)/i.test(command))return!0;if(!/^gh\s+api(?:\s|$)/i.test(command))return!1;if(/\bmutation\b/i.test(command))return!1;let method=command.match(/\s(?:--method(?:\s+|=)|-X(?:\s+|=)?)([A-Z]+)/i)?.[1];if(method&&method.toUpperCase()!=="GET")return!1;if(/\s(?:--input|--raw-field)(?:\s|=)/i.test(command)||/\s-F(?:\s|=|\S)/.test(command))return!1;return!/\s(?:--field|-f)(?:\s|=)(?!query=)/i.test(command)}function isAllowedSafeGhPrCheckout(command){if(/\s--(?:force|recurse-submodules)(?:\s|=|$)/i.test(command))return!1;let tokens=command.trim().split(/\s+/);if(tokens.length<4||tokens[0]!=="gh"||tokens[1]!=="pr"||tokens[2]!=="checkout")return!1;let target=tokens[3];if(!/^\d+$/.test(target)&&!/^https:\/\/github\.com\/[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+\/pull\/\d+$/.test(target))return!1;for(let index=4;index<tokens.length;index+=1){let token=tokens[index],repoEquals=token.match(/^--repo=(.+)$/)?.[1];if(repoEquals){if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repoEquals))return!1;continue}let branchEquals=token.match(/^--branch=(.+)$/)?.[1];if(branchEquals){if(!isSafeGitRefToken(branchEquals))return!1;continue}if(token==="--repo"||token==="-R"){let repo=tokens[++index];if(!repo||!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repo))return!1;continue}if(token==="--branch"||token==="-b"){let branch=tokens[++index];if(!branch||!isSafeGitRefToken(branch))return!1;continue}return!1}return!0}function normalizePrHeadSha(prHeadSha){let normalized=prHeadSha.trim();if(!normalized)throw Error("BLOCKED: PR workflow requires a non-empty pr_head_sha");return normalized}async function currentPrFeedbackRevisionDigest(directory,state){if(!state.prHeadSha)throw Error("BLOCKED: PR_FEEDBACK revision binding requires pr_head_sha");let digest2=await resolvePrWorkflowRevisionDigestForGate(directory,state.prHeadSha);if(!digest2)throw Error("BLOCKED: PR_FEEDBACK could not compute a bounded current-revision digest");return digest2}async function resolvePrWorkflowRevisionDigestForGate(directory,baseHeadSha){if(_test_exports.resolvePrWorkflowRevisionDigest!==resolvePrWorkflowRevisionDigest)return _test_exports.resolvePrWorkflowRevisionDigest(directory,baseHeadSha);return resolvePrWorkflowRevisionDigestAsync(directory,baseHeadSha)}function normalizeBatchId(batchId){let normalized=batchId.trim();if(!normalized)throw Error("BLOCKED: PR workflow requires a non-empty batch id");return normalized}function sameStringArray(left,right){return left.length===right.length&&left.every((value,index)=>value===right[index])}function assertExactStringSet(actual,expected,label){let actualSet=new Set(actual),expectedSet=new Set(expected),missing=[...expectedSet].filter((value)=>!actualSet.has(value)),extra=[...actualSet].filter((value)=>!expectedSet.has(value));if(actual.length!==actualSet.size||actualSet.size!==expectedSet.size||missing.length>0||extra.length>0)throw Error(`BLOCKED: ${label} must exactly cover the mechanically derived inventory; missing: ${missing.join(", ")||"(none)"}; extra: ${extra.join(", ")||"(none)"}`)}function derivePrReviewCandidateInventory(directory,state){let sources=[],baseDimensionSources=new Map,baseSourceCreditedDimensions=new Map,baseSourceFullOwnershipCount=new Map;for(let batch of[...state.prReviewBaseDispatches??[]].reverse()){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:base",batch.validatedAt);for(let lane of batch.lanes){let ownedDimensions=lane.ownedWorkflowLanes?.length?lane.ownedWorkflowLanes:[lane.workflowLane];if(!ownedDimensions.every((dimension)=>successful.has(dimension)))continue;let key=`${batch.batchId}\x00${lane.laneId}`;baseSourceFullOwnershipCount.set(key,ownedDimensions.length);for(let dimension of ownedDimensions)if(!baseDimensionSources.has(dimension)){baseDimensionSources.set(dimension,{batchId:batch.batchId,laneId:lane.laneId});let credited=baseSourceCreditedDimensions.get(key);if(credited)credited.push(dimension);else baseSourceCreditedDimensions.set(key,[dimension])}}}let seenBaseSourceKeys=new Set;for(let{batchId,laneId}of baseDimensionSources.values()){let key=`${batchId}\x00${laneId}`;if(seenBaseSourceKeys.has(key))continue;seenBaseSourceKeys.add(key);let credited=baseSourceCreditedDimensions.get(key),fullOwnershipCount=baseSourceFullOwnershipCount.get(key)??0;sources.push({batchId,laneId,mode:"swarm-pr-review:base",creditedLanes:credited&&credited.length<fullOwnershipCount?credited:void 0})}let selectedCouncilLanes=new Set;for(let batch of[...state.prReviewValidationBatches??[]].reverse()){if(batch.phase!=="council")continue;let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:council",batch.validatedAt);for(let lane of batch.lanes)if(successful.has(lane.workflowLane)&&!selectedCouncilLanes.has(lane.workflowLane))sources.push({batchId:batch.batchId,laneId:lane.laneId,mode:"swarm-pr-review:council"}),selectedCouncilLanes.add(lane.workflowLane)}if(state.prReviewTriggerEvalPath){let triggerPath=validateSwarmPath(directory,state.prReviewTriggerEvalPath),triggerArtifact;try{triggerArtifact=JSON.parse(readFileSync6(triggerPath,"utf-8"))}catch{throw Error("BLOCKED: PR_REVIEW trigger evaluation artifact is missing or invalid")}let receipt;try{receipt=parsePrReviewTriggerReceipt(triggerArtifact)}catch(error49){throw Error(`BLOCKED: PR_REVIEW trigger evaluation is invalid: ${error49 instanceof Error?error49.message:String(error49)}`)}for(let row of receipt.matchedRows)sources.push({batchId:row.source_batch_id,laneId:row.source_lane_id,mode:"swarm-pr-review:micro",workflowLane:row.trigger_id})}let candidateIds=[],extractedLaneKeys=new Set;for(let source of sources){let resolvedArtifact=!1;for(let record2 of findByBatchId(directory,source.batchId,{parentSessionId:state.sessionID})){if(record2.laneId!==source.laneId||record2.mode!==source.mode||record2.status!=="completed"||record2.workspace?.prHeadSha!==state.prHeadSha||record2.workspace?.gitHead!==state.prHeadSha||record2.result?.outputDegraded===!0||record2.result?.transcriptIncomplete===!0||record2.result?.truncated===!0)continue;let ref=record2.result?.outputRef?.trim(),artifact=ref?readLaneOutput(directory,ref)?.artifact:void 0,recordOwnedLanes=record2.ownedWorkflowLanes?.length?record2.ownedWorkflowLanes:record2.workflowLane?[record2.workflowLane]:void 0;if(!artifact||!workflowArtifactHasContractMarker(directory,state,record2,source.mode,record2.workflowLane??source.workflowLane??source.laneId,void 0,void 0,recordOwnedLanes))continue;if(source.workflowLane&&(!recordOwnedLanes?.includes(source.workflowLane)||!prReviewDiscoveryArtifactCoversLane(artifact.text,source.workflowLane,recordOwnedLanes)))continue;resolvedArtifact=!0;let laneKey=`${source.batchId}\x00${source.laneId}`;if(!extractedLaneKeys.has(laneKey))extractedLaneKeys.add(laneKey),candidateIds.push(...extractCandidateIds(artifact.text,source.mode==="swarm-pr-review:micro"?"micro_lane":"base_explorer",source.creditedLanes))}if(source.mode==="swarm-pr-review:micro"&&!resolvedArtifact)throw Error(`BLOCKED: PR_REVIEW mandatory micro-lane provenance is missing or invalid for ${source.workflowLane??source.laneId}`)}return assertNoDuplicates(candidateIds,"PR_REVIEW discovery candidate ids"),candidateIds.length>0?candidateIds.sort():["CLEAN-REVIEW"]}function appendBoundedCandidateIssue(issues,message){if(issues.length<MAX_CANDIDATE_ISSUES_PER_ARTIFACT-1){issues.push(message.slice(0,MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS));return}if(issues.length===MAX_CANDIDATE_ISSUES_PER_ARTIFACT-1)issues.push("additional malformed candidate diagnostics omitted")}function parseCanonicalCandidateRows(text,fallbackFamily){let rows=[],issues=[],headerFamily=null;for(let[index,line]of removeCandidateCodeFences(text).split(/\r?\n/).entries()){let fields=splitPipeFields(line).map((field)=>field.trim()),detectedHeaderFamily=candidateHeaderFamily(fields);if(detectedHeaderFamily){headerFamily=detectedHeaderFamily;continue}let explicitMarker=fields[0]==="[CANDIDATE]",markerlessRow=headerFamily!==null&&Boolean(fields[0])&&!fields[0].startsWith("[");if(!explicitMarker&&!markerlessRow)continue;if(explicitMarker&&headerFamily===null){appendBoundedCandidateIssue(issues,`row ${index+1} field header: candidate output must begin with one exact canonical base or micro [CANDIDATE] header`);continue}let family=headerFamily??fallbackFamily,candidateFields=explicitMarker?fields.slice(1):fields,analysis=analyzeCandidateFields(candidateFields,family);if(!analysis.valid){for(let issue2 of analysis.issues)appendBoundedCandidateIssue(issues,`row ${index+1} field ${issue2.field}: ${issue2.message}`);continue}if(!analysis.candidateId||!analysis.workflowLane)continue;rows.push({candidateId:analysis.candidateId,workflowLane:analysis.workflowLane,evidence:candidateFields.slice(2).join("\x00"),lineNumber:index+1})}return{rows,issues}}function extractCandidateIds(text,fallbackFamily,scopeToLanes){let inScope=(lane)=>!scopeToLanes||lane!==void 0&&scopeToLanes.includes(lane);return parseCanonicalCandidateRows(text,fallbackFamily).rows.filter((row)=>inScope(row.workflowLane)).map((row)=>row.candidateId)}function derivePrReviewCriticInventory(directory,state){return[...deriveLatestPrReviewReviewerVerdicts(directory,state).entries()].filter(([,verdict])=>verdict.classification==="CONFIRMED"&&["CRITICAL","HIGH","MEDIUM"].includes(verdict.severity)).map(([itemId])=>itemId).sort()}function deriveLatestPrReviewCriticVerdicts(directory,state){let reviewerVerdicts=deriveLatestPrReviewReviewerVerdicts(directory,state),criticBatches=(state.prReviewValidationBatches??[]).filter((batch)=>batch.phase==="critic");for(let batch of[...criticBatches].reverse()){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:critic",batch.validatedAt);if(batch.lanes.some((lane)=>!successful.has(lane.workflowLane))||successful.size!==batch.lanes.length)continue;let required2=batch.lanes.flatMap((lane)=>lane.reviewItemIds??[]),verdicts=new Map;for(let lane of batch.lanes){let ref=findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===lane.laneId)?.result?.outputRef?.trim(),artifact=ref?readLaneOutput(directory,ref)?.artifact:void 0;if(!artifact)continue;for(let itemId of lane.reviewItemIds??[]){let verdict=parseCriticVerdict(artifact.text,itemId,reviewerVerdicts.get(itemId)?.severity);if(verdict)verdicts.set(itemId,verdict)}}if(required2.every((itemId)=>verdicts.has(itemId)))return verdicts}return new Map}function deriveLatestPrReviewReviewerVerdicts(directory,state){let reviewerBatches=(state.prReviewValidationBatches??[]).filter((batch)=>batch.phase==="reviewer");for(let batch of[...reviewerBatches].reverse()){let successful=successfulObligationsFromExactBatch(directory,state,batch.batchId,batch.lanes,"swarm-pr-review:reviewer",batch.validatedAt);if(batch.lanes.some((lane)=>!successful.has(lane.workflowLane))||successful.size!==batch.lanes.length)continue;let required2=batch.lanes.flatMap((lane)=>lane.reviewItemIds??[]),verdicts=new Map;for(let lane of batch.lanes){let ref=findByBatchId(directory,batch.batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===lane.laneId)?.result?.outputRef?.trim(),artifact=ref?readLaneOutput(directory,ref)?.artifact:void 0;if(!artifact)continue;for(let itemId of lane.reviewItemIds??[]){let verdict=parseReviewerVerdict(artifact.text,itemId);if(verdict)verdicts.set(itemId,verdict)}}if(required2.every((itemId)=>verdicts.has(itemId)))return verdicts}return new Map}function successfulObligationsFromExactBatch(directory,state,batchId,expectedLanes,expectedMode,validatedAt,checkWorkflowLane=!0,forbiddenSubagentSessionIds=new Set,expectedRevisionDigest,diagnostics){let records=findByBatchId(directory,batchId,{parentSessionId:state.sessionID}),successful=new Set,validatedAtMs=Date.parse(validatedAt);if(!Number.isFinite(validatedAtMs))return successful;let expectedByLaneId=new Map(expectedLanes.map((lane)=>[lane.laneId,lane]));if(expectedByLaneId.size!==expectedLanes.length)return successful;let recordCountByLaneId=new Map,recordCountBySubagentSessionId=new Map;for(let record2 of records){if(!record2.laneId||!expectedByLaneId.has(record2.laneId))continue;recordCountByLaneId.set(record2.laneId,(recordCountByLaneId.get(record2.laneId)??0)+1);let subagentSessionId=record2.subagentSessionId?.trim();if(subagentSessionId)recordCountBySubagentSessionId.set(subagentSessionId,(recordCountBySubagentSessionId.get(subagentSessionId)??0)+1)}for(let record2 of records){let expectedLane=record2.laneId?expectedByLaneId.get(record2.laneId):void 0,expectedWorkflowLane=expectedLane?.workflowLane,expectedOwnedLanes=expectedLane?.ownedWorkflowLanes?.length?expectedLane.ownedWorkflowLanes:expectedWorkflowLane!==void 0?[expectedWorkflowLane]:void 0,subagentSessionId=record2.subagentSessionId?.trim();if(expectedWorkflowLane!==void 0&&expectedOwnedLanes!==void 0&&record2.laneId!==void 0&&recordCountByLaneId.get(record2.laneId)===1&&Boolean(subagentSessionId)&&recordCountBySubagentSessionId.get(subagentSessionId)===1&&!forbiddenSubagentSessionIds.has(subagentSessionId)&&record2.createdAt>=validatedAtMs&&(!checkWorkflowLane||record2.workflowLane===expectedWorkflowLane)&&(!checkWorkflowLane||ownedLaneSetsEqual(record2.ownedWorkflowLanes,expectedOwnedLanes))&&record2.mode===expectedMode&&record2.workspace?.prHeadSha===state.prHeadSha&&record2.workspace?.gitHead===state.prHeadSha&&record2.status==="completed"&&record2.result?.outputDegraded!==!0&&record2.result?.transcriptIncomplete!==!0&&record2.result?.truncated!==!0&&(record2.result?.chars??0)>0&&Boolean(record2.result?.digest?.trim())&&Boolean(record2.result?.outputRef?.trim())&&workflowArtifactHasContractMarker(directory,state,record2,expectedMode,expectedWorkflowLane,expectedLane?.reviewItemIds,expectedRevisionDigest,expectedOwnedLanes,diagnostics))for(let obligation of expectedOwnedLanes)successful.add(obligation)}return successful}function ownedLaneSetsEqual(recordOwned,expectedOwned){if(!recordOwned||recordOwned.length===0)return expectedOwned.length===1;let recordSet=new Set(recordOwned),expectedSet=new Set(expectedOwned);if(recordSet.size!==recordOwned.length||recordSet.size!==expectedSet.size)return!1;return recordOwned.every((owned)=>expectedSet.has(owned))}function workflowArtifactHasContractMarker(directory,state,record2,expectedMode,expectedWorkflowLane,reviewItemIds,expectedRevisionDigest,ownedWorkflowLanes,diagnostics){let ref=record2.result?.outputRef?.trim();if(!ref)return!1;let loaded=readLaneOutput(directory,ref);if(!loaded)return!1;let artifact=loaded.artifact,recordPrHeadSha=record2.workspace?.prHeadSha,recordGitHead=record2.workspace?.gitHead,resolvedRevisionDigest=expectedRevisionDigest??(recordPrHeadSha?_test_exports.resolvePrWorkflowRevisionDigest(directory,recordPrHeadSha):null),expectedReviewScope=state.mode==="PR_REVIEW"&&state.prReviewBaseSha&&state.prHeadSha?`complete PR diff ${state.prReviewBaseSha}...${state.prHeadSha}`:void 0;if(artifact.batchId!==record2.batchId||artifact.laneId!==record2.laneId||artifact.mode!==expectedMode||artifact.sessionId!==record2.subagentSessionId||artifact.parentSessionId!==record2.parentSessionId||artifact.agent!==record2.swarmPrefixedAgent||artifact.role!==record2.normalizedAgent||artifact.source!=="collect_lane_results"||artifact.workflowLane!==record2.workflowLane||artifact.workflowLane!==expectedWorkflowLane||!recordPrHeadSha||artifact.prHeadSha!==recordPrHeadSha||!recordGitHead||artifact.gitHead!==recordGitHead||!resolvedRevisionDigest||artifact.revisionDigest!==resolvedRevisionDigest||expectedReviewScope!==void 0&&(record2.workspace?.scope!==expectedReviewScope||artifact.scope!==expectedReviewScope)||artifact.digest!==record2.result?.digest||artifact.chars!==record2.result?.chars)return!1;if(expectedMode==="swarm-pr-review:reviewer")return Boolean(reviewItemIds?.length&&reviewItemIds.every((itemId)=>Boolean(parseReviewerVerdict(artifact.text,itemId))));if(expectedMode==="swarm-pr-review:critic"){let reviewerVerdicts=deriveLatestPrReviewReviewerVerdicts(directory,state);return Boolean(reviewItemIds?.length&&reviewItemIds.every((itemId)=>Boolean(parseCriticVerdict(artifact.text,itemId,reviewerVerdicts.get(itemId)?.severity))))}if(expectedMode==="swarm-pr-feedback:verification")return/^\[FEEDBACK-VERIFIED\]\s*\|/m.test(artifact.text);let feedbackVerdict={"swarm-pr-feedback:stage-b-reviewer":["[STAGE-B-REVIEW]","APPROVE"],"swarm-pr-feedback:stage-b-test":["[STAGE-B-TEST]","PASS"],"swarm-pr-feedback:closeout-reviewer":["[CLOSEOUT-REVIEW]","APPROVE"],"swarm-pr-feedback:closeout-critic":["[CLOSEOUT-CRITIC]","APPROVE"]}[expectedMode];if(feedbackVerdict)return Boolean(reviewItemIds?.length&&reviewItemIds.every((itemId)=>artifactHasExactPositiveVerdictRow(artifact.text,feedbackVerdict[0],itemId,feedbackVerdict[1])));let coveredLanes=ownedWorkflowLanes?.length?ownedWorkflowLanes:[expectedWorkflowLane],coverageAnalyses=coveredLanes.map((coveredLane)=>({coveredLane,analysis:analyzePrReviewDiscoveryArtifact(artifact.text,coveredLane,coveredLanes)}));if(coverageAnalyses.some(({analysis})=>!analysis.covered)){for(let{coveredLane,analysis}of coverageAnalyses){if(analysis.covered||analysis.issues.length===0)continue;if(diagnostics&&diagnostics.length<MAX_BASE_COVERAGE_DIAGNOSTICS){let diagnostic=`batch=${record2.batchId??"(missing)"} lane=${record2.laneId??"(missing)"} workflow_lane=${coveredLane} output_ref=${ref} digest=${record2.result?.digest??"(missing)"}: ${analysis.issues.join("; ")}`;diagnostics.push(diagnostic.slice(0,MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS))}}return!1}if(coveredLanes.length>1){let seenEvidence=new Map;for(let coveredLane of coveredLanes){let evidence2=extractLaneCoverageEvidenceText(artifact.text,coveredLane,coveredLanes);if(evidence2===null)continue;if(seenEvidence.get(evidence2))return!1;seenEvidence.set(evidence2,coveredLane)}}return!0}function analyzePrReviewDiscoveryArtifact(text,expectedWorkflowLane,ownedWorkflowLanes=[expectedWorkflowLane]){let fallbackFamily=PR_REVIEW_BASE_DIMENSION_IDS.includes(expectedWorkflowLane)?"base_explorer":"micro_lane",issues=[],canonicalText=removeCandidateCodeFences(text),firstTabularFields=canonicalText.split(/\r?\n/).map((line)=>splitPipeFields(line).map((field)=>field.trim())).find((fields)=>fields.length>=2&&fields.some((field)=>field.length>0));if((firstTabularFields?candidateHeaderFamily(firstTabularFields):null)!==fallbackFamily)return appendBoundedCandidateIssue(issues,`field header: expected one exact canonical ${fallbackFamily} [CANDIDATE] header before discovery rows`),{covered:!1,evidence:null,issues};let parsed=parseCandidates({output_ref:"pr-workflow:discovery-artifact",batchId:"pr-workflow",laneId:expectedWorkflowLane,agent:"explorer",role:"explorer",digest:"0".repeat(64),text:canonicalText,artifact_status:"ok",source:"collect_lane_results",produced_at:"1970-01-01T00:00:00.000Z"},{accept_partial:!1,accept_degraded:!1,degraded:!1,row_format_version:1,producer:"swarm-pr-review",expected_family:fallbackFamily,...fallbackFamily==="base_explorer"?{expected_lane:expectedWorkflowLane,expected_lanes:[...ownedWorkflowLanes]}:{expected_micro_lane:expectedWorkflowLane,expected_micro_lanes:[...ownedWorkflowLanes]}});if(parsed.error)appendBoundedCandidateIssue(issues,parsed.error);for(let detail of parsed.diagnostics.parse_error_details)appendBoundedCandidateIssue(issues,`row ${detail.row_index+1} field ${detail.field}: ${detail.message}`);if(parsed.error||parsed.diagnostics.parse_error_details.length>0)return{covered:!1,evidence:null,issues};let matchingCandidate=parsed.candidates.find((candidate)=>(candidate.lane??candidate.micro_lane)===expectedWorkflowLane);if(matchingCandidate)return{covered:!0,evidence:[matchingCandidate.severity,matchingCandidate.category,matchingCandidate.file_line,matchingCandidate.claim,matchingCandidate.evidence_summary,matchingCandidate.impact_context??matchingCandidate.invariant_violated,matchingCandidate.confidence].join("\x00"),issues};let clean=parsed.clean_attestation;if(clean&&(clean.row_format_family==="base_explorer"?clean.lane:clean.micro_lane)===expectedWorkflowLane)return{covered:!0,evidence:`${clean.coverage_scope}\x00${clean.evidence}`,issues};return{covered:!1,evidence:null,issues}}function prReviewDiscoveryArtifactCoversLane(text,expectedWorkflowLane,ownedWorkflowLanes=[expectedWorkflowLane]){return analyzePrReviewDiscoveryArtifact(text,expectedWorkflowLane,ownedWorkflowLanes).covered}function extractLaneCoverageEvidenceText(text,expectedWorkflowLane,ownedWorkflowLanes=[expectedWorkflowLane]){return analyzePrReviewDiscoveryArtifact(text,expectedWorkflowLane,ownedWorkflowLanes).evidence}function parseReviewerVerdict(text,itemId){let rows=text.split(/\r?\n/).map(pipeFields).filter((fields2)=>fields2[0]==="[REVIEWED]"&&fields2[1]===itemId);if(rows.length!==1)return null;let fields=rows[0];if(fields.length!==10||!fields.slice(1).every(Boolean))return null;let introduced=fields[5].replace(/^introduced_by_pr\s*:\s*/i,"").toUpperCase();if(!REVIEWER_CLASSIFICATIONS.has(fields[2])||!REVIEWER_EVIDENCE_TYPES.has(fields[3])||!REVIEW_SEVERITIES.has(fields[4])||!["YES","NO","UNKNOWN"].includes(introduced))return null;if(fields[7].length<8||fields[8].length<5||fields[9].length<3)return null;return{classification:fields[2],severity:fields[4]}}function parseCriticVerdict(text,itemId,reviewerSeverity){let rows=text.split(/\r?\n/).map(pipeFields).filter((fields2)=>fields2[0]==="[CRITIC]"&&fields2[1]===itemId);if(rows.length!==1)return null;let fields=rows[0];if(fields.length!==6||!fields.slice(1).every(Boolean)||!CRITIC_STATUSES.has(fields[2])||!REVIEW_SEVERITIES.has(fields[3]))return null;if(fields[2]==="NEEDS_MORE_EVIDENCE")return null;if(fields[2]==="DISPROVED"&&fields[3]!=="NONE")return null;if(fields[2]==="UPHELD"&&!["CRITICAL","HIGH","MEDIUM"].includes(fields[3]))return null;if(fields[2]==="DOWNGRADED"&&fields[3]==="CRITICAL")return null;if(reviewerSeverity){let severityRank=new Map([["NONE",0],["INFO",1],["LOW",2],["MEDIUM",3],["HIGH",4],["CRITICAL",5]]),reviewerRank=severityRank.get(reviewerSeverity),criticRank=severityRank.get(fields[3]);if(reviewerRank===void 0||criticRank===void 0)return null;if(fields[2]==="UPHELD"&&criticRank!==reviewerRank)return null;if(fields[2]==="DOWNGRADED"&&criticRank>=reviewerRank)return null}if(fields[4].length<6||fields[5].length<6)return null;return{status:fields[2],severity:fields[3]}}function artifactHasExactPositiveVerdictRow(text,marker,itemId,positiveVerdict){let rows=text.split(/\r?\n/).map(pipeFields).filter((fields)=>fields[0]===marker&&fields[1]===itemId);return rows.length===1&&rows[0].length>=4&&rows[0][2]===positiveVerdict&&rows[0].slice(1,4).every(Boolean)}function pipeFields(line){if(!line.includes("|"))return[];return line.split("|").map((field)=>field.trim())}function feedbackArtifactCoversItems(directory,state,batchId,laneId,itemIds){let ref=findByBatchId(directory,batchId,{parentSessionId:state.sessionID}).find((candidate)=>candidate.laneId===laneId)?.result?.outputRef?.trim(),loaded=ref?readLaneOutput(directory,ref):null;if(!loaded)return!1;let rows=loaded.artifact.text.split(/\r?\n/).map(pipeFields).filter((fields)=>fields[0]==="[FEEDBACK-VERIFIED]");if(rows.length!==itemIds.length)return!1;return itemIds.every((itemId)=>{let matches=rows.filter((fields)=>fields[1]===itemId);return matches.length===1&&matches[0].length===4&&matches[0].slice(1,4).every(Boolean)&&FEEDBACK_CLASSIFICATIONS.has(matches[0][2])})}async function persistState(directory,state){let validated=PrWorkflowGateStateSchema.parse(state);await withSessionStateMutation(directory,validated.sessionID,async()=>{let nextState=await writeStateWhileLocked(directory,validated);Object.assign(state,nextState)})}async function writeStateWhileLocked(directory,state,options={}){let validated=PrWorkflowGateStateSchema.parse(state),current=await readPrWorkflowGateStateFromDisk(directory,validated.sessionID);if(current?current.revision!==validated.revision:validated.revision!==0)throw Error("BLOCKED: PR workflow gate state changed concurrently; reload the active session state before retrying");if(current?.workflowInstanceId&&validated.workflowInstanceId!==current.workflowInstanceId&&options.replaceWorkflowInstanceId!==current.workflowInstanceId)throw Error("BLOCKED: PR workflow gate state changed concurrently; reload the active session state before retrying");let nextState=PrWorkflowGateStateSchema.parse({...validated,revision:validated.revision+1}),filePath=workflowGateStatePath(directory,validated.sessionID);return await writeAtomicJson2(directory,filePath,nextState),rememberState(directory,nextState),nextState}function workflowCheckoutMutationLockRelativePath(){return path14.join(WORKFLOW_GATE_DIR,"checkout.lock")}function workflowCheckoutMutationLockPath(directory){return validateSwarmPath(directory,workflowCheckoutMutationLockRelativePath())}function openCheckoutLockFile(lockPath){return fsp3.open(lockPath,"wx")}function removeCheckoutLockFile(lockPath){return fsp3.rm(lockPath)}function checkoutMutationProjectKey(directory){return normalizeComparableFsPath(directory)}async function withCheckoutMutationDeadline(promise2,phase){let timeout;try{return await Promise.race([promise2,new Promise((resolve9)=>{timeout=setTimeout(()=>{resolve9({status:"timeout",error:new PrWorkflowCheckoutMutationTimeoutError(phase)})},_test_exports.checkoutMutationActionTimeoutMs)})])}finally{if(timeout)clearTimeout(timeout)}}async function withPrWorkflowCheckoutMutationLock(directory,action){let key=checkoutMutationProjectKey(directory),previous=pendingCheckoutMutationsByProject.get(key)??Promise.resolve(),release,current=new Promise((resolve9)=>{release=resolve9}),queued=previous.then(()=>current);pendingCheckoutMutationsByProject.set(key,queued);let previousResult=await withCheckoutMutationDeadline(previous.then(()=>({status:"ready"})),"queue");if(previousResult.status==="timeout")throw release(),queued.then(()=>{if(pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key)}),previousResult.error;let lock;try{lock=await acquireCheckoutMutationLock(directory)}catch(error49){if(release(),pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key);throw error49}let actionOutcome=Promise.resolve().then(action).then((value)=>({status:"fulfilled",value}),(error49)=>({status:"rejected",error:error49})),outcome=await withCheckoutMutationDeadline(actionOutcome,"action");if(outcome.status==="timeout")throw actionOutcome.then(async()=>{try{await releaseCheckoutMutationLock(lock)}catch{}finally{if(release(),pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key)}}),outcome.error;try{if(outcome.status==="rejected")throw outcome.error;return outcome.value}finally{try{await releaseCheckoutMutationLock(lock)}finally{if(release(),pendingCheckoutMutationsByProject.get(key)===queued)pendingCheckoutMutationsByProject.delete(key)}}}async function acquireCheckoutMutationLock(directory){let lockPath=workflowCheckoutMutationLockPath(directory),verifiedParent=await ensurePrWorkflowSafeParentDirectory(directory,lockPath);for(let attempt=0;attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS;attempt++)try{let handle=await _test_exports.openCheckoutLock(lockPath),lock={ownerToken:randomUUID2(),pid:process.pid,createdAtMs:_test_exports.nowMs()},lockIdentity,writeError;try{let openedStat=await handle.stat({bigint:!0});lockIdentity={dev:openedStat.dev,ino:openedStat.ino},lockIdentity=await assertOpenedSwarmFileIdentity(directory,lockPath,handle,verifiedParent,"PR workflow checkout mutation lock"),await _test_exports.beforeCheckoutLockWrite?.(),await handle.writeFile(JSON.stringify(lock),"utf-8")}catch(error49){writeError=error49}finally{await handle.close().catch(()=>{return})}if(writeError){if(lockIdentity)await removeCheckoutMutationLockByIdentity(directory,lockPath,lockIdentity,verifiedParent);throw writeError}return{path:lockPath,ownerToken:lock.ownerToken}}catch(error49){if(error49.code!=="EEXIST")throw error49;if(await reclaimAbandonedCheckoutMutationLock(lockPath))continue;if(attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS-1)await delay(STATE_MUTATION_LOCK_RETRY_DELAY_MS)}throw Error("BLOCKED: PR workflow checkout mutation is being handled by another process; retry after that checkout settles")}async function releaseCheckoutMutationLock(lock){let lastError;for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES3;attempt++){try{if(await removeCheckoutMutationLockIfOwned(lock.path,lock.ownerToken)){completedCheckoutLockOwners.delete(lock.path);return}lastError=Error("PR workflow checkout mutation lock ownership changed before release")}catch(error49){lastError=error49}if(attempt<WINDOWS_RENAME_MAX_RETRIES3-1)await delay(RENAME_RETRY_DELAY_MS)}throw rememberCompletedCheckoutLockOwner(lock.path,lock.ownerToken),lastError instanceof Error?lastError:Error("PR workflow checkout mutation lock release failed")}async function reclaimAbandonedCheckoutMutationLock(lockPath){let lock=await readCheckoutMutationLock(lockPath);if(lock){if(lock.pid===process.pid&&completedCheckoutLockOwners.get(lockPath)===lock.ownerToken){let removed=await removeCheckoutMutationLockIfOwned(lockPath,lock.ownerToken);if(removed)completedCheckoutLockOwners.delete(lockPath);return removed}if(_test_exports.isProcessAlive(lock.pid))return!1;return removeCheckoutMutationLockIfOwned(lockPath,lock.ownerToken)}try{let stat6=await fsp3.stat(lockPath);if(_test_exports.nowMs()-stat6.mtimeMs<STATE_MUTATION_LOCK_UNINITIALIZED_STALE_MS)return!1;return await fsp3.rm(lockPath,{force:!0}),!0}catch(error49){if(error49.code==="ENOENT")return!0;throw error49}}async function readCheckoutMutationLock(lockPath){let raw;try{raw=await fsp3.readFile(lockPath,"utf-8")}catch(error49){if(error49.code==="ENOENT")return null;throw error49}try{let parsed=JSON.parse(raw);if(typeof parsed==="object"&&parsed!==null&&typeof parsed.ownerToken==="string"&&parsed.ownerToken.length>0&&typeof parsed.pid==="number"&&Number.isInteger(parsed.pid)&&parsed.pid>0&&typeof parsed.createdAtMs==="number"&&Number.isFinite(parsed.createdAtMs))return parsed}catch{}return null}async function removeCheckoutMutationLockIfOwned(lockPath,ownerToken){let lock=await readCheckoutMutationLock(lockPath);if(!lock||lock.ownerToken!==ownerToken)return!1;try{return await _test_exports.removeCheckoutLock(lockPath),!0}catch(error49){if(error49.code==="ENOENT")return!1;throw error49}}async function removeCheckoutMutationLockByIdentity(directory,lockPath,identity,verifiedParent){let lastError;for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES3;attempt++)try{await assertClosedSwarmFileIdentity(directory,lockPath,identity,verifiedParent,"PR workflow checkout mutation lock"),await _test_exports.removeCheckoutLock(lockPath);return}catch(error49){if(error49.code==="ENOENT")return;if(lastError=error49,attempt<WINDOWS_RENAME_MAX_RETRIES3-1)await delay(RENAME_RETRY_DELAY_MS)}throw lastError instanceof Error?lastError:Error("PR workflow checkout mutation lock cleanup failed")}function rememberCompletedCheckoutLockOwner(lockPath,ownerToken){completedCheckoutLockOwners.delete(lockPath),completedCheckoutLockOwners.set(lockPath,ownerToken);while(completedCheckoutLockOwners.size>MAX_COMPLETED_CHECKOUT_LOCK_OWNERS){let oldest=completedCheckoutLockOwners.keys().next().value;if(oldest===void 0)break;completedCheckoutLockOwners.delete(oldest)}}async function withSessionStateMutation(directory,sessionID,action){let key=stateCacheKey(directory,sessionID),previous=pendingStateMutationsByProjectSession.get(key)??Promise.resolve(),release,current=new Promise((resolve9)=>{release=resolve9}),queued=previous.then(()=>current);pendingStateMutationsByProjectSession.set(key,queued),await previous;try{let lock=await acquireSessionStateMutationLock(directory,sessionID);try{return await action()}finally{await releaseSessionStateMutationLock(lock)}}finally{if(release(),pendingStateMutationsByProjectSession.get(key)===queued)pendingStateMutationsByProjectSession.delete(key)}}async function acquireSessionStateMutationLock(directory,sessionID){let lockPath=workflowGateStateLockPath(directory,sessionID),verifiedParent=await ensurePrWorkflowSafeParentDirectory(directory,lockPath);for(let attempt=0;attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS;attempt++)try{let handle=await fsp3.open(lockPath,"wx"),lock={ownerToken:randomUUID2(),pid:process.pid,createdAtMs:_test_exports.nowMs()},writeError;try{await _test_exports.beforeSessionStateLockWrite?.(),await assertOpenedSwarmFileIdentity(directory,lockPath,handle,verifiedParent,"PR workflow state mutation lock"),await handle.writeFile(JSON.stringify(lock),"utf-8")}catch(error49){writeError=error49}finally{await handle.close().catch(()=>{return})}if(writeError)throw await removeSessionStateMutationLockIfOwned(lockPath,lock.ownerToken),writeError;return{path:lockPath,ownerToken:lock.ownerToken}}catch(error49){if(error49.code!=="EEXIST")throw error49;if(await reclaimAbandonedSessionStateMutationLock(lockPath))continue;if(attempt<STATE_MUTATION_LOCK_MAX_ATTEMPTS-1)await delay(STATE_MUTATION_LOCK_RETRY_DELAY_MS)}throw Error("BLOCKED: PR workflow gate state is being mutated by another process; retry after that session transition finishes")}async function releaseSessionStateMutationLock(lock){try{await removeSessionStateMutationLockIfOwned(lock.path,lock.ownerToken)}catch{}}async function reclaimAbandonedSessionStateMutationLock(lockPath){let lock=await readSessionStateMutationLock(lockPath);if(lock){if(_test_exports.isProcessAlive(lock.pid))return!1;return removeSessionStateMutationLockIfOwned(lockPath,lock.ownerToken)}try{let stat6=await fsp3.stat(lockPath);if(_test_exports.nowMs()-stat6.mtimeMs<STATE_MUTATION_LOCK_UNINITIALIZED_STALE_MS)return!1;return await fsp3.rm(lockPath,{force:!0}),!0}catch(error49){if(error49.code==="ENOENT")return!0;throw error49}}async function readSessionStateMutationLock(lockPath){let raw;try{raw=await fsp3.readFile(lockPath,"utf-8")}catch(error49){if(error49.code==="ENOENT")return null;throw error49}try{let parsed=JSON.parse(raw);if(typeof parsed==="object"&&parsed!==null&&typeof parsed.ownerToken==="string"&&parsed.ownerToken.length>0&&typeof parsed.pid==="number"&&Number.isInteger(parsed.pid)&&parsed.pid>0&&typeof parsed.createdAtMs==="number"&&Number.isFinite(parsed.createdAtMs))return parsed}catch{}return null}async function removeSessionStateMutationLockIfOwned(lockPath,ownerToken){let lock=await readSessionStateMutationLock(lockPath);if(!lock||lock.ownerToken!==ownerToken)return!1;try{return await fsp3.rm(lockPath),!0}catch(error49){if(error49.code==="ENOENT")return!1;throw error49}}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch(error49){return error49.code!=="ESRCH"}}async function readPrWorkflowGateStateFromDisk(directory,sessionID){let filePath=workflowGateStatePath(directory,sessionID),raw;try{raw=await fsp3.readFile(filePath,"utf-8")}catch(error49){if(error49.code==="ENOENT")return null;throw error49}let parsedJson;try{parsedJson=JSON.parse(raw)}catch{throw Error(`BLOCKED: PR workflow gate state for session "${sessionID}" is not valid JSON`)}let parsed=PrWorkflowGateStateSchema.safeParse(parsedJson);if(!parsed.success)throw Error(`BLOCKED: PR workflow gate state for session "${sessionID}" is invalid`);return parsed.data}function rememberState(directory,state){let cacheKey=stateCacheKey(directory,state.sessionID);trackedStatesByProjectSession.delete(cacheKey),trackedStatesByProjectSession.set(cacheKey,state);while(trackedStatesByProjectSession.size>MAX_TRACKED_SESSIONS){let oldestKey=trackedStatesByProjectSession.keys().next().value;if(!oldestKey)break;trackedStatesByProjectSession.delete(oldestKey)}}function stateCacheKey(directory,sessionID){let resolved=path14.normalize(path14.resolve(directory));return`${process.platform==="win32"?resolved.toLowerCase():resolved}\x00${normalizeSessionID(sessionID)}`}function workflowGateStatePath(directory,sessionID){return validateSwarmPath(directory,workflowGateStateRelativePath(sessionID))}function workflowGateStateLockPath(directory,sessionID){return validateSwarmPath(directory,workflowGateStateLockRelativePath(sessionID))}function workflowGateStateLockRelativePath(sessionID){return path14.join(WORKFLOW_GATE_DIR,`${prWorkflowSessionFileStem(sessionID)}.lock`)}function workflowGateStateRelativePath(sessionID){return path14.join(WORKFLOW_GATE_DIR,`${prWorkflowSessionFileStem(sessionID)}.json`)}function prWorkflowSessionFileStem(sessionID){let normalized=normalizeSessionID(sessionID),slug=normalized.replace(/[^A-Za-z0-9_.-]/g,"_").slice(0,80)||"session",digest2=createHash7("sha256").update(normalized).digest("hex").slice(0,12);return`${slug}-${digest2}`}function normalizeSessionID(sessionID){let normalized=sessionID.trim();if(!normalized)throw Error("BLOCKED: PR workflow gate requires a non-empty sessionID");return normalized}async function ensurePrWorkflowSafeParentDirectory(directory,filePath){let swarmRoot=path14.resolve(directory,".swarm"),parentPath=path14.dirname(path14.resolve(filePath)),relativeParent=path14.relative(swarmRoot,parentPath);if(relativeParent===".."||relativeParent.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeParent))throw Error("BLOCKED: PR workflow atomic destination escapes the project .swarm directory");await fsp3.mkdir(swarmRoot,{recursive:!0});let currentPath=swarmRoot,currentIdentity=await assertSafeDirectory(currentPath,void 0);for(let segment of relativeParent.split(path14.sep).filter(Boolean)){let nextPath=path14.join(currentPath,segment);await _test_exports.beforeSafeDirectoryCreate?.(currentPath,nextPath),await assertSafeDirectory(currentPath,currentIdentity);try{await fsp3.mkdir(nextPath)}catch(error49){if(error49.code!=="EEXIST")throw error49}await assertSafeDirectory(currentPath,currentIdentity);let nextIdentity=await assertSafeDirectory(nextPath,void 0),[realCurrent,realNext]=await Promise.all([fsp3.realpath(currentPath),fsp3.realpath(nextPath)]);if(normalizeComparableFsPath(path14.dirname(realNext))!==normalizeComparableFsPath(realCurrent))throw Error("BLOCKED: PR workflow directory creation escaped the project .swarm tree");currentPath=nextPath,currentIdentity=nextIdentity}let realRoot=await fsp3.realpath(swarmRoot),realParent=await fsp3.realpath(parentPath),relativeRealParent=path14.relative(realRoot,realParent);if(relativeRealParent===".."||relativeRealParent.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeRealParent))throw Error("BLOCKED: PR workflow atomic parent escapes the project .swarm directory");return realParent}async function assertSafeDirectory(directoryPath,expectedIdentity){let stat6=await fsp3.lstat(directoryPath,{bigint:!0});if(stat6.isSymbolicLink()||!stat6.isDirectory()||expectedIdentity&&!sameBigIntFileIdentity(stat6,expectedIdentity))throw Error("BLOCKED: PR workflow .swarm path must be a real directory and must not change during the operation");return{dev:stat6.dev,ino:stat6.ino}}async function assertOpenedSwarmFileIdentity(directory,filePath,handle,expectedParent,label){let openedStat=await handle.stat({bigint:!0});if(!openedStat.isFile())throw Error(`BLOCKED: ${label} is not a file`);return await assertClosedSwarmFileIdentity(directory,filePath,openedStat,expectedParent,label),{dev:openedStat.dev,ino:openedStat.ino}}async function assertClosedSwarmFileIdentity(directory,filePath,expectedIdentity,expectedParent,label){if(!expectedIdentity)throw Error(`BLOCKED: ${label} has no identity`);let[stat6,realRoot,realFile,realParent]=await Promise.all([fsp3.lstat(filePath,{bigint:!0}),fsp3.realpath(path14.resolve(directory,".swarm")),fsp3.realpath(filePath),fsp3.realpath(path14.dirname(filePath))]),relativeFile=path14.relative(realRoot,realFile);if(stat6.isSymbolicLink()||!stat6.isFile()||!sameBigIntFileIdentity(stat6,expectedIdentity)||normalizeComparableFsPath(realParent)!==normalizeComparableFsPath(expectedParent)||relativeFile===""||relativeFile===".."||relativeFile.startsWith(`..${path14.sep}`)||path14.isAbsolute(relativeFile))throw Error(`BLOCKED: ${label} changed or escaped .swarm`)}async function writeAtomicJson2(directory,filePath,value){let safeParent=await ensurePrWorkflowSafeParentDirectory(directory,filePath),tempPath=`${filePath}.tmp.${process.pid}.${randomUUID2()}`,tempIdentity,lastError;try{let handle=await fsp3.open(tempPath,"wx");try{await _test_exports.beforeAtomicTempWrite?.(),tempIdentity=await assertOpenedSwarmFileIdentity(directory,tempPath,handle,safeParent,"PR workflow atomic temporary file"),await handle.writeFile(JSON.stringify(value,null,2),"utf-8"),await handle.sync()}finally{await handle.close()}await _test_exports.beforeAtomicRename?.(),await assertClosedSwarmFileIdentity(directory,tempPath,tempIdentity,safeParent,"PR workflow atomic temporary file");for(let attempt=0;attempt<WINDOWS_RENAME_MAX_RETRIES3;attempt++)try{await _test_exports.rename(tempPath,filePath),lastError=void 0;break}catch(error49){lastError=error49;let code=error49.code;if(code!=="EEXIST"&&code!=="EPERM"&&code!=="EBUSY")break;if(attempt<WINDOWS_RENAME_MAX_RETRIES3-1)await delay(RENAME_RETRY_DELAY_MS)}if(lastError)throw lastError;await assertClosedSwarmFileIdentity(directory,filePath,tempIdentity,safeParent,"PR workflow atomic destination file")}finally{try{await fsp3.rm(tempPath,{force:!0})}catch{}}}async function writePrWorkflowAtomicJson(directory,filePath,value){await writeAtomicJson2(directory,filePath,value)}function isoNow(){return new Date().toISOString()}function delay(ms){return new Promise((resolve9)=>setTimeout(resolve9,ms))}var PR_REVIEW_BASE_DIMENSION_IDS,PR_REVIEW_REQUIRED_MICRO_LANE_IDS,PR_REVIEW_DEPTH_TIER_THRESHOLDS,PR_REVIEW_BASE_LANE_FLOORS,PR_REVIEW_MICRO_LANE_FLOORS,GATE_SCHEMA_VERSION=1,MAX_TRACKED_SESSIONS=200,MAX_WORKFLOW_BATCHES=128,WINDOWS_RENAME_MAX_RETRIES3=3,RENAME_RETRY_DELAY_MS=10,STATE_MUTATION_LOCK_MAX_ATTEMPTS=50,STATE_MUTATION_LOCK_RETRY_DELAY_MS=10,STATE_MUTATION_LOCK_UNINITIALIZED_STALE_MS=30000,MAX_COMPLETED_CHECKOUT_LOCK_OWNERS=64,CHECKOUT_MUTATION_ACTION_TIMEOUT_MS=300000,MAX_CANDIDATE_ISSUES_PER_ARTIFACT=8,MAX_BASE_COVERAGE_DIAGNOSTICS=8,MAX_BASE_COVERAGE_DIAGNOSTIC_CHARS=1000,DISPATCH_TOOL_NAME="dispatch_lanes_async",BLOCKING_DISPATCH_TOOL_NAME="dispatch_lanes",WORKFLOW_GATE_DIR="pr-workflow-gates",trackedStatesByProjectSession,pendingStateMutationsByProjectSession,pendingCheckoutMutationsByProject,completedCheckoutLockOwners,PrReviewBaseDimensionIdSchema,PrReviewBaseDispatchRecordSchema,PrFeedbackLaneOwnershipSchema,PrFeedbackVerificationRecordSchema,PrFeedbackStageACheckReceiptSchema,PrFeedbackStageARecordSchema,PrFeedbackGateBatchRecordSchema,PrFeedbackReadyToPublishRecordSchema,PrReviewValidationBatchRecordSchema,PrFeedbackScopeDeclarationRecordSchema,PrWorkflowCheckoutRecoveryRecordSchema,PrFeedbackReviewHandoffRecordSchema,PrWorkflowGateStateSchema,PR_FEEDBACK_PHASE_ORDER,PR_FEEDBACK_PHASE_ROLE,PR_REVIEW_HANDOFF_RELATIVE_PATH_PATTERN,PR_REVIEW_HANDOFF_MAX_BYTES=131072,PR_REVIEW_FINDINGS_MAX_BYTES=10485760,PrReviewFeedbackHandoffArtifactSchema,PrReviewFindingProjectionSchema,_test_exports,PR_WORKFLOW_SHARED_CONTROLLER_TOOLS,PR_REVIEW_CONTROLLER_TOOLS,PR_FEEDBACK_CONTROLLER_TOOLS,PR_REVIEW_READ_ONLY_TOOL_NAMES,PR_WORKFLOW_CD_PREFIX_PATTERN,PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN,PR_WORKFLOW_MAX_CD_PREFIX_STRIPS=3,PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN,PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN,REVIEWER_CLASSIFICATIONS,REVIEWER_EVIDENCE_TYPES,REVIEW_SEVERITIES,CRITIC_STATUSES,FEEDBACK_CLASSIFICATIONS,PrWorkflowCheckoutMutationTimeoutError;var init_pr_workflow_gate=__esm(()=>{init_zod();init_candidate_contract();init_candidate_parser();init_lane_output_store();init_pending_delegations();init_pr_review_trigger_contract();init_workspace_snapshot();init_constants();init_schema();init_pr_workflow_state();init_tool_metadata();init_utils2();PR_REVIEW_BASE_DIMENSION_IDS=["intent-architecture","correctness-state","tests-falsifiability","security-trust","reliability-performance","compatibility-delivery"],PR_REVIEW_REQUIRED_MICRO_LANE_IDS=PR_REVIEW_REQUIRED_TRIGGER_IDS,PR_REVIEW_DEPTH_TIER_THRESHOLDS={smallMaxChangedLines:100,smallMaxChangedFiles:5,mediumMaxChangedLines:1500,mediumMaxChangedFiles:50},PR_REVIEW_BASE_LANE_FLOORS={S:1,M:3,L:PR_REVIEW_BASE_DIMENSION_IDS.length},PR_REVIEW_MICRO_LANE_FLOORS={S:1,M:6,L:PR_REVIEW_REQUIRED_MICRO_LANE_IDS.length};trackedStatesByProjectSession=new Map,pendingStateMutationsByProjectSession=new Map,pendingCheckoutMutationsByProject=new Map,completedCheckoutLockOwners=new Map,PrReviewBaseDimensionIdSchema=exports_external.enum(["intent-architecture","correctness-state","tests-falsifiability","security-trust","reliability-performance","compatibility-delivery"]),PrReviewBaseDispatchRecordSchema=exports_external.object({batchId:exports_external.string().min(1),lanes:exports_external.array(exports_external.object({laneId:exports_external.string().min(1),workflowLane:PrReviewBaseDimensionIdSchema,ownedWorkflowLanes:exports_external.array(PrReviewBaseDimensionIdSchema).min(1).max(PR_REVIEW_BASE_DIMENSION_IDS.length).optional()}).strict()).min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackLaneOwnershipSchema=exports_external.object({laneId:exports_external.string().min(1),ownedItemIds:exports_external.array(exports_external.string().min(1)).min(1)}).strict(),PrFeedbackVerificationRecordSchema=exports_external.object({batchId:exports_external.string().min(1),ownership:exports_external.array(PrFeedbackLaneOwnershipSchema).min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackStageACheckReceiptSchema=exports_external.object({category:exports_external.enum(["build","typecheck","lint","diff-check","reproduction"]),workingDirectory:exports_external.string().min(1).optional(),obligationId:exports_external.string().min(1).optional(),validatorContract:exports_external.object({path:exports_external.string().min(1),id:exports_external.string().min(1)}).strict().optional(),command:exports_external.array(exports_external.string().min(1)).min(1),targets:exports_external.array(exports_external.string().min(1)).min(1).optional(),feedbackTargets:exports_external.array(exports_external.object({feedbackItemId:exports_external.string().min(1),target:exports_external.string().min(1),expectedBehavior:exports_external.string().min(8)}).strict()).min(1).optional(),durationMs:exports_external.number().nonnegative()}).strict(),PrFeedbackStageARecordSchema=exports_external.object({revisionDigest:exports_external.string().min(1),checks:exports_external.array(PrFeedbackStageACheckReceiptSchema).min(2).max(258),feedbackItemIds:exports_external.array(exports_external.string().min(1)).min(1).optional(),applicableCategories:exports_external.array(exports_external.enum(["build","typecheck","lint"])).max(3).optional(),applicableObligations:exports_external.array(exports_external.object({id:exports_external.string().min(1),category:exports_external.enum(["build","typecheck","lint"]),workingDirectory:exports_external.string().min(1),source:exports_external.string().min(1),validatorContract:exports_external.object({path:exports_external.string().min(1),id:exports_external.string().min(1)}).strict().optional()}).strict()).max(256).optional(),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackGateBatchRecordSchema=exports_external.object({batchId:exports_external.string().min(1),phase:exports_external.enum(["stage-b-reviewer","stage-b-test","closeout-reviewer","closeout-critic"]),laneId:exports_external.string().min(1),itemIds:exports_external.array(exports_external.string().min(1)).min(1),revisionDigest:exports_external.string().min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackReadyToPublishRecordSchema=exports_external.object({revisionDigest:exports_external.string().min(1),localHead:exports_external.string().min(1),remoteName:exports_external.string().min(1),remoteBranchRef:exports_external.string().startsWith("refs/heads/"),remoteRef:exports_external.string().startsWith("refs/remotes/"),validatedAt:exports_external.string().min(1)}).strict(),PrReviewValidationBatchRecordSchema=exports_external.object({batchId:exports_external.string().min(1),phase:exports_external.enum(["council","reviewer","critic"]),lanes:exports_external.array(exports_external.object({laneId:exports_external.string().min(1),workflowLane:exports_external.string().min(1),reviewItemIds:exports_external.array(exports_external.string().min(1)).min(1).optional()}).strict()).min(1),validatedAt:exports_external.string().min(1)}).strict(),PrFeedbackScopeDeclarationRecordSchema=exports_external.object({taskId:exports_external.string().regex(/^\d+\.\d+(?:\.\d+)*$/),files:exports_external.array(exports_external.string().min(1)).min(1).max(1e4),revisionDigest:exports_external.string().min(1),declaredAt:exports_external.string().min(1),consumedByCallId:exports_external.string().min(1).optional()}).strict(),PrWorkflowCheckoutRecoveryRecordSchema=exports_external.object({code:exports_external.enum(["UNMERGED_INDEX","GIT_OPERATION_IN_PROGRESS","DIRTY_SUBMODULE","SWARM_STATE_TRACKING_ERROR","GIT_STATE_INDETERMINATE"]),retryable:exports_external.literal(!1),requiredAction:exports_external.string().min(1).max(2000),evidence:exports_external.object({worktreeRoot:exports_external.string().nullable(),gitDir:exports_external.string().nullable(),operations:exports_external.array(exports_external.string().min(1)).max(16),unmergedCodes:exports_external.array(exports_external.string().min(1)).max(16),paths:exports_external.array(exports_external.string()).max(20),trackedCount:exports_external.number().int().nonnegative(),untrackedCount:exports_external.number().int().nonnegative(),pathsTruncated:exports_external.boolean(),detail:exports_external.string().max(1000).optional()}).strict(),detectedAt:exports_external.string().min(1)}).strict(),PrFeedbackReviewHandoffRecordSchema=exports_external.object({path:exports_external.string().min(1).max(512),runId:exports_external.string().min(1).max(128),sourcePrHeadSha:exports_external.string().regex(/^[0-9a-f]{6,64}$/i),prUrl:exports_external.string().url().max(2000),findingIds:exports_external.array(exports_external.string().min(1).max(128)).min(1).max(1000),digest:exports_external.string().regex(/^[0-9a-f]{64}$/),sourceWorkflowInstanceId:exports_external.string().min(1).max(128),provenance:exports_external.enum(["active-review-v1","external-v1"])}).strict(),PrWorkflowGateStateSchema=exports_external.object({schemaVersion:exports_external.literal(GATE_SCHEMA_VERSION),revision:exports_external.number().int().nonnegative().default(0),workflowInstanceId:exports_external.string().min(1).max(128).optional(),sessionID:exports_external.string().min(1),mode:exports_external.enum(["PR_REVIEW","PR_FEEDBACK"]),activatedAt:exports_external.string().min(1),updatedAt:exports_external.string().min(1),prHeadSha:exports_external.string().min(1).optional(),prReviewBaseRef:exports_external.string().min(1).optional(),prReviewBaseSha:exports_external.string().min(1).optional(),prReviewDepthTier:exports_external.enum(["S","M","L"]).optional(),prReviewDiffStats:exports_external.object({changedLines:exports_external.number().int().nonnegative(),changedFiles:exports_external.number().int().nonnegative(),hasSubmoduleChange:exports_external.boolean().default(!1)}).strict().optional(),prReviewBaseDispatches:exports_external.array(PrReviewBaseDispatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prReviewBaseDispatch:PrReviewBaseDispatchRecordSchema.optional(),prReviewTriggerLedger:exports_external.array(PrReviewInlineTriggerRowSchema).length(PR_REVIEW_REQUIRED_TRIGGER_IDS.length).optional(),prReviewTriggerEvalPath:exports_external.string().min(1).optional(),prReviewValidationBatches:exports_external.array(PrReviewValidationBatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prReviewArtifactRunId:exports_external.string().min(1).optional(),prReviewFindingsPath:exports_external.string().min(1).optional(),prReviewArtifactBoundaries:exports_external.array(exports_external.enum(["post_explorer","post_reviewer","post_critic"])).max(3).optional(),prReviewHandoffPath:exports_external.string().min(1).optional(),prReviewHandoffRequired:exports_external.boolean().optional(),checkoutRecovery:PrWorkflowCheckoutRecoveryRecordSchema.optional(),prFeedbackTargetUrl:exports_external.string().url().max(2000).optional(),prFeedbackReviewHandoff:PrFeedbackReviewHandoffRecordSchema.optional(),prFeedbackInventory:exports_external.array(exports_external.string().min(1)).min(1).optional(),prFeedbackVerifications:exports_external.array(PrFeedbackVerificationRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prFeedbackVerification:PrFeedbackVerificationRecordSchema.optional(),prFeedbackStageA:PrFeedbackStageARecordSchema.optional(),prFeedbackGateBatches:exports_external.array(PrFeedbackGateBatchRecordSchema).max(MAX_WORKFLOW_BATCHES).optional(),prFeedbackReadyToPublish:PrFeedbackReadyToPublishRecordSchema.optional(),prFeedbackScopes:exports_external.array(PrFeedbackScopeDeclarationRecordSchema).max(MAX_WORKFLOW_BATCHES).optional()}).passthrough();PR_FEEDBACK_PHASE_ORDER=["stage-b-reviewer","stage-b-test","closeout-reviewer","closeout-critic"];PR_FEEDBACK_PHASE_ROLE={"stage-b-reviewer":"reviewer","stage-b-test":"test_engineer","closeout-reviewer":"reviewer","closeout-critic":"critic"};PR_REVIEW_HANDOFF_RELATIVE_PATH_PATTERN=/^pr-review\/([A-Za-z0-9][A-Za-z0-9._-]{0,127})\/feedback-handoff\.json$/,PrReviewFeedbackHandoffArtifactSchema=exports_external.object({schema_version:exports_external.literal(1),run_id:exports_external.string().min(1).max(128),pr_head_sha:exports_external.string().regex(/^[0-9a-f]{6,64}$/i),created_at:exports_external.string().datetime(),pr_url:exports_external.string().url().max(2000),finding_ids:exports_external.array(exports_external.string().min(1).max(128)).min(1).max(1000),summary:exports_external.string().min(1).max(20000),provenance:exports_external.array(exports_external.string().min(1).max(4000)).min(1).max(1000)}).strict();PrReviewFindingProjectionSchema=exports_external.object({finding_id:exports_external.string().min(1).max(128),status:exports_external.enum(["PENDING","CONFIRMED","DISPROVED","PRE_EXISTING"]),next_action:exports_external.enum(["route_to_reviewer","route_to_critic","report","suppress_with_reason","handoff_to_feedback"])}).passthrough();_test_exports={workflowGateStateRelativePath,workflowGateStateLockRelativePath,workflowCheckoutMutationLockRelativePath,withPrWorkflowCheckoutMutationLock,resetTrackedStateCache:()=>{trackedStatesByProjectSession.clear(),pendingStateMutationsByProjectSession.clear(),pendingCheckoutMutationsByProject.clear(),completedCheckoutLockOwners.clear(),_test_exports.beforeTerminalClear=void 0,_test_exports.beforePrFeedbackTransitionLock=void 0,_test_exports.beforePrFeedbackTrackingSwitch=void 0,_test_exports.afterPrFeedbackTrackingSwitch=void 0,_test_exports.beforePrFeedbackTrackingPersist=void 0,_test_exports.beforeBoundedSwarmFileOpen=void 0,_test_exports.beforeSessionStateLockWrite=void 0,_test_exports.beforeCheckoutLockWrite=void 0,_test_exports.beforeSafeDirectoryCreate=void 0,_test_exports.beforeAtomicTempWrite=void 0,_test_exports.beforeAtomicRename=void 0,_test_exports.openCheckoutLock=openCheckoutLockFile,_test_exports.removeCheckoutLock=removeCheckoutLockFile,_test_exports.checkoutMutationActionTimeoutMs=CHECKOUT_MUTATION_ACTION_TIMEOUT_MS},beforeTerminalClear:void 0,beforePrFeedbackTransitionLock:void 0,beforePrFeedbackTrackingSwitch:void 0,afterPrFeedbackTrackingSwitch:void 0,beforePrFeedbackTrackingPersist:void 0,beforeBoundedSwarmFileOpen:void 0,beforeSessionStateLockWrite:void 0,beforeCheckoutLockWrite:void 0,beforeSafeDirectoryCreate:void 0,beforeAtomicTempWrite:void 0,beforeAtomicRename:void 0,openCheckoutLock:openCheckoutLockFile,removeCheckoutLock:removeCheckoutLockFile,checkoutMutationActionTimeoutMs:CHECKOUT_MUTATION_ACTION_TIMEOUT_MS,resolveCurrentGitHead,resolveCurrentGitHeadAsync,resolveCurrentUpstreamPushTarget,resolveCurrentUpstreamPushTargetAsync,resolveCurrentUpstreamRemoteRef,resolveExactRemoteBranchHead,resolveExactRemoteBranchHeadAsync,resolveCommitCountSince,resolveCommitCountSinceAsync,resolveIsWorkingTreeClean,resolveIsWorkingTreeCleanAsync,resolveIsExactSingleChildCommit,resolveIsExactSingleChildCommitAsync,resolvePrReviewDiffStats,resolvePrReviewDiffStatsAsync,resolvePrWorkflowRevisionDigest,resolveRemoteRefsContainingHead,resolveRemoteRefsContainingHeadAsync,parseCriticVerdict,isProcessAlive,isSafeStandaloneGitCommit,rename:fsp3.rename,nowMs:()=>Date.now()};PR_WORKFLOW_SHARED_CONTROLLER_TOOLS=new Set(["abort_pr_workflow","collect_lane_results","complete_pr_workflow","dispatch_lanes_async","prepare_pr_workflow_checkout"]),PR_REVIEW_CONTROLLER_TOOLS=new Set(["parse_lane_candidates","write_pr_review_artifact","write_pr_review_trigger_eval"]),PR_FEEDBACK_CONTROLLER_TOOLS=new Set(["prepare_pr_feedback_scope","run_pr_feedback_stage_a"]);PR_REVIEW_READ_ONLY_TOOL_NAMES=new Set(["ast_grep_search","codesearch","glob","grep","list","lsp","open","read","search","skill","tree","view","web_fetch","web_search","webfetch","websearch"]);PR_WORKFLOW_CD_PREFIX_PATTERN=/^cd\s+(?:\/d\s+)?(?:"[A-Za-z0-9 _.\\/:~+-]+"|'[A-Za-z0-9 _.\\/:~+-]+'|[A-Za-z0-9_.\\/:~+-]+)\s*&&\s*/i,PR_WORKFLOW_TRAILING_STDERR_MERGE_PATTERN=/\s+2>&1\s*$/,PR_WORKFLOW_GIT_DIR_OVERRIDE_PATTERN=/^[Gg][Ii][Tt](?: -C (?:"[^"]+"|'[^']+'|\S+))* (.+)$/,PR_WORKFLOW_GIT_HAS_DIR_OVERRIDE_PATTERN=/^[Gg][Ii][Tt] -C /;REVIEWER_CLASSIFICATIONS=new Set(["CONFIRMED","DISPROVED","UNVERIFIED","PRE_EXISTING"]),REVIEWER_EVIDENCE_TYPES=new Set(["STRUCTURALLY_PROVEN","EXECUTION_PROVEN","STATIC_TRACE_PROVEN","PLAUSIBLE_BUT_UNVERIFIED"]),REVIEW_SEVERITIES=new Set(["CRITICAL","HIGH","MEDIUM","LOW","INFO","NONE"]),CRITIC_STATUSES=new Set(["UPHELD","DOWNGRADED","DISPROVED","NEEDS_MORE_EVIDENCE"]),FEEDBACK_CLASSIFICATIONS=new Set(["CONFIRMED","PARTIAL","DISPROVED","PRE_EXISTING","NEEDS_MORE_EVIDENCE","NEEDS_USER_DECISION"]);PrWorkflowCheckoutMutationTimeoutError=class PrWorkflowCheckoutMutationTimeoutError extends Error{phase;code="PR_WORKFLOW_CHECKOUT_MUTATION_TIMEOUT";retryable=!1;constructor(phase){super(phase==="queue"?"BLOCKED: timed out waiting for the active PR workflow checkout mutation; the existing owner still holds serialization and must settle before retrying":"BLOCKED: PR workflow checkout mutation exceeded its execution deadline; serialization remains held until the in-flight action actually settles");this.phase=phase;this.name="PrWorkflowCheckoutMutationTimeoutError"}}});async function handleAbortPrWorkflowCommand(directory,args2,sessionID){let tokens=(args2??[]).filter((token)=>token.trim().length>0),modeToken=tokens[0]?.toUpperCase(),knownMode=modeToken&&KNOWN_MODES.has(modeToken)?modeToken:void 0,reasonStartIndex=knownMode?1:0,reason=tokens.slice(reasonStartIndex).join(" ").trim().slice(0,500)||void 0;if(modeToken&&!knownMode)return`Error: Unknown mode "${modeToken}". Expected PR_REVIEW or PR_FEEDBACK.
|
|
186
186
|
|
|
187
187
|
${USAGE}`;if(!sessionID?.trim())return`Error: abort-pr-workflow requires an active sessionID.
|
|
188
188
|
|
|
@@ -6059,14 +6059,14 @@ ${promptRaw}`,log("[delegate-directive-injection] injected",{caller_agent:caller
|
|
|
6059
6059
|
${errorSummary}`)}}}}init_pending_delegations();init_constants();init_file_locks();init_state2();init_recovery();init_utils();init_core3();init_merge();init_worktree_merge_status();init_worktree_ownership_tag();init_worktree_provisioning_owner();import*as fs119 from"node:fs";import*as fsPromises10 from"node:fs/promises";import*as path213 from"node:path";var INIT_ORPHAN_RECOVERY_TIMEOUT_MS=1e4,OWNERSHIP_TAG_SCAN_TIMEOUT_MS2=2000;async function listOwnershipTagSessionIds(directory){let scan=await scanBackgroundWorktreeOwnershipTagsForRecovery(directory);if(scan.status==="uncertain")return scan;return{status:"ok",sessionIds:[...new Set(scan.owners.map((owner)=>owner.sessionId))]}}var ORPHAN_RECOVERY_LOCK_FILE=WORKTREE_LIFECYCLE_LOCK_FILE,_internals143={rmSync:fs119.rmSync,removeWorktree,isLocked,listActiveLocks,tryAcquireLock,listOwnershipTagSessionIds,scanDelegationsForRecovery,scanDelegationFallbacksForRecovery,scanWorktreeMergeFailuresForRecovery,scanWorktreeProvisioningOwnersForRecovery};async function writeAdvisoryFile(directory,cleanupResult,warnings,attempted,removedWorktrees=[]){let advisoryPath=path213.join(directory,".swarm","advisories","init-orphan-recovery.json"),advisory={initTimestamp:new Date().toISOString(),warnings,errors:cleanupResult.errors,reclaimed:{removedBranches:cleanupResult.removed,removedWorktrees,prunedWorktrees:attempted},...cleanupResult.skippedRecoveryBranches&&cleanupResult.skippedRecoveryBranches.length>0?{preservedRecoveryBranches:cleanupResult.skippedRecoveryBranches}:{},...cleanupResult.recoveryReadError?{recoveryReadError:!0,note:"skipped all lane-branch deletions this pass because .swarm/recovery/ was unreadable (fail-safe)"}:{}};try{await fsPromises10.mkdir(path213.dirname(advisoryPath),{recursive:!0}),await fsPromises10.writeFile(advisoryPath,JSON.stringify(advisory,null,2),"utf-8")}catch{log("initOrphanRecovery advisory file write failed (non-fatal)")}}async function enumerateOrphanedWorktreeDirs(directory,activeSessionIds,protectedWorktreePaths=new Set){let orphanedDirs=[],worktreeRoot=path213.resolve(path213.dirname(directory),SWARM_WORKTREE_DIR_NAME),entries;try{entries=await fsPromises10.readdir(worktreeRoot,{withFileTypes:!0})}catch{return[]}for(let entry of entries){if(!entry.isDirectory())continue;let sessionId=entry.name;if(activeSessionIds.includes(sessionId))continue;let sessionEntries;try{sessionEntries=await fsPromises10.readdir(path213.join(worktreeRoot,sessionId),{withFileTypes:!0})}catch{continue}for(let laneEntry of sessionEntries){if(!laneEntry.isDirectory())continue;let worktreePath=path213.join(worktreeRoot,sessionId,laneEntry.name);if(protectedWorktreePaths.has(path213.resolve(worktreePath)))continue;orphanedDirs.push(worktreePath)}}return orphanedDirs}async function isCrossProcessLockHeld(directory){if(_internals143.isLocked(directory,ORPHAN_RECOVERY_LOCK_FILE))return!0;if(_internals143.listActiveLocks(directory).length>0)return!0;return!1}async function removeOrphanedWorktreeDir(worktreePath,projectRoot){if(!fs119.existsSync(path213.join(worktreePath,".git")))try{_internals143.rmSync(worktreePath,{recursive:!0,force:!0});return}catch(error93){return error93 instanceof Error?error93.message:String(error93)}let removeResult=await _internals143.removeWorktree(worktreePath,projectRoot);if(!("error"in removeResult))return;try{_internals143.rmSync(worktreePath,{recursive:!0,force:!0});return}catch{return removeResult.error}}async function crossProcessAdvisoryResult(directory,warning){let result={attempted:!0,crossProcessLockHeld:!0,warnings:[warning],orphanedBranches:[],removedWorktrees:[],prunedWorktrees:!1};return await writeAdvisoryFile(directory,{removed:[],skipped:[],errors:[]},result.warnings,!1,[]),result}function worktreePathKey(worktreePath,directory){let absolutePath2=path213.isAbsolute(worktreePath)?worktreePath:path213.resolve(directory,worktreePath),normalized=path213.normalize(absolutePath2);return process.platform==="win32"?normalized.toLowerCase():normalized}async function runInitOrphanRecovery(directory){let result,recoveryLockRelease;try{if(await isCrossProcessLockHeld(directory))return crossProcessAdvisoryResult(directory,"Cross-process lock held — another opencode process may be active. "+"Skipping destructive cleanup to preserve its worktrees/branches. Run '/swarm status' or check '.swarm/locks/' to identify active processes.");let lockAcquireResult=await _internals143.tryAcquireLock(directory,ORPHAN_RECOVERY_LOCK_FILE,"init-orphan-recovery","init");if(!lockAcquireResult.acquired)return crossProcessAdvisoryResult(directory,"Cross-process lifecycle lock was acquired by another process during init; skipping destructive cleanup to preserve its worktrees/branches.");recoveryLockRelease=lockAcquireResult.lock._release;let activeSessionIds=Array.from(swarmState.agentSessions.keys()),provisioningOwnerScan=await withTimeout(Promise.resolve(_internals143.scanWorktreeProvisioningOwnersForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("worktree provisioning ownership scan exceeded its bounded init budget"));if(provisioningOwnerScan.status==="uncertain")throw Error(`worktree provisioning ownership state is uncertain; destructive orphan cleanup skipped: ${provisioningOwnerScan.reason}`);for(let owner of provisioningOwnerScan.owners){if(!activeSessionIds.includes(owner.worktreeSessionId))activeSessionIds.push(owner.worktreeSessionId);if(!activeSessionIds.includes(owner.parentSessionId))activeSessionIds.push(owner.parentSessionId)}let ownershipTagScan=await withTimeout(_internals143.listOwnershipTagSessionIds(directory),OWNERSHIP_TAG_SCAN_TIMEOUT_MS2,Error("background ownership tag scan exceeded its bounded init budget"));if(ownershipTagScan.status==="uncertain")throw Error(`background ownership tag state is uncertain; destructive orphan cleanup skipped: ${ownershipTagScan.reason}`);for(let sessionId of ownershipTagScan.sessionIds)if(!activeSessionIds.includes(sessionId))activeSessionIds.push(sessionId);let fallbackOwnerScan=await withTimeout(_internals143.scanDelegationFallbacksForRecovery(directory),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("background delegation fallback ownership scan exceeded its bounded init budget"));if(fallbackOwnerScan.status==="uncertain")throw Error(`background fallback ownership state is uncertain; destructive orphan cleanup skipped: ${fallbackOwnerScan.reason}`);let primaryOwnerScan=await withTimeout(Promise.resolve(_internals143.scanDelegationsForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("background primary ownership scan exceeded its bounded init budget"));if(primaryOwnerScan.status==="uncertain")throw Error(`background primary ownership state is uncertain; destructive orphan cleanup skipped: ${primaryOwnerScan.reason}`);let isUnsettledWorktreeOwner=(record3)=>Boolean(record3.worktree)&&!(record3.coderSettlement?.state==="settled"&&record3.coderSettlement.outcome?.kind==="standard-worktree"&&(record3.coderSettlement.outcome.result==="merged"||record3.coderSettlement.outcome.result==="unchanged")),durableWorktreeOwners=primaryOwnerScan.owners.filter(isUnsettledWorktreeOwner),mergeOwnerScan=await withTimeout(Promise.resolve(_internals143.scanWorktreeMergeFailuresForRecovery(directory)),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error("worktree merge ownership scan exceeded its bounded init budget"));if(mergeOwnerScan.status==="uncertain")throw Error(`worktree merge ownership state is uncertain; destructive orphan cleanup skipped: ${mergeOwnerScan.reason}`);let allDurableOwners=[...durableWorktreeOwners,...fallbackOwnerScan.owners.map((artifact)=>artifact.record).filter(isUnsettledWorktreeOwner)],preservedMergeFailures=mergeOwnerScan.failures.map(([,failure])=>failure).filter((failure)=>typeof failure.worktreePath==="string"),protectedWorktreePaths=new Set([...allDurableOwners.map((record3)=>record3.worktree?.worktreePath),...preservedMergeFailures.map((failure)=>failure.worktreePath)].filter((value)=>typeof value==="string").map((value)=>path213.resolve(value)));for(let owner of allDurableOwners){let worktreeSessionId=owner.worktree?.worktreeSessionId;if(worktreeSessionId&&!activeSessionIds.includes(worktreeSessionId))activeSessionIds.push(worktreeSessionId);if(!activeSessionIds.includes(owner.parentSessionId))activeSessionIds.push(owner.parentSessionId)}for(let failure of preservedMergeFailures){let segments=failure.branch?.split("/")??[],worktreeSessionId=segments[0]==="swarm"&&segments.length>=4?segments[2]:segments[0]==="swarm-lane"&&segments.length>=3?segments[1]:void 0;if(worktreeSessionId&&!activeSessionIds.includes(worktreeSessionId))activeSessionIds.push(worktreeSessionId)}let orphanedWorktreeDirs=await withTimeout(enumerateOrphanedWorktreeDirs(directory,activeSessionIds,protectedWorktreePaths),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during worktree enumeration; continuing without orphan reclamation`)),removedWorktrees=[],worktreeWarnings=[],recoveryRecords=listRecoveryRecords(directory),recoveryReadError=recoveryReadErrored(directory),recoveryWorktreePaths=new Set(recoveryRecords.map((record3)=>worktreePathKey(record3.worktreePath,directory)));if(recoveryReadError)worktreeWarnings.push("Recovery records are unreadable or fail schema validation; skipped all orphaned worktree deletion this pass (fail-safe).");else for(let worktreePath of orphanedWorktreeDirs){if(recoveryWorktreePaths.has(worktreePathKey(worktreePath,directory))){worktreeWarnings.push(`Preserved recovery worktree "${worktreePath}"; an unresolved recovery record still references it.`);continue}let error93=await removeOrphanedWorktreeDir(worktreePath,directory);if(error93)worktreeWarnings.push(`Could not reclaim orphaned worktree "${worktreePath}": ${error93}`);else removedWorktrees.push(worktreePath)}let cleanupResult=await withTimeout(cleanupOrphanedBranches(directory,activeSessionIds),INIT_ORPHAN_RECOVERY_TIMEOUT_MS,Error(`runInitOrphanRecovery exceeded ${INIT_ORPHAN_RECOVERY_TIMEOUT_MS}ms budget during branch cleanup; continuing without orphan reclamation`)),branchWarnings=cleanupResult.errors.map((e)=>`Could not delete orphaned branch "${e.branch}": ${e.error}`),allWarnings=[...worktreeWarnings,...branchWarnings];result={attempted:!0,crossProcessLockHeld:!1,warnings:allWarnings,orphanedBranches:cleanupResult.removed,removedWorktrees,prunedWorktrees:cleanupResult.recoveryReadError!==!0},await writeAdvisoryFile(directory,cleanupResult,allWarnings,!0,removedWorktrees)}catch(err){let msg=err instanceof Error?err.message:String(err);log("initOrphanRecovery timed out or failed (non-fatal)",{error:msg}),result={attempted:!1,crossProcessLockHeld:!1,warnings:[`Orphan recovery timed out or failed: ${msg}`],orphanedBranches:[],removedWorktrees:[],prunedWorktrees:!1,diagnostic:{file:".swarm/advisories/init-orphan-recovery.json",reason:msg}},await writeAdvisoryFile(directory,{removed:[],skipped:[],skippedRecoveryBranches:[],errors:[]},result.warnings,!1,[])}finally{try{await recoveryLockRelease?.()}catch{}}return result}init_state2();import*as fs120 from"node:fs/promises";import*as path214 from"node:path";var ADVISORY_FILENAME="init-orphan-recovery.json";function createInitOrphanRecoveryAdvisoryHook(directory){let consumedBySession=new Set;async function readAdvisoryFile(){let advisoryPath=path214.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{let content=await fs120.readFile(advisoryPath,"utf-8");return JSON.parse(content)}catch{return null}}async function deleteAdvisoryFile(){let advisoryPath=path214.join(directory,".swarm","advisories",ADVISORY_FILENAME);try{await fs120.unlink(advisoryPath)}catch{}}function formatError3(error93){return`ORPHAN_RECOVERY_ERROR: Could not reclaim branch "${error93.branch}": ${error93.error}`}async function messagesTransform(_input,output){let messages=output.messages;if(!messages||messages.length===0)return;let sessionId=messages[messages.length-1]?.info?.sessionID;if(!sessionId)return;let activeAgent=swarmState.activeAgent.get(sessionId),session=swarmState.agentSessions.get(sessionId),ORCHESTRATOR_NAME2="Architect";if(!(activeAgent?activeAgent===ORCHESTRATOR_NAME2||activeAgent.endsWith("_Architect"):session?session.agentName===ORCHESTRATOR_NAME2||session.agentName.endsWith("_Architect"):!1))return;if(consumedBySession.has(sessionId))return;let advisory=await readAdvisoryFile();if(!advisory)return;consumedBySession.add(sessionId),await deleteAdvisoryFile();let reclaimedForGate=advisory.reclaimed;if(!((advisory.warnings?.length??0)>0||(advisory.errors?.length??0)>0||(reclaimedForGate?.removedBranches?.length??0)>0||(reclaimedForGate?.removedWorktrees?.length??0)>0))return;let targetSession=ensureAgentSession(sessionId),timestamp=advisory.initTimestamp?new Date(advisory.initTimestamp).toLocaleString():"unknown";pushAdvisory(targetSession,`[INIT ORPHAN RECOVERY] Plugin init detected the following at ${timestamp}:`);for(let warning of advisory.warnings??[])pushAdvisory(targetSession,` WARNING: ${warning}`);for(let err of advisory.errors??[])pushAdvisory(targetSession,` ERROR: ${formatError3(err)}`);let reclaimed=advisory.reclaimed;if((reclaimed?.removedBranches?.length??0)>0)pushAdvisory(targetSession,` Reclaimed ${reclaimed.removedBranches.length} orphaned branch(es): ${reclaimed.removedBranches.join(", ")}`);if(reclaimed?.removedWorktrees&&reclaimed.removedWorktrees.length>0)pushAdvisory(targetSession,` Reclaimed ${reclaimed.removedWorktrees.length} orphaned worktree directory(ies): ${reclaimed.removedWorktrees.join(", ")}`);if(reclaimed?.prunedWorktrees)pushAdvisory(targetSession," Stale worktree metadata pruned.")}return{messagesTransform}}init_delegation_gate();import*as fs121 from"node:fs";import*as path216 from"node:path";function computeNextMode(params){let{issueReference,traceState,workflowArtifacts}=params,noop={nextMode:null,directive:null,nextLastTransition:traceState.lastTransition,nextCompleted:traceState.completed};if(!issueReference||issueReference.flags.trace!==!0)return noop;if(traceState.completed)return noop;if(workflowArtifacts.specIssueNumber===null||workflowArtifacts.specIssueNumber!==issueReference.number||traceState.issueNumber!==issueReference.number)return noop;if(!workflowArtifacts.specExists)return noop;if(!workflowArtifacts.planExists&&(traceState.lastTransition===null||traceState.lastTransition==="ISSUE_INGEST_TO_PLAN")){if(traceState.lastTransition==="ISSUE_INGEST_TO_PLAN")return noop;return{nextMode:"PLAN",directive:null,nextLastTransition:"ISSUE_INGEST_TO_PLAN",nextCompleted:!1}}if(!workflowArtifacts.criticApproved)return noop;if(workflowArtifacts.planExists&&!workflowArtifacts.allPhasesComplete){if(traceState.lastTransition==="PLAN_TO_EXECUTE")return noop;return{nextMode:"EXECUTE",directive:null,nextLastTransition:"PLAN_TO_EXECUTE",nextCompleted:!1}}if(!workflowArtifacts.planExists)return noop;if(traceState.lastTransition==="EXECUTE_TO_COMMIT")return noop;return{nextMode:null,directive:"All phases complete. Compose commit-pr to publish the PR. Read .swarm/issue-reference.json for Closes #N.",nextLastTransition:"EXECUTE_TO_COMMIT",nextCompleted:!0}}init_manager();import{existsSync as existsSync105,mkdirSync as mkdirSync54,readFileSync as readFileSync80,renameSync as renameSync34,unlinkSync as unlinkSync35,writeFileSync as writeFileSync36}from"node:fs";import*as path215 from"node:path";async function _defaultLoadPlanFromLedger(directory){return loadPlanJsonOnly(directory)}var _internals144={readFileSync:readFileSync80,writeFileSync:writeFileSync36,existsSync:existsSync105,renameSync:renameSync34,mkdirSync:mkdirSync54,unlinkSync:unlinkSync35,loadPlanFromLedger:_defaultLoadPlanFromLedger};function isPhaseComplete(status){return status==="complete"||status==="completed"}function isValidIssueReference(obj){if(typeof obj!=="object"||obj===null)return!1;let o=obj;if(typeof o.url!=="string"||!o.url.startsWith("https://github.com/"))return!1;return typeof o.owner==="string"&&typeof o.repo==="string"&&typeof o.number==="number"&&typeof o.timestamp==="string"&&typeof o.flags==="object"&&o.flags!==null}function isValidTraceState(obj){if(typeof obj!=="object"||obj===null)return!1;let o=obj;return typeof o.issueNumber==="number"&&(o.lastTransition===null||typeof o.lastTransition==="string")&&typeof o.completed==="boolean"}function readIssueReference(directory){try{let filePath=path215.join(directory,".swarm","issue-reference.json"),raw=_internals144.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(!isValidIssueReference(parsed))return null;return parsed}catch{return null}}function readTraceState(directory){let defaultState={issueNumber:0,lastTransition:null,completed:!1};try{let filePath=path215.join(directory,".swarm","issue-trace-state.json"),raw=_internals144.readFileSync(filePath,"utf-8"),parsed=JSON.parse(raw);if(!isValidTraceState(parsed))return defaultState;return parsed}catch{return defaultState}}function writeTraceState(directory,state){let swarmDir=path215.join(directory,".swarm");_internals144.mkdirSync(swarmDir,{recursive:!0});let finalPath=path215.join(swarmDir,"issue-trace-state.json"),tmpPath=path215.join(swarmDir,`issue-trace-state.tmp.${process.pid}.${Date.now()}.json`);_internals144.writeFileSync(tmpPath,JSON.stringify(state,null,2),"utf-8");try{_internals144.renameSync(tmpPath,finalPath)}catch{try{_internals144.unlinkSync(finalPath)}catch{}try{_internals144.renameSync(tmpPath,finalPath)}catch(retryErr){try{_internals144.unlinkSync(tmpPath)}catch{}throw retryErr}}}function readSpecIssueNumber(directory){try{let filePath=path215.join(directory,".swarm","spec.md"),raw=_internals144.readFileSync(filePath,"utf-8"),sectionStart=raw.indexOf("## Source Issue");if(sectionStart===-1)return null;let nextHeading=raw.indexOf(`
|
|
6060
6060
|
## `,sectionStart+14),sectionEnd=nextHeading===-1?raw.length:nextHeading,section=raw.slice(sectionStart,sectionEnd),numberMatch=section.match(/-\s+Number:\s*(\d+)/);if(numberMatch)return parseInt(numberMatch[1],10);let urlMatch=section.match(/-\s+URL:.*\/issues\/(\d+)/);if(urlMatch)return parseInt(urlMatch[1],10);return null}catch{return null}}async function readPlanPhaseStatus(directory){let plan=await _internals144.loadPlanFromLedger(directory);if(!plan||plan.phases.length===0)return{allComplete:!1};return{allComplete:plan.phases.every((phase)=>isPhaseComplete(phase.status))}}function specExists(directory){return _internals144.existsSync(path215.join(directory,".swarm","spec.md"))}function planExists(directory){return _internals144.existsSync(path215.join(directory,".swarm","plan.json"))}var _internals145={readIssueReference,readTraceState,writeTraceState,readSpecIssueNumber,readPlanPhaseStatus,specExists,planExists,isPlanCriticApproved},cachedApproval=null;async function boundedApprovalCheck(directory,timeoutMs){try{let ledgerPath=path216.join(directory,".swarm","plan-ledger.jsonl"),currentSize=-1;try{currentSize=fs121.statSync(ledgerPath).size}catch{let timeout=new Promise((resolve80)=>{setTimeout(()=>resolve80(!1),timeoutMs)});return await Promise.race([_internals145.isPlanCriticApproved(directory),timeout])}if(cachedApproval&&cachedApproval.dir===directory&&cachedApproval.size===currentSize)return cachedApproval.result;let timer;try{let timeout=new Promise((resolve80)=>{timer=setTimeout(()=>resolve80(!1),timeoutMs)}),result=await Promise.race([_internals145.isPlanCriticApproved(directory),timeout]);return cachedApproval={dir:directory,size:currentSize,result},result}finally{if(timer!==void 0)clearTimeout(timer)}}catch{return!1}}function createIssueTraceHook(_config,directory,approvalTimeoutMs=5000){return{messagesTransform:async(_input,output)=>{try{let issueRef=_internals145.readIssueReference(directory);if(!issueRef||issueRef.flags.trace!==!0)return;let traceState=_internals145.readTraceState(directory),_specExists=_internals145.specExists(directory),_specIssueNumber=_internals145.readSpecIssueNumber(directory),_planExists=_internals145.planExists(directory),_criticApproved=await boundedApprovalCheck(directory,approvalTimeoutMs),_allPhasesComplete=(await _internals145.readPlanPhaseStatus(directory)).allComplete,result=computeNextMode({issueReference:issueRef,traceState,workflowArtifacts:{specExists:_specExists,specIssueNumber:_specIssueNumber,planExists:_planExists,criticApproved:_criticApproved,allPhasesComplete:_allPhasesComplete}});if(result.nextMode===null&&result.directive===null)return;let finalDirective=result.directive?result.directive.replace("#N",`#${issueRef.number}`):null,messagesToAdd=[];if(result.nextMode!==null)messagesToAdd.push({role:"system",content:[{type:"text",text:`[MODE: ${result.nextMode}]`}]});if(finalDirective!==null)messagesToAdd.push({role:"system",content:[{type:"text",text:finalDirective}]});_internals145.writeTraceState(directory,{issueNumber:traceState.issueNumber,lastTransition:result.nextLastTransition,completed:result.nextCompleted});let out=output;if(out.messages)out.messages.push(...messagesToAdd)}catch{}}}}init_schema();init_state2();init_logger();import{appendFile as appendFile22,mkdir as mkdir45}from"node:fs/promises";import*as path217 from"node:path";var HIGH_RISK_TOOLS=new Set(["save_plan","update_task_status","phase_complete","task","Task","skill_regenerate","skill_retire"]),DEFAULT_MAX_GATE_DENIALS=5,DEFAULT_GATE_STALENESS_MS=600000;async function knowledgeApplicationGateBefore(directory,input,config3){if(!config3.enabled)return;let toolName=typeof input.tool==="string"?input.tool:"";if(!(config3.high_risk_tools?new Set(config3.high_risk_tools):HIGH_RISK_TOOLS).has(toolName))return;let agentRaw=typeof input.agent==="string"?input.agent:"";if(!agentRaw)return;if(stripKnownSwarmPrefix(agentRaw)!=="architect")return;let sessionID=typeof input.sessionID==="string"?input.sessionID:void 0;if(!sessionID){if(config3.mode==="enforce")throw Error("KNOWLEDGE_ENFORCE_GATE_DENY: missing sessionID on tool.execute.before; refusing to evaluate critical-directive ack state");_internals146.writeWarnEvent(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,reason:"missing_sessionID",mode:config3.mode}).catch(()=>{});return}let cached3=swarmState.currentCriticalShownIds.get(sessionID);if(!cached3||cached3.ids.length===0){clearGateDenialCount(sessionID);return}let ackedIds=new Set;for(let id of cached3.ids)for(let result of["applied","ignored","violated"]){let key=buildAckDedupKey(sessionID,id,result);if(swarmState.knowledgeAckDedup.has(key)){ackedIds.add(id);break}}let unacked=cached3.ids.filter((id)=>!ackedIds.has(id));if(unacked.length===0){clearGateDenialCount(sessionID);return}if(config3.mode==="enforce"&&config3.critical_requires_ack){let maxDenials=config3.max_gate_denials??DEFAULT_MAX_GATE_DENIALS,stalenessMs=config3.gate_staleness_ms??DEFAULT_GATE_STALENESS_MS,age=Date.now()-cached3.generatedAt;if(age>stalenessMs){for(let id of unacked)addKnowledgeAckDedup(buildAckDedupKey(sessionID,id,"applied"));clearCriticalShownIds(sessionID),clearGateDenialCount(sessionID),await writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_staleness_clear",tool:toolName,agent:agentRaw,sessionID,cleared_ids:unacked,age_ms:age,staleness_threshold_ms:stalenessMs}).catch((err)=>{warn(`[knowledge-application-gate] staleness-clear audit write failed: ${err instanceof Error?err.message:String(err)}`)});return}let directiveKey=buildGateDenialDirectiveKey(cached3.ids),denials=incrementGateDenialCount(sessionID,directiveKey);if(denials>maxDenials){for(let id of unacked)addKnowledgeAckDedup(buildAckDedupKey(sessionID,id,"applied"));clearCriticalShownIds(sessionID),clearGateDenialCount(sessionID),await writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_denial_limit_clear",tool:toolName,agent:agentRaw,sessionID,cleared_ids:unacked,denial_count:denials,max_gate_denials:maxDenials}).catch((err)=>{warn(`[knowledge-application-gate] denial-limit-clear audit write failed: ${err instanceof Error?err.message:String(err)}`)});return}let ids=unacked.join(", ");throw Error(`KNOWLEDGE_ENFORCE_GATE_DENY: ${toolName} blocked — critical knowledge directive(s) ${ids} require KNOWLEDGE_APPLIED:<id>, KNOWLEDGE_IGNORED:<id> reason=..., or KNOWLEDGE_VIOLATED:<id> reason=... before this action.`)}writeWarnEvent2(directory,{timestamp:new Date().toISOString(),event:"knowledge_application_gate_warn",tool:toolName,agent:agentRaw,sessionID,unacknowledged_critical_ids:unacked}).catch(()=>{})}async function writeWarnEvent2(directory,record3){let filePath=path217.join(directory,".swarm","events.jsonl");await mkdir45(path217.dirname(filePath),{recursive:!0}),await appendFile22(filePath,`${JSON.stringify(record3)}
|
|
6061
6061
|
`,"utf-8")}async function knowledgeApplicationTransformScan(directory,output,sessionID){if(!output?.messages)return;if(!sessionID)return;let target;for(let i=output.messages.length-1;i>=0;i--){let m=output.messages[i],agent=m.info?.agent;if(typeof agent==="string"&&stripKnownSwarmPrefix(agent)==="architect"){target=m;break}}if(!target)return;let text=(target.parts??[]).map((p)=>typeof p.text==="string"?p.text:"").join(`
|
|
6062
|
-
`);if(!text)return;let acks=parseAcknowledgments(text);if(acks.length===0)return;let ctx={sessionId:sessionID};for(let ack of acks){let key=buildAckDedupKey(sessionID,ack.id,ack.result);if(swarmState.knowledgeAckDedup.has(key))continue;addKnowledgeAckDedup(key);try{await recordAcknowledgment(directory,ack,ctx)}catch(err){warn(`[knowledge-application-gate] transform-scan record failed: ${err instanceof Error?err.message:String(err)}`)}}}var _internals146={knowledgeApplicationGateBefore,knowledgeApplicationTransformScan,HIGH_RISK_TOOLS,writeWarnEvent:writeWarnEvent2};init_knowledge_curator();init_micro_reflector();init_normalize_tool_name();init_pr_subscriptions();init_utils();init_stored_input_args();init_normalize_tool_name();var MAX_OUTPUT_SCAN_BYTES=65536,PR_URL_PATTERN=/https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)\/pull\/(\d+)/,_internals147={subscribe,log};function extractPrUrl(text){let match=PR_URL_PATTERN.exec(text.slice(0,MAX_OUTPUT_SCAN_BYTES));if(!match)return null;let owner=match[1],repo=match[2],prNumber=Number.parseInt(match[3],10);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return{repoFullName:`${owner}/${repo}`,prNumber,prUrl:`https://github.com/${owner}/${repo}/pull/${prNumber}`}}function createPrAutoSubscribeHook(directory,config3){return{toolAfter:async(input,output)=>{try{if(!config3.enabled||!config3.auto_subscribe_on_pr_create)return;let sessionID=typeof input.sessionID==="string"?input.sessionID.trim():"";if(!sessionID)return;let tool3=normalizeToolNameLowerCase(input.tool??"");if(tool3!=="bash"&&tool3!=="shell")return;let args2=(typeof input.callID==="string"?getStoredInputArgs(input.callID):void 0)??input.args??output.args;if(!(typeof args2?.command==="string"?args2.command:"").includes("gh pr create"))return;let outputText2=typeof output.output==="string"?output.output:"";if(!outputText2)return;let prInfo=extractPrUrl(outputText2);if(!prInfo)return;await _internals147.subscribe(directory,{sessionID,prNumber:prInfo.prNumber,repoFullName:prInfo.repoFullName,prUrl:prInfo.prUrl,maxSubscriptions:config3.max_subscriptions}),_internals147.log("[pr-monitor] Auto-subscribed session to created PR",{sessionID,pr:`${prInfo.repoFullName}#${prInfo.prNumber}`})}catch(err){_internals147.log("[pr-monitor] Auto-subscribe failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}}}init_pr_workflow_gate();init_pr_feedback_event_queue();init_pr_workflow_auto_wake();init_pr_workflow_gate();var DEFAULT_WAKE_TIMEOUT_MS=5000,_internals148={readPrWorkflowGateState,claimPrFeedbackMonitorEvents,readPrFeedbackMonitorQueue},DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES=5,DEFAULT_WAKE_COOLDOWN_MS=30000,DEFAULT_BANNER_COOLDOWN_MS=20000,MAX_FALLBACK_BANNER_INJECTIONS_PER_SESSION=20,BANNER_PREFIX_PATTERN=/^--- \[(?:PR_REVIEW|PR_FEEDBACK) WORKFLOW ACTIVE/,MAX_TRACKED_WAKE_SESSIONS=200;function canonicalGitHubPrUrl5(value){try{let url3=new URL(value),match=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!match)return null;let number7=Number(match[3]);if(!Number.isSafeInteger(number7)||number7<=0)return null;return`github.com/${match[1].toLowerCase()}/${match[2].toLowerCase()}/pull/${number7}`}catch{return null}}function sameGitHubPr3(left,right){let leftCanonical=canonicalGitHubPrUrl5(left);return leftCanonical!==null&&leftCanonical===canonicalGitHubPrUrl5(right)}function formatQueuedMonitorEventsText(events){if(events.length===0)return"";return["Queued PR monitor events are now authorized for this PR_FEEDBACK workflow and must be treated as feedback inputs for the current round:",...events.map((event)=>`- ${event.type} on ${event.repoFullName}#${event.prNumber}: ${event.message.split(`
|
|
6062
|
+
`);if(!text)return;let acks=parseAcknowledgments(text);if(acks.length===0)return;let ctx={sessionId:sessionID};for(let ack of acks){let key=buildAckDedupKey(sessionID,ack.id,ack.result);if(swarmState.knowledgeAckDedup.has(key))continue;addKnowledgeAckDedup(key);try{await recordAcknowledgment(directory,ack,ctx)}catch(err){warn(`[knowledge-application-gate] transform-scan record failed: ${err instanceof Error?err.message:String(err)}`)}}}var _internals146={knowledgeApplicationGateBefore,knowledgeApplicationTransformScan,HIGH_RISK_TOOLS,writeWarnEvent:writeWarnEvent2};init_knowledge_curator();init_micro_reflector();init_normalize_tool_name();init_pr_subscriptions();init_utils();init_stored_input_args();init_normalize_tool_name();var MAX_OUTPUT_SCAN_BYTES=65536,PR_URL_PATTERN=/https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)\/pull\/(\d+)/,_internals147={subscribe,log};function extractPrUrl(text){let match=PR_URL_PATTERN.exec(text.slice(0,MAX_OUTPUT_SCAN_BYTES));if(!match)return null;let owner=match[1],repo=match[2],prNumber=Number.parseInt(match[3],10);if(!Number.isSafeInteger(prNumber)||prNumber<=0)return null;return{repoFullName:`${owner}/${repo}`,prNumber,prUrl:`https://github.com/${owner}/${repo}/pull/${prNumber}`}}function createPrAutoSubscribeHook(directory,config3){return{toolAfter:async(input,output)=>{try{if(!config3.enabled||!config3.auto_subscribe_on_pr_create)return;let sessionID=typeof input.sessionID==="string"?input.sessionID.trim():"";if(!sessionID)return;let tool3=normalizeToolNameLowerCase(input.tool??"");if(tool3!=="bash"&&tool3!=="shell")return;let args2=(typeof input.callID==="string"?getStoredInputArgs(input.callID):void 0)??input.args??output.args;if(!(typeof args2?.command==="string"?args2.command:"").includes("gh pr create"))return;let outputText2=typeof output.output==="string"?output.output:"";if(!outputText2)return;let prInfo=extractPrUrl(outputText2);if(!prInfo)return;await _internals147.subscribe(directory,{sessionID,prNumber:prInfo.prNumber,repoFullName:prInfo.repoFullName,prUrl:prInfo.prUrl,maxSubscriptions:config3.max_subscriptions}),_internals147.log("[pr-monitor] Auto-subscribed session to created PR",{sessionID,pr:`${prInfo.repoFullName}#${prInfo.prNumber}`})}catch(err){_internals147.log("[pr-monitor] Auto-subscribe failed (non-fatal)",{error:err instanceof Error?err.message:String(err)})}}}}init_pr_workflow_gate();init_pr_feedback_event_queue();init_pr_workflow_auto_wake();init_pr_workflow_gate();var DEFAULT_WAKE_TIMEOUT_MS=5000,_internals148={readPrWorkflowGateState,claimPrFeedbackMonitorEvents,readPrFeedbackMonitorQueue},DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES=5,DEFAULT_WAKE_COOLDOWN_MS=30000,DEFAULT_BANNER_COOLDOWN_MS=20000,MAX_FALLBACK_BANNER_INJECTIONS_PER_SESSION=20,BANNER_PREFIX_PATTERN=/^--- \[(?:PR_REVIEW|PR_FEEDBACK) WORKFLOW ACTIVE/,DEFAULT_TOTAL_WAKE_CEILINGS={S:12,M:54,L:102},MAX_TRACKED_WAKE_SESSIONS=200;function canonicalGitHubPrUrl5(value){try{let url3=new URL(value),match=url3.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/);if(url3.protocol!=="https:"||url3.hostname.toLowerCase()!=="github.com"||!match)return null;let number7=Number(match[3]);if(!Number.isSafeInteger(number7)||number7<=0)return null;return`github.com/${match[1].toLowerCase()}/${match[2].toLowerCase()}/pull/${number7}`}catch{return null}}function sameGitHubPr3(left,right){let leftCanonical=canonicalGitHubPrUrl5(left);return leftCanonical!==null&&leftCanonical===canonicalGitHubPrUrl5(right)}function formatQueuedMonitorEventsText(events){if(events.length===0)return"";return["Queued PR monitor events are now authorized for this PR_FEEDBACK workflow and must be treated as feedback inputs for the current round:",...events.map((event)=>`- ${event.type} on ${event.repoFullName}#${event.prNumber}: ${event.message.split(`
|
|
6063
6063
|
`)[0]}`),"Do not expand or replace an already-declared immutable feedback inventory; if these events require a later round, finish or abort the current round first."].join(`
|
|
6064
|
-
`)}function blockedText(mode,options={}){let lines=[`[${mode} WORKFLOW ACTIVE]`,`The ${mode} workflow gate is still active. Continue with the required structured lanes, evidence, and controller tools until \`complete_pr_workflow\` succeeds.`,`If the bind/checkout path is unreachable — for example a compound \`git fetch && git checkout\` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — call \`abort_pr_workflow\` (mode: "${mode}", reason: "<one-line cause>") to clear the gate, or ask the user to run \`/swarm abort-pr-workflow\`.`];if(options.suspended){let max=options.maxConsecutive;lines.push(`Auto-resume is suspended after ${max??"the configured number of"} consecutive unproductive retries (the durable gate \`revision\` did not advance). The session will not be re-awoken automatically. Run \`/swarm abort-pr-workflow\` or call \`abort_pr_workflow\` to clear the gate, or complete the workflow with \`complete_pr_workflow\` to publish normally.`)}if(options.userInterrupted)lines.push("Auto-resume is paused after a user interruption. The durable workflow gate is preserved, but the plugin will not re-awaken this session. Send a new message to continue, or run `/swarm abort-pr-workflow` to clear the workflow.");if(options.recovery)lines.push(`Auto-resume is disabled because manual Git recovery is required. code=${options.recovery.code} retryable=false required_action=${options.recovery.requiredAction}`);return lines.join(`
|
|
6065
|
-
`)}function workflowBanner(mode,options={}){let lines=[`--- [${mode} WORKFLOW ACTIVE — output below is not a terminal verdict; \`complete_pr_workflow\` clears the gate on success; if the bind/checkout path is unreachable call \`abort_pr_workflow\` or run \`/swarm abort-pr-workflow\`] ---`];if(options.suspended){let max=options.maxConsecutive;lines.push(`[Auto-resume is suspended after ${max??"the configured number of"} consecutive unproductive retries. Run \`/swarm abort-pr-workflow\` or call \`abort_pr_workflow\` to clear the gate, or complete the workflow with \`complete_pr_workflow\`.]`)}if(options.userInterrupted)lines.push("[Auto-resume paused after a user interruption. Send a new message to continue, or run `/swarm abort-pr-workflow` to clear the workflow.]");if(options.recovery)lines.push(`[Manual Git recovery required; auto-resume disabled. code=${options.recovery.code} retryable=false required_action=${options.recovery.requiredAction}]`);return lines.join(" ")}function createPrWorkflowResponseGate(options){let wakeTimeoutMs=options.wakeTimeoutMs??DEFAULT_WAKE_TIMEOUT_MS,maxConsecutive=options.maxConsecutiveUnproductiveWakes??DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES,wakeCooldownMs=options.wakeCooldownMs??DEFAULT_WAKE_COOLDOWN_MS,bannerCooldownMs=options.bannerCooldownMs??DEFAULT_BANNER_COOLDOWN_MS,activeWakeSessions=new Set,wakeBudgets=new Map,bannerStamps=new Map,banneredMessages=new Map,fallbackInjections=new Map,session=options.client?.session;function evictIfOverBound(){while(wakeBudgets.size>MAX_TRACKED_WAKE_SESSIONS){let
|
|
6066
|
-
${formatQueuedMonitorEventsText(queuedMonitorEvents)}`:"",promptRejected=!1,promptAccepted=!1,timer;try{let args2={path:{id:sessionID},body:{messageID:pluginWakeMessageID,parts:[{type:"text",text:`${blockedText(state.mode,{suspended:!1,maxConsecutive})}
|
|
6067
|
-
Do not stop or summarize. Inspect the durable gate, dispatch or collect the next missing required lane, and continue until complete_pr_workflow succeeds. If the bind/checkout path is genuinely unreachable, call abort_pr_workflow instead of looping.${queuedMonitorText}`}]}},call=session.promptAsync?session.promptAsync(args2):session.prompt(args2),result=await Promise.race([call,new Promise((_resolve,reject2)=>{timer=setTimeout(()=>reject2(Error("PR workflow resume prompt timed out")),wakeTimeoutMs)})]);if(result?.error!=null)throw promptRejected=!0,Error(`PR workflow resume prompt failed: ${String(result.error)}`);promptAccepted=!0}finally{if(timer)clearTimeout(timer);if(promptRejected)cancelPrWorkflowPluginWake(options.directory,sessionID,pluginWakeMessageID);let postWakeState=await _internals148.readPrWorkflowGateState(options.directory,sessionID)
|
|
6064
|
+
`)}function blockedText(mode,options={}){let lines=[`[${mode} WORKFLOW ACTIVE]`,`The ${mode} workflow gate is still active. Continue with the required structured lanes, evidence, and controller tools until \`complete_pr_workflow\` succeeds.`,`If the bind/checkout path is unreachable — for example a compound \`git fetch && git checkout\` was rejected as read-only shell syntax, the PR head cannot be fetched, or the working tree is on the wrong branch — call \`abort_pr_workflow\` (mode: "${mode}", reason: "<one-line cause>") to clear the gate, or ask the user to run \`/swarm abort-pr-workflow\`.`];if(options.suspended)if(options.suspendedReason==="total")lines.push("Auto-resume is suspended because the total per-session wake budget has been exhausted. The session will not be re-awoken automatically. Run `/swarm abort-pr-workflow`, call `abort_pr_workflow`, or complete the workflow with `complete_pr_workflow` to publish normally.");else{let max=options.maxConsecutive;lines.push(`Auto-resume is suspended after ${max??"the configured number of"} consecutive unproductive retries (the durable gate \`revision\` did not advance). The session will not be re-awoken automatically. Run \`/swarm abort-pr-workflow\` or call \`abort_pr_workflow\` to clear the gate, or complete the workflow with \`complete_pr_workflow\` to publish normally.`)}if(options.userInterrupted)lines.push("Auto-resume is paused after a user interruption. The durable workflow gate is preserved, but the plugin will not re-awaken this session. Send a new message to continue, or run `/swarm abort-pr-workflow` to clear the workflow.");if(options.recovery)lines.push(`Auto-resume is disabled because manual Git recovery is required. code=${options.recovery.code} retryable=false required_action=${options.recovery.requiredAction}`);return lines.join(`
|
|
6065
|
+
`)}function workflowBanner(mode,options={}){let lines=[`--- [${mode} WORKFLOW ACTIVE — output below is not a terminal verdict; \`complete_pr_workflow\` clears the gate on success; if the bind/checkout path is unreachable call \`abort_pr_workflow\` or run \`/swarm abort-pr-workflow\`] ---`];if(options.suspended)if(options.suspendedReason==="total")lines.push("[Auto-resume is suspended because the total per-session wake budget has been exhausted. Run `/swarm abort-pr-workflow`, call `abort_pr_workflow`, or complete the workflow with `complete_pr_workflow`.]");else{let max=options.maxConsecutive;lines.push(`[Auto-resume is suspended after ${max??"the configured number of"} consecutive unproductive retries. Run \`/swarm abort-pr-workflow\` or call \`abort_pr_workflow\` to clear the gate, or complete the workflow with \`complete_pr_workflow\`.]`)}if(options.userInterrupted)lines.push("[Auto-resume paused after a user interruption. Send a new message to continue, or run `/swarm abort-pr-workflow` to clear the workflow.]");if(options.recovery)lines.push(`[Manual Git recovery required; auto-resume disabled. code=${options.recovery.code} retryable=false required_action=${options.recovery.requiredAction}]`);return lines.join(" ")}function createPrWorkflowResponseGate(options){let wakeTimeoutMs=options.wakeTimeoutMs??DEFAULT_WAKE_TIMEOUT_MS,maxConsecutive=options.maxConsecutiveUnproductiveWakes??DEFAULT_MAX_CONSECUTIVE_UNPRODUCTIVE_WAKES,wakeCooldownMs=options.wakeCooldownMs??DEFAULT_WAKE_COOLDOWN_MS,bannerCooldownMs=options.bannerCooldownMs??DEFAULT_BANNER_COOLDOWN_MS,resolveTotalWakeCeiling=(tier)=>{if(options.totalWakeCeiling===void 0)return DEFAULT_TOTAL_WAKE_CEILINGS[tier];return typeof options.totalWakeCeiling==="number"?options.totalWakeCeiling:options.totalWakeCeiling[tier]??DEFAULT_TOTAL_WAKE_CEILINGS[tier]},activeWakeSessions=new Set,wakeBudgets=new Map,bannerStamps=new Map,banneredMessages=new Map,fallbackInjections=new Map,session=options.client?.session;function evictIfOverBound(){while(wakeBudgets.size>MAX_TRACKED_WAKE_SESSIONS){let evicted=!1;for(let[key,budget]of wakeBudgets){if(budget.suspended)continue;wakeBudgets.delete(key),evicted=!0;break}if(!evicted)break}}function evictBannerDedupeMapsIfOverBound(){while(bannerStamps.size>MAX_TRACKED_WAKE_SESSIONS){let oldestKey=bannerStamps.keys().next().value;if(oldestKey===void 0)break;bannerStamps.delete(oldestKey)}while(banneredMessages.size>MAX_TRACKED_WAKE_SESSIONS){let oldestKey=banneredMessages.keys().next().value;if(oldestKey===void 0)break;banneredMessages.delete(oldestKey)}while(fallbackInjections.size>MAX_TRACKED_WAKE_SESSIONS){let oldestKey=fallbackInjections.keys().next().value;if(oldestKey===void 0)break;fallbackInjections.delete(oldestKey)}}function resetBudget(sessionID){wakeBudgets.delete(sessionID),bannerStamps.delete(sessionID),banneredMessages.delete(sessionID),fallbackInjections.delete(sessionID)}return{event:async(input)=>{let wakeDecision=await observePrWorkflowAutoWakeEvent(options.directory,input.event),event2=input.event,sessionID=event2?.properties?.sessionID??event2?.data?.sessionID;if(event2?.type!=="session.idle"||typeof sessionID!=="string"||!sessionID.trim()||wakeDecision.suppressWake||activeWakeSessions.has(sessionID))return;activeWakeSessions.add(sessionID);try{let state=await _internals148.readPrWorkflowGateState(options.directory,sessionID);if(!state){resetBudget(sessionID),clearPrWorkflowAutoWakeState(options.directory,sessionID);return}if(state.checkoutRecovery)return;if(isPrWorkflowAutoWakeSuppressed(options.directory,sessionID))return;if(!session)return;evictIfOverBound();let budget=wakeBudgets.get(sessionID);if(!budget)budget={consecutiveUnproductive:0,lastWakeAt:0,suspended:!1,totalWakes:0,suspendedReason:"consecutive"},wakeBudgets.set(sessionID,budget);if(budget.suspended)return;let now=Date.now();if(budget.lastSeenRevision!==void 0&&state.revision>budget.lastSeenRevision)budget.consecutiveUnproductive=0;if(budget.consecutiveUnproductive>0&&budget.lastWakeAt>0&&now-budget.lastWakeAt<wakeCooldownMs)return;let madeProgress=budget.lastSeenRevision===void 0?!0:state.revision>budget.lastSeenRevision,pluginWakeMessageID=markPrWorkflowPluginWake(options.directory,sessionID),feedbackTarget=state.prFeedbackTargetUrl??state.prFeedbackReviewHandoff?.prUrl,queuedMonitorEvents=(state.mode==="PR_FEEDBACK"&&!state.prFeedbackInventory&&feedbackTarget?await _internals148.readPrFeedbackMonitorQueue(options.directory,sessionID).catch(()=>null):null)?.events.filter((event3)=>!event3.claimedWorkflowInstanceId&&Boolean(feedbackTarget)&&sameGitHubPr3(event3.prUrl,feedbackTarget??""))??[],queuedMonitorText=queuedMonitorEvents.length>0?`
|
|
6066
|
+
${formatQueuedMonitorEventsText(queuedMonitorEvents)}`:"",promptRejected=!1,promptAccepted=!1,timer;try{let args2={path:{id:sessionID},body:{messageID:pluginWakeMessageID,parts:[{type:"text",text:`${blockedText(state.mode,{suspended:!1,suspendedReason:void 0,maxConsecutive})}
|
|
6067
|
+
Do not stop or summarize. Inspect the durable gate, dispatch or collect the next missing required lane, and continue until complete_pr_workflow succeeds. If the bind/checkout path is genuinely unreachable, call abort_pr_workflow instead of looping.${queuedMonitorText}`}]}},call=session.promptAsync?session.promptAsync(args2):session.prompt(args2),result=await Promise.race([call,new Promise((_resolve,reject2)=>{timer=setTimeout(()=>reject2(Error("PR workflow resume prompt timed out")),wakeTimeoutMs)})]);if(result?.error!=null)throw promptRejected=!0,Error(`PR workflow resume prompt failed: ${String(result.error)}`);promptAccepted=!0}finally{if(timer)clearTimeout(timer);if(promptRejected)cancelPrWorkflowPluginWake(options.directory,sessionID,pluginWakeMessageID);let postWakeState;try{postWakeState=await _internals148.readPrWorkflowGateState(options.directory,sessionID)}catch{postWakeState=state}if(promptAccepted&&queuedMonitorEvents.length>0&&feedbackTarget&&state.workflowInstanceId&&postWakeState?.mode==="PR_FEEDBACK"&&postWakeState.workflowInstanceId===state.workflowInstanceId&&!postWakeState.prFeedbackInventory&&sameGitHubPr3(postWakeState.prFeedbackTargetUrl??postWakeState.prFeedbackReviewHandoff?.prUrl??"",feedbackTarget))await _internals148.claimPrFeedbackMonitorEvents(options.directory,sessionID,state.workflowInstanceId,feedbackTarget,queuedMonitorEvents.map((event3)=>event3.dedupToken)).catch(()=>[]);if(budget.lastWakeAt=now,postWakeState===null)resetBudget(sessionID);else{let currentRevision=postWakeState.revision,effectiveMadeProgress=madeProgress||budget.lastSeenRevision!==void 0&¤tRevision>budget.lastSeenRevision;if(budget.lastSeenRevision=currentRevision,!effectiveMadeProgress){if(budget.consecutiveUnproductive+=1,budget.consecutiveUnproductive>=maxConsecutive)budget.suspended=!0,budget.suspendedReason="consecutive"}else budget.consecutiveUnproductive=0;budget.totalWakes+=1;let tier=postWakeState.prReviewDepthTier??"L",totalCeiling=resolveTotalWakeCeiling(tier);if(budget.totalWakes>=totalCeiling)budget.suspended=!0,budget.suspendedReason="total"}}}finally{activeWakeSessions.delete(sessionID)}},textComplete:async(input,output)=>{if(!input.sessionID?.trim())return;let state=await _internals148.readPrWorkflowGateState(options.directory,input.sessionID);if(!state){resetBudget(input.sessionID),clearPrWorkflowAutoWakeState(options.directory,input.sessionID);return}if(!output.text.trim())return;if(BANNER_PREFIX_PATTERN.test(output.text))return;let messageID=input.messageID?.trim();if(messageID){if(banneredMessages.get(input.sessionID)===messageID)return}else{let injected=fallbackInjections.get(input.sessionID)??0;if(injected>=MAX_FALLBACK_BANNER_INJECTIONS_PER_SESSION)return;fallbackInjections.set(input.sessionID,injected+1),evictBannerDedupeMapsIfOverBound()}let budget=wakeBudgets.get(input.sessionID),suspended=budget?.suspended??!1,suspendedReason=budget?.suspendedReason,userInterrupted=isPrWorkflowAutoWakeSuppressed(options.directory,input.sessionID),recovery=state.checkoutRecovery?{code:state.checkoutRecovery.code,requiredAction:state.checkoutRecovery.requiredAction}:void 0,forceFullBanner=suspended||userInterrupted||Boolean(recovery),now=Date.now(),lastBannerAt=bannerStamps.get(input.sessionID),withinCooldown=lastBannerAt!==void 0&&now-lastBannerAt<bannerCooldownMs;if(messageID)banneredMessages.set(input.sessionID,messageID),evictBannerDedupeMapsIfOverBound();if(!forceFullBanner&&withinCooldown){output.text=`--- [${state.mode} WORKFLOW ACTIVE] ---
|
|
6068
6068
|
|
|
6069
|
-
${output.text}`;return}let banner=workflowBanner(state.mode,{suspended,userInterrupted,maxConsecutive,recovery});bannerStamps.set(input.sessionID,now),evictBannerDedupeMapsIfOverBound(),output.text=`${banner}
|
|
6069
|
+
${output.text}`;return}let banner=workflowBanner(state.mode,{suspended,suspendedReason,userInterrupted,maxConsecutive,recovery});bannerStamps.set(input.sessionID,now),evictBannerDedupeMapsIfOverBound(),output.text=`${banner}
|
|
6070
6070
|
|
|
6071
6071
|
${output.text}`},_inspectWakeBudget:(sessionID)=>wakeBudgets.get(sessionID)}}init_pending_delegations();init_pr_workflow_gate();var MAX_PARENT_DEPTH=16,MAX_TRACKED_SESSION_PARENTS=512;function rememberBounded2(parents,childSessionID,parentSessionID){parents.delete(childSessionID),parents.set(childSessionID,parentSessionID);while(parents.size>MAX_TRACKED_SESSION_PARENTS){let oldest=parents.keys().next().value;if(typeof oldest!=="string")break;parents.delete(oldest)}}function createPrWorkflowSessionResolver(options){let session=options.client?.session,parents=new Map;return{observeEvent:(input)=>{let event=input.event;if(event?.type!=="session.created"&&event?.type!=="session.updated")return;let child=event.properties?.info?.id,parent=event.properties?.info?.parentID;if(typeof child==="string"&&child.trim()&&typeof parent==="string"&&parent.trim())rememberBounded2(parents,child.trim(),parent.trim())},resolve:async(sessionID)=>{let original=sessionID.trim();if(!original)return sessionID;let current=original,visited=new Set;for(let depth=0;depth<MAX_PARENT_DEPTH;depth+=1){if(visited.has(current))break;if(visited.add(current),await readPrWorkflowGateState(options.directory,current))return current;let parent=parents.get(current);if(!parent)parent=findByCorrelationId(options.directory,current)?.parentSessionId;if(!parent&&session?.get){let result=await session.get({path:{id:current},query:{directory:options.directory}});if(result?.error==null){let candidate=result?.data?.parentID;if(typeof candidate==="string"&&candidate.trim())parent=candidate.trim()}}if(!parent)return original;rememberBounded2(parents,current,parent),current=parent}return original}}}init_review_receipt_collector();init_schema();init_scope_binding();init_state2();init_normalize_tool_name();init_review_receipt();init_review_receipt_scope();init_reviewer_scope_file_fingerprint();init_skill_propagation_gate();init_task_result_classifier();function lifecycleTarget(args2){let delegation=parseDelegationArgs(args2);return delegation?stripKnownSwarmPrefix(delegation.targetAgent).toLowerCase():""}function isTaskTool6(tool3){if(typeof tool3!=="string")return!1;let normalized=normalizeToolName(tool3);return normalized==="Task"||normalized==="task"}function generationFingerprintsAreCurrent(directory,generation){let{modifiedFiles,modifiedFileFingerprints:fingerprints}=generation;if(modifiedFiles.length===0||modifiedFiles.length!==fingerprints.length||new Set(modifiedFiles).size!==modifiedFiles.length||new Set(fingerprints.map((entry)=>entry.file)).size!==fingerprints.length)return!1;let fingerprintBytes=0;for(let file3 of modifiedFiles){let stored=fingerprints.filter((entry)=>entry.file===file3),current=captureReviewerScopeFileFingerprint(directory,file3,MAX_REVIEWER_SCOPE_FINGERPRINT_AGGREGATE_BYTES-fingerprintBytes);if(stored.length!==1||!current||!reviewerScopeFileFingerprintsEqual(stored[0],current))return!1;if(current.kind==="file")fingerprintBytes+=current.size}return!0}function scopeMatchesGenerationFingerprints(scope,generation){let records=new Map;for(let line of scope.content.split(`
|
|
6072
6072
|
`).slice(1)){if(!line)continue;try{let parsed=JSON.parse(line);if(typeof parsed.path==="string")records.set(parsed.path,parsed)}catch{return!1}}if(records.size!==generation.modifiedFileFingerprints.length||scope.files.length!==generation.modifiedFiles.length)return!1;return generation.modifiedFileFingerprints.every((fingerprint)=>{let record3=records.get(fingerprint.file);if(!record3)return!1;return fingerprint.kind==="deleted"?record3.state==="deleted":record3.state==="file"&&record3.bytes===fingerprint.size&&record3.sha256===fingerprint.hash})}async function beginApprovedReviewerScopeLifecycle(input){if(!isTaskTool6(input.tool))return null;let taskId=await resolveReviewerScopeTaskId(input.directory,input.args);if(!taskId)return null;let target=lifecycleTarget(input.args);if(target==="coder"){let binding=getScopeBindingForParentDispatch({parentSessionId:input.parentSessionID,dispatchCallId:input.callID});if(binding?.taskId!==taskId)return null;let rawArgs=input.args&&typeof input.args==="object"?input.args:null;return startReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID,background:rawArgs?.background===!0||rawArgs?.background==="true",declaredFiles:binding.files})?"coder_started":null}if(target==="reviewer"){let ready=peekReadyReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId});if(!ready||!generationFingerprintsAreCurrent(input.directory,ready)){if(ready)discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID});throw Error("REVIEWER_SCOPE_STALE: coder post-write fingerprints are incomplete or changed before reviewer dispatch")}let snapshot=await buildReviewerTaskScope(input.directory,ready.modifiedFiles,input.maxBytes,{taskId:ready.taskId,coderCallID:ready.coderCallID,generation:ready.generation,sessionIncarnation:ready.sessionIncarnation}),current=peekReadyReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId}),exactGenerationStillCurrent=current!==null&¤t.coderCallID===ready.coderCallID&¤t.generation===ready.generation&¤t.sessionIncarnation===ready.sessionIncarnation&&isReviewerScopeGenerationCurrent({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID,generation:ready.generation,sessionIncarnation:ready.sessionIncarnation});if(!snapshot||!current||!exactGenerationStillCurrent||!generationFingerprintsAreCurrent(input.directory,current)||!scopeMatchesGenerationFingerprints(snapshot,current))throw discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:ready.coderCallID}),Error("REVIEWER_SCOPE_STALE: exact reviewer dispatch scope changed during capture");let claimed=claimReviewerScopeGeneration({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID});if(!claimed||claimed.coderCallID!==ready.coderCallID||claimed.generation!==ready.generation||claimed.sessionIncarnation!==ready.sessionIncarnation||!attachReviewerScopeGenerationDispatchSnapshot({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID,snapshot:{hash:computeScopeFingerprint(snapshot.content,snapshot.description).hash,description:snapshot.description,files:[...snapshot.files],headSha:snapshot.headSha,taskId:claimed.taskId,coderCallID:claimed.coderCallID,generation:claimed.generation,sessionIncarnation:claimed.sessionIncarnation}}))throw discardReviewerScopeGenerationClaim({parentSessionID:input.parentSessionID,taskId,reviewerCallID:input.callID}),Error("REVIEWER_SCOPE_STALE: exact reviewer dispatch scope could not be captured");return"reviewer_claimed"}return null}async function completeReviewerScopeLifecycle(input){if(!isTaskTool6(input.tool))return null;if(lifecycleTarget(input.args)!=="coder")return null;let result=classifyTaskResult(input.output);if(result==="running")return null;let taskId=await resolveReviewerScopeTaskId(input.directory,input.args);if(!taskId)return discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,coderCallID:input.callID}),null;if(result==="non_success")return discardReviewerScopeGenerationForCoderCall({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID}),null;return markReviewerScopeGenerationReady({parentSessionID:input.parentSessionID,taskId,coderCallID:input.callID})?"coder_ready":null}init_schema();init_bun_compat();init_logger();var import_picomatch2=__toESM(require_picomatch2(),1);import{existsSync as existsSync106,readdirSync as readdirSync34,readFileSync as readFileSync81,statSync as statSync45}from"node:fs";import*as path218 from"node:path";var PREDICATE_TIMEOUT_MS=15000,GREP_MAX_FILES=1e4,GREP_MAX_BYTES_PER_FILE=1e6,GREP_SKIP_DIRECTORIES=new Set([".git",".swarm","node_modules","dist","coverage"]),TOOL_BINARY_ALLOWLIST=new Set(["rg","grep","git","biome","eslint","tsc","ruff"]);function validateRepoRelativeGlob(directory,value){let v=value.trim();if(!v)return null;if(v.includes("\x00"))return null;if(v.startsWith("/")||/^[A-Za-z]:[\\/]/.test(v)||v.startsWith("\\"))return null;if(v.split(/[/\\]/).some((s)=>s===".."))return null;let globStart=v.search(/[*?{[]/),concrete=globStart===-1?v:v.slice(0,globStart);if(concrete){let baseDir=path218.resolve(directory),resolved=path218.resolve(baseDir,concrete),rel=path218.relative(baseDir,resolved);if(rel.startsWith("..")||path218.isAbsolute(rel))return null}return v}function findBinaryInPath(binary){let candidates=process.platform==="win32"?[`${binary}.exe`,`${binary}.cmd`,`${binary}.bat`,binary]:[binary];for(let dir of(process.env.PATH??"").split(path218.delimiter)){if(!dir)continue;for(let name of candidates){let candidate=path218.join(dir,name);if(existsSync106(candidate))return candidate}}return null}function safeChildEnv(){let env={};if(process.env.PATH)env.PATH=process.env.PATH;if(process.env.HOME)env.HOME=process.env.HOME;if(process.env.SystemRoot)env.SystemRoot=process.env.SystemRoot;if(process.env.TEMP)env.TEMP=process.env.TEMP;if(process.env.TMP)env.TMP=process.env.TMP;return env}async function runArgv(argv,cwd){let proc=bunSpawn(argv,{stdin:"ignore",stdout:"pipe",stderr:"pipe",cwd,env:safeChildEnv()}),finished=!1;try{let timeout=new Promise((resolve81)=>setTimeout(()=>resolve81("timeout"),PREDICATE_TIMEOUT_MS));if(await Promise.race([proc.exited,timeout])==="timeout")return{exitCode:null,stdout:"",stderr:"",timedOut:!0};let[stdout,stderr]=await Promise.all([proc.stdout.text().catch(()=>""),proc.stderr.text().catch(()=>"")]);return finished=!0,{exitCode:proc.exitCode,stdout,stderr,timedOut:!1}}finally{if(!finished)try{proc.kill()}catch{}}}async function runGrepPredicate(rest,directory){let lastColon=rest.lastIndexOf(":");if(lastColon<=0||lastColon===rest.length-1)return{result:"error",detail:"grep: expected <regex>:<path-glob>"};let regex=rest.slice(0,lastColon),rawGlob=rest.slice(lastColon+1),glob=validateRepoRelativeGlob(directory,rawGlob);if(glob===null)return{result:"error",detail:`grep: unsafe or empty path-glob "${rawGlob}"`};let pattern;try{pattern=new RegExp(regex,"m")}catch(err){return{result:"error",detail:`grep: invalid regex ${err instanceof Error?err.message:String(err)}`}}let matcher=import_picomatch2.default(glob,{dot:!0}),visited=0,matches=0,walk=(dir)=>{if(visited>=GREP_MAX_FILES)return;let entries;try{entries=readdirSync34(dir,{withFileTypes:!0})}catch{return}for(let entry of entries){if(visited>=GREP_MAX_FILES)return;let fullPath=path218.join(dir,entry.name),relPath=path218.relative(directory,fullPath).replace(/\\/g,"/");if(entry.isDirectory()){if(!GREP_SKIP_DIRECTORIES.has(entry.name))walk(fullPath);continue}if(!entry.isFile())continue;if(visited++,!matcher(relPath))continue;try{if(statSync45(fullPath).size>GREP_MAX_BYTES_PER_FILE)continue;let found=readFileSync81(fullPath,"utf-8").match(pattern);if(found)matches+=found.length}catch{}}};if(walk(directory),visited>=GREP_MAX_FILES)return{result:"error",detail:`grep: file scan exceeded ${GREP_MAX_FILES} files`};if(matches===0)return{result:"pass",detail:"grep: zero matches"};return{result:"fail",detail:`grep: ${matches} match(es) found`}}async function runToolPredicate(rest,directory){let raw=rest.trim();if(!raw)return{result:"error",detail:"tool: empty command"};if(raw.includes("\x00"))return{result:"error",detail:"tool: null byte in command"};let argvParts=raw.split(/\s+/).filter((p)=>p.length>0);if(argvParts.length===0)return{result:"error",detail:"tool: empty command"};let binary=argvParts[0];if(binary.includes("/")||binary.includes("\\"))return{result:"error",detail:`tool: path-qualified binary "${binary}" is not allowed`};if(!TOOL_BINARY_ALLOWLIST.has(binary))return{result:"error",detail:`tool: binary "${binary}" is not on the allowlist`};let resolved=findBinaryInPath(binary);if(!resolved)return{result:"error",detail:`tool: binary "${binary}" not found`};let res=await runArgv([resolved,...argvParts.slice(1)],directory);if(res.timedOut)return{result:"error",detail:"tool: timed out"};if(res.exitCode===0)return{result:"pass",detail:"tool: exit 0"};return{result:"fail",detail:`tool: exit ${res.exitCode} ${res.stderr.slice(0,200)}`}}async function changedPaths(directory){let git2=findBinaryInPath("git");if(!git2)return null;let res=await runArgv([git2,"status","--porcelain","-z"],directory);if(res.timedOut||res.exitCode!==0)return null;let out=new Set;for(let entry of res.stdout.split("\x00")){if(entry.length<=3)continue;let p=entry.slice(3);if(p)out.add(path218.normalize(p))}return out}async function runFileModifiedPredicate(rest,directory,expectModified){let label=expectModified?"file_modified":"file_not_modified",safe=validateRepoRelativeGlob(directory,rest);if(safe===null)return{result:"error",detail:`${label}: unsafe or empty path "${rest}"`};let changed=await changedPaths(directory);if(changed===null)return{result:"error",detail:`${label}: git unavailable or failed`};let target=path218.normalize(safe),isChanged=changed.has(target);return{result:(expectModified?isChanged:!isChanged)?"pass":"fail",detail:`${label}: ${target} ${isChanged?"changed":"unchanged"}`}}async function runDirectivePredicate(predicate,directory){try{if(typeof predicate!=="string"||!predicate.trim())return{result:"error",detail:"predicate: empty"};let trimmed=predicate.trim(),firstColon=trimmed.indexOf(":");if(firstColon<=0)return{result:"error",detail:"predicate: missing handler prefix (expected <handler>:...)"};let handler=trimmed.slice(0,firstColon),rest=trimmed.slice(firstColon+1);switch(handler){case"grep":return await runGrepPredicate(rest,directory);case"tool":return await runToolPredicate(rest,directory);case"file_not_modified":return await runFileModifiedPredicate(rest,directory,!1);case"file_modified":return await runFileModifiedPredicate(rest,directory,!0);default:return{result:"error",detail:`predicate: unknown handler "${handler}"`}}}catch(err){return warn(`[directive-predicate-runner] unexpected error: ${err instanceof Error?err.message:String(err)}`),{result:"error",detail:"predicate: unexpected error (fail-closed)"}}}init_knowledge_escalator();init_knowledge_events();init_skill_propagation_gate();var VERDICT_PATTERN=/\b(VERIFIED|VIOLATED|N\/A)\s*:\s*([A-Za-z0-9._-]{1,80})(?:\s+(?:evidence|reason)\s*=\s*([^\n\r]+?))?(?=$|[\n\r]|\s+(?:VERIFIED|VIOLATED|N\/A)\b)/gi;function parseReviewerDirectiveCompliance(text){if(!text||typeof text!=="string")return[];let out=[];for(let m of text.matchAll(VERDICT_PATTERN)){let verb=m[1].toUpperCase(),id=m[2],evidence2=m[3]?.trim().slice(0,280),verdict=verb==="VERIFIED"?"verified":verb==="VIOLATED"?"violated":"n_a";out.push({id,verdict,evidence:evidence2})}return out}function verdictToEventType(v){return v==="verified"?"applied":v==="violated"?"violated":"n_a"}async function reconcileReviewerVerdicts(params){let result={emitted:[],omittedCriticals:[]};try{let verifyById=new Map(params.directivesToVerify.map((d)=>[d.id,d]));if(verifyById.size===0)return result;let verdicts=parseReviewerDirectiveCompliance(params.transcript),addressed=new Set,violatedIds=new Set,traceId=newTraceId(),sessionId=params.sessionId??"unknown",agent=params.agent??"reviewer";for(let v of verdicts){let directive=verifyById.get(v.id);if(!directive)continue;addressed.add(v.id);let type=verdictToEventType(v.verdict),predicateCheck;if(v.verdict==="violated"&&directive.verification_predicate){let outcome=await runDirectivePredicate(directive.verification_predicate,params.directory);predicateCheck={predicate:directive.verification_predicate,result:outcome.result,detail:outcome.detail}}if(await recordKnowledgeEvent(params.directory,{type,trace_id:traceId,knowledge_id:v.id,session_id:sessionId,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:v.evidence,predicate_check:predicateCheck}),type==="violated")violatedIds.add(v.id);result.emitted.push({id:v.id,type,source:"reviewer"})}for(let d of params.directivesToVerify){if(d.priority!=="critical")continue;if(addressed.has(d.id))continue;result.omittedCriticals.push(d.id),await recordKnowledgeEvent(params.directory,{type:"violated",trace_id:traceId,knowledge_id:d.id,session_id:sessionId,task_id:params.taskId,phase:params.phase,agent,source:"reviewer",reason:"reviewer_omitted"}),violatedIds.add(d.id),result.emitted.push({id:d.id,type:"violated",source:"reviewer"})}if(violatedIds.size>0)await escalateViolatedEntries(params.directory,[...violatedIds])}catch{}return result}function isTaskTool7(tool3){return tool3==="Task"||tool3==="task"}async function collectReviewerVerdictsAfter(directory,input,output){if(!isTaskTool7(input.tool))return;let parsedArgs=parseDelegationArgs(input.args);if(!parsedArgs)return;if(stripKnownSwarmPrefix(parsedArgs.targetAgent).toLowerCase()!=="reviewer")return;let argsRecord=input.args&&typeof input.args==="object"?input.args:null,prompt=argsRecord&&typeof argsRecord.prompt==="string"?argsRecord.prompt:"";if(!prompt)return;let transcript=typeof output.output==="string"?output.output:"";if(!transcript)return;let directivesToVerify=parseDirectivesToVerifyBlock(prompt);if(directivesToVerify.length===0)return;let sessionId=typeof input.sessionID==="string"?input.sessionID:void 0;await reconcileReviewerVerdicts({directory,transcript,directivesToVerify,sessionId,agent:"reviewer"})}init_constants();init_schema();init_scope_binding();init_scope_persistence();init_state2();init_normalize_tool_name();init_pr_workflow_gate();init_write_target_resolver();import*as path219 from"node:path";var WRITE_TOOLS2=new Set(WRITE_TOOL_NAMES);function createScopeGuardHook(config3,fallbackDirectory,injectAdvisory){let enabled=config3.enabled??!0,_skipInTurbo=config3.skip_in_turbo??!1;return{toolBefore:async(input,output)=>{if(!enabled)return;let toolName=normalizeToolName(input.tool);if(!WRITE_TOOLS2.has(toolName))return;let sessionId=input.sessionID,activeAgent=swarmState.activeAgent.get(sessionId),session=swarmState.agentSessions.get(sessionId),agentName=activeAgent??session?.agentName??"unknown",agentRole=stripKnownSwarmPrefix(agentName);if(agentRole===ORCHESTRATOR_NAME)return;if(agentRole!=="coder")return;let directory=_internals149.resolveSessionWorkspaceDirectory(sessionId,fallbackDirectory),targets=_internals149.resolveWriteTargets(toolName,output.args,{directory});if(targets.status==="unverifiable")throw Error(`WRITE TARGET UNVERIFIABLE: ${agentName} invoked ${toolName}: ${targets.reason}`);if(targets.paths.length===0)return;let taskId=_internals149.resolveTaskId(session),binding=taskId?_internals149.resolveAuthorizedScopeBinding({directory,taskId,activeSessionId:sessionId}):_internals149.resolveAuthorizedScopeBindingForSession({directory,activeSessionId:sessionId});if(!binding){if(binding=_internals149.getAuthorizedPrFeedbackScopeBinding({directory,activeSessionId:sessionId,taskId:taskId??void 0})??_internals149.resolveAuthorizedPrFeedbackScopeBindingFromDisk({directory,activeSessionId:sessionId,taskId:taskId??void 0}),binding&&!await _internals149.validatePrFeedbackScopeBinding(directory,binding))binding=null}if(!taskId&&binding&&session)taskId=binding.taskId,session.currentTaskId=binding.taskId,session.declaredCoderScope=[...binding.files];let declaredScope=binding?.files??null;if(!declaredScope||declaredScope.length===0){let mismatch=_internals149.describeScopeWorkspaceMismatch({directory,activeSessionId:sessionId,taskId});if(mismatch)throw Error(`${mismatch} ${agentName} cannot invoke ${toolName} for task ${taskId??"unknown"}.`);throw Error(`SCOPE_NOT_DECLARED: ${agentName} cannot invoke ${toolName} without a validated scope for task ${taskId??"unknown"}.`)}for(let rawPath of targets.paths){let filePath=sanitizePath(rawPath);if(!isFileInScope(filePath,declaredScope,directory))reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,swarmState,declaredScope)}}}}function isFileInScope(filePath,scopeEntries,directory){let dir=directory??process.cwd(),resolvedFile=path219.resolve(dir,filePath);return scopeEntries.filter((scope)=>scope.length>0).some((scope)=>{let resolvedScope=path219.resolve(dir,scope);if(resolvedFile===resolvedScope)return!0;let rel=path219.relative(resolvedScope,resolvedFile);return rel.length>0&&!rel.startsWith("..")&&!path219.isAbsolute(rel)})}function sanitizePath(raw){let result="";for(let i=0;i<raw.length;i++){let c=raw.charCodeAt(i);if(c<=31||c===127||c>=128&&c<=159){result+="_";continue}result+=raw[i]}return result.replace(/\[[\d;]*m/g,"")}var _internals149={sanitizePath,resolveWriteTargets:resolveWriteTargets2,resolveAuthorizedScopeBinding,resolveAuthorizedScopeBindingForSession,getAuthorizedPrFeedbackScopeBinding,resolveAuthorizedPrFeedbackScopeBindingFromDisk,validatePrFeedbackScopeBinding,resolveSessionWorkspaceDirectory,describeScopeWorkspaceMismatch,resolveTaskId:(session)=>session?.currentTaskId??null};function reportScopeViolation(agentName,filePath,taskId,session,injectAdvisory,state,scopeEntries){let violationMessage=`SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskId??"unknown"}. Declared scope: [${scopeEntries.slice(0,3).join(", ")}${scopeEntries.length>3?"...":""}]`;if(session)session.lastScopeViolation=violationMessage,session.scopeViolationDetected=!0;if(injectAdvisory)for(let[archSessionId,archSession]of state.agentSessions){let archAgent=state.activeAgent.get(archSessionId)??archSession.agentName;if(stripKnownSwarmPrefix(archAgent)===ORCHESTRATOR_NAME){try{injectAdvisory(archSessionId,`[SCOPE GUARD] ${violationMessage}`)}catch{}break}}throw Error(violationMessage)}init_constants();init_schema();init_state2();init_normalize_tool_name();function createSelfReviewHook(config3,injectAdvisory){let enabled=config3.enabled??!0,skipInTurbo=config3.skip_in_turbo??!0;return{toolAfter:async(input,output)=>{if(!enabled)return;if(normalizeToolName(input.tool)!=="update_task_status")return;let args2=output.args;if(args2?.status!=="in_progress")return;let taskId=typeof args2?.task_id==="string"?args2.task_id:"unknown",sessionId=input.sessionID,agentName=swarmState.activeAgent.get(sessionId)??swarmState.agentSessions.get(sessionId)?.agentName??"";if(stripKnownSwarmPrefix(agentName)!==ORCHESTRATOR_NAME)return;if(skipInTurbo){let session=swarmState.agentSessions.get(sessionId);if(session&&session.turboMode===!0)return}let advisory=[`[SELF-REVIEW] Task ${taskId} is now delegated to coder.`,"After coder completes, review for:"," • Broken conditionals (inverted if/else, wrong comparisons)"," • Off-by-one errors (array bounds, loop indices)"," • Assumptions contradicting existing codebase patterns"," • Missing error handling (uncaught exceptions, unhandled promises)"," • Scope creep (changes outside the declared task spec)","Delegate to critic with self-review focus before marking complete."].join(`
|