import {
  checkSizingAdvisory
} from "./chunk-DSYBDHYH.js";
import {
  resolveStateDir
} from "./chunk-NRAXROED.js";
import {
  isInWorktree
} from "./chunk-E3REJTAJ.js";
import {
  SpawnStrategyFactory,
  WUStateStore,
  WU_BRIEF_EVIDENCE_NOTE_PREFIX,
  WU_OPTIONS,
  createWUParser,
  formatDependencyError,
  validateSpawnDependencies
} from "./chunk-2GXVIN57.js";
import {
  SPAWN_END_SENTINEL,
  TRUNCATION_WARNING_BANNER,
  evaluateCondition,
  formatSpawnRecordedMessage,
  generateAgentCoordinationSection,
  generateClientSkillsGuidance,
  generateExecutionModeSection,
  generateSkillsSelectionSection,
  generateThinkToolGuidance,
  loadTemplatesWithOverrides,
  recordSpawnToRegistry,
  replaceTokens,
  resolveClientConfig,
  validateSpawnArgs
} from "./chunk-6W5XHWYV.js";
import {
  checkLaneLock,
  getLockPolicyForLane,
  getWipLimitForLane
} from "./chunk-JONWQUB5.js";
import {
  createGitForPath
} from "./chunk-2UFQ3A3C.js";
import {
  TEST_METHODOLOGY_HINTS,
  classifyWork,
  generateCodeCraftGuidance,
  generateDesignContextSection,
  generateEnforcementSummary,
  generateMandatoryStandards,
  generatePolicyBasedTestGuidance,
  generateReadBeforeWriteDiscipline,
  generateSelfReviewDirective
} from "./chunk-NMG736UR.js";
import {
  INVARIANT_TYPES,
  loadInvariants
} from "./chunk-EZ6ZBYBM.js";
import {
  parseYAML
} from "./chunk-NRIZR3A7.js";
import {
  WU_PATHS
} from "./chunk-6HO4GWJE.js";
import {
  BRANCHES,
  CONFIG_FILES,
  DIRECTORIES,
  EMOJI,
  FILE_SYSTEM,
  LUMENFLOW_PATHS,
  PATTERNS,
  REMOTES
} from "./chunk-DWMLTXKQ.js";
import {
  WU_STATUS,
  findProjectRoot,
  getConfig,
  resolvePolicy
} from "./chunk-V6OJGLBA.js";
import {
  ErrorCodes,
  createError,
  die
} from "./chunk-RXRKBBSM.js";

// src/wu-spawn-strategy-resolver.ts
import { existsSync as existsSync3, readFileSync } from "fs";

// ../core/dist/wu-spawn-context.js
import { existsSync, statSync } from "fs";
import path from "path";
var DEFAULT_MAX_SIZE = 4096;
var MEMORY_PATHS = {
  MEMORY_DIR: LUMENFLOW_PATHS.MEMORY_DIR,
  MEMORY_FILE: "memory.jsonl"
};
var MEMORY_CONTEXT_ERRORS = {
  DEPRECATED_SPAWN_CONTEXT_MAX_SIZE: "memory.spawn_context_max_size is no longer supported. Use memory.delegation_context_max_size instead."
};
var MEMORY_CONTEXT_SECTION_HEADER = "## Memory Context";
async function checkMemoryLayerInitialized(baseDir) {
  const memoryFilePath = path.join(baseDir, MEMORY_PATHS.MEMORY_DIR, MEMORY_PATHS.MEMORY_FILE);
  if (!existsSync(memoryFilePath)) {
    return false;
  }
  try {
    const stats = statSync(memoryFilePath);
    return stats.size > 0;
  } catch {
    return false;
  }
}
function getMemoryContextMaxSize(config) {
  const memoryConfig = config;
  if (memoryConfig?.memory?.spawn_context_max_size !== void 0) {
    throw createError(ErrorCodes.DEPRECATED_API, MEMORY_CONTEXT_ERRORS.DEPRECATED_SPAWN_CONTEXT_MAX_SIZE);
  }
  return memoryConfig?.memory?.delegation_context_max_size ?? DEFAULT_MAX_SIZE;
}
function hasGenerateContext(module) {
  if (!module || typeof module !== "object") {
    return false;
  }
  const candidate = module;
  return typeof candidate.generateContext === "function";
}
async function callMemContextCore(baseDir, options) {
  try {
    const memoryModuleName = "@lumenflow/memory";
    const memModule = await import(memoryModuleName);
    if (!hasGenerateContext(memModule)) {
      return null;
    }
    return await memModule.generateContext(baseDir, options);
  } catch {
    return null;
  }
}
function formatForSpawnPrompt(contextBlock, wuId) {
  if (!contextBlock || contextBlock.trim() === "") {
    return "";
  }
  let content = contextBlock.replace(/^<!--\s*mem:context[^>]*-->\s*\n*/m, "");
  content = content.replace(/^## /gm, "### ");
  const header = `${MEMORY_CONTEXT_SECTION_HEADER}

`;
  const intro = `Prior context from memory layer for ${wuId}:

`;
  return header + intro + content.trim() + "\n";
}
async function generateMemoryContextSection(baseDir, options) {
  const { wuId, lane, maxSize = DEFAULT_MAX_SIZE, sortByDecay = false, trackAccess = false, maxRecentSummaries, maxProjectNodes } = options;
  const isInitialized = await checkMemoryLayerInitialized(baseDir);
  if (!isInitialized) {
    return "";
  }
  const result = await callMemContextCore(baseDir, {
    wuId,
    maxSize,
    sortByDecay,
    trackAccess,
    lane,
    maxRecentSummaries,
    maxProjectNodes
  });
  if (!result) {
    return "";
  }
  if (!result.success || result.stats.totalNodes === 0) {
    return "";
  }
  return formatForSpawnPrompt(result.contextBlock, wuId);
}

// src/wu-spawn-prompt-builders.ts
import { existsSync as existsSync2 } from "fs";
import path2 from "path";
import { fileURLToPath } from "url";
import { minimatch } from "minimatch";

// src/wu-spawn-completion.ts
var COMPLETION_COMMANDS = {
  GATES: "pnpm gates",
  STATUS_PREFIX: "pnpm wu:status --id",
  DONE_PREFIX: "pnpm wu:done --id",
  RECOVER_PREFIX: "pnpm wu:recover --id"
};
var WU_STATUS_VALUES = {
  DONE: "done",
  IN_PROGRESS: "in_progress"
};
function formatWuCommand(commandPrefix, id) {
  return `${commandPrefix} ${id}`;
}
function generateCompletionWorkflowSection(id) {
  const statusCommand = formatWuCommand(COMPLETION_COMMANDS.STATUS_PREFIX, id);
  const doneCommand = formatWuCommand(COMPLETION_COMMANDS.DONE_PREFIX, id);
  const recoverCommand = formatWuCommand(COMPLETION_COMMANDS.RECOVER_PREFIX, id);
  return `## Completion Workflow

**CRITICAL: Complete autonomously. Do NOT ask for permission.**

After all acceptance criteria are satisfied:

1. Run gates in the worktree: \`${COMPLETION_COMMANDS.GATES}\`
2. If gates pass, cd back to main checkout
3. Verify status from main: \`${statusCommand}\`
4. If status is \`${WU_STATUS_VALUES.DONE}\`, stop and report already completed.
   do NOT run \`${doneCommand}\`.
   do NOT run \`${recoverCommand}\`.
5. If status is \`${WU_STATUS_VALUES.IN_PROGRESS}\`, continue autonomously with \`${doneCommand}\`.

\`\`\`bash
# From worktree, after gates pass:
cd /path/to/main  # NOT the worktree
${statusCommand}

# Status decision:
# - done: report already completed, stop.
# - in_progress: complete now.
${doneCommand}
\`\`\`

**wu:done** handles: merge to main, stamp creation, worktree cleanup.

**Do not ask** "should I run wu:done?" \u2014 just run it when gates pass.`;
}

// src/wu-spawn-prompt-builders.ts
var SPAWN_PROMPT_BUILDERS_DIR = path2.dirname(fileURLToPath(import.meta.url));
var DEFAULT_TEMPLATE_BASE_DIR = findProjectRoot(SPAWN_PROMPT_BUILDERS_DIR);
var DEFAULT_WORKTREES_DIR_SEGMENT = DIRECTORIES.WORKTREES.replace(/\/+$/g, "");
var PRIMARY_MAIN_REF = `${REMOTES.ORIGIN}/${BRANCHES.MAIN}`;
var LANE_GUIDANCE_TEMPLATE_ID_PREFIX = "lane-guidance-";
var DESIGN_CONTEXT_TEMPLATE_ID_PREFIX = "design-context-";
var VERIFICATION_TEMPLATE_ID_PREFIX = "verification-";
var REQUIRED_VERIFICATION_TEMPLATE_ID = "verification-requirements";
var VERIFICATION_TEMPLATE_IDS = /* @__PURE__ */ new Set([
  "documentation-directive",
  "visual-directive",
  "refactor-directive",
  "structured-content-directive"
]);
function normalizeDirectorySegment(value, fallback) {
  const normalized = value.replace(/\\/g, "/").replace(/^\/+|\/+$/g, "");
  return normalized.length > 0 ? normalized : fallback;
}
function resolveWorktreesDirSegment(config) {
  const configuredWorktreesDir = config?.directories.worktrees;
  if (configuredWorktreesDir) {
    return normalizeDirectorySegment(configuredWorktreesDir, DEFAULT_WORKTREES_DIR_SEGMENT);
  }
  return DEFAULT_WORKTREES_DIR_SEGMENT;
}
function resolveWorktreePathHint(doc, id, config) {
  if (doc.worktree_path) {
    return doc.worktree_path;
  }
  return `${resolveWorktreesDirSegment(config)}/<lane>-${id.toLowerCase()}`;
}
function resolveClaimWorktreePathHint(lane, id, config) {
  const laneSlug = (lane || "unknown").toLowerCase().replace(/[:\s]+/g, "-").replace(/-+/g, "-");
  return `${resolveWorktreesDirSegment(config)}/${laneSlug}-${id.toLowerCase()}`;
}
function usesNonTddHint(testMethodologyHint) {
  return testMethodologyHint === TEST_METHODOLOGY_HINTS.SMOKE_TEST || testMethodologyHint === TEST_METHODOLOGY_HINTS.STRUCTURED_CONTENT;
}
function resolveLaneGuidanceSection(templates, lane) {
  const templateSections = collectTemplateSections(
    templates,
    (id) => id.startsWith(LANE_GUIDANCE_TEMPLATE_ID_PREFIX)
  );
  if (templateSections.length > 0) {
    return templateSections.join("\n\n---\n\n");
  }
  return generateLaneGuidance(lane);
}
function collectTemplateSections(templates, matcher) {
  return Array.from(templates.entries()).filter(([id]) => matcher(id)).map(([, content]) => content.trim()).filter((content) => content.length > 0);
}
function resolveVerificationGuidanceSection(templates, fallback) {
  const requiredVerificationSections = collectTemplateSections(
    templates,
    (id) => id === REQUIRED_VERIFICATION_TEMPLATE_ID
  );
  const strategySections = collectTemplateSections(
    templates,
    (id) => id !== REQUIRED_VERIFICATION_TEMPLATE_ID && (id.startsWith("methodology-") || id.startsWith(VERIFICATION_TEMPLATE_ID_PREFIX) || VERIFICATION_TEMPLATE_IDS.has(id))
  );
  const templateSections = [...requiredVerificationSections, ...strategySections];
  if (templateSections.length > 0) {
    return templateSections.join("\n\n---\n\n");
  }
  return fallback;
}
function resolveDesignContextSection(templates, classification) {
  const templateSections = collectTemplateSections(
    templates,
    (id) => id.startsWith(DESIGN_CONTEXT_TEMPLATE_ID_PREFIX)
  );
  if (templateSections.length > 0) {
    return templateSections.join("\n\n---\n\n");
  }
  return generateDesignContextSection(classification);
}
var MANDATORY_TRIGGERS = {
  // No mandatory triggers for LumenFlow framework development.
};
function detectMandatoryAgents(codePaths) {
  if (!codePaths || codePaths.length === 0) {
    return [];
  }
  const triggeredAgents = /* @__PURE__ */ new Set();
  for (const [agentName, patterns] of Object.entries(MANDATORY_TRIGGERS)) {
    const isTriggered = codePaths.some(
      (filePath) => patterns.some((pattern) => minimatch(filePath, pattern))
    );
    if (isTriggered) {
      triggeredAgents.add(agentName);
    }
  }
  return Array.from(triggeredAgents);
}
function formatAcceptance(acceptance) {
  if (!acceptance || acceptance.length === 0) {
    return "- No acceptance criteria defined";
  }
  return acceptance.map((item) => `- [ ] ${item}`).join("\n");
}
function formatSpecRefs(specRefs) {
  if (!specRefs || specRefs.length === 0) {
    return "";
  }
  return specRefs.map((ref) => `- ${ref}`).join("\n");
}
function formatRisks(risks) {
  if (!risks || risks.length === 0) {
    return "";
  }
  return risks.map((risk) => `- ${risk}`).join("\n");
}
function formatManualTests(manualTests) {
  if (!manualTests || manualTests.length === 0) {
    return "";
  }
  return manualTests.map((test) => `- [ ] ${test}`).join("\n");
}
function formatTestPaths(testPaths) {
  if (!testPaths || testPaths.length === 0) {
    return "";
  }
  return testPaths.map((testPath) => `- \`${testPath}\``).join("\n");
}
function formatRequiredVerification(doc) {
  const sections = [];
  const unitTests = formatTestPaths(doc.tests?.unit);
  if (unitTests) {
    sections.push(`### Unit Test Paths

${unitTests}`);
  }
  const e2eTests = formatTestPaths(doc.tests?.e2e);
  if (e2eTests) {
    sections.push(`### E2E Test Paths

${e2eTests}`);
  }
  const manualTests = formatManualTests(doc.tests?.manual);
  if (manualTests) {
    sections.push(`### Manual Verification

${manualTests}`);
  }
  return sections.join("\n\n");
}
function generateRequiredVerificationSection(doc) {
  const requiredVerification = formatRequiredVerification(doc);
  if (!requiredVerification) {
    return "";
  }
  return `## Required Verification From WU Spec

${requiredVerification}`;
}
function generateImplementationContext(doc) {
  const sections = [];
  const refs = formatSpecRefs(doc.spec_refs);
  if (refs) {
    sections.push(`## References

${refs}`);
  }
  if (doc.notes && doc.notes.trim()) {
    sections.push(`## Implementation Notes

${doc.notes.trim()}`);
  }
  const risks = formatRisks(doc.risks);
  if (risks) {
    sections.push(`## Risks

${risks}`);
  }
  if (sections.length === 0) {
    return "";
  }
  return sections.join("\n\n---\n\n");
}
function codePathMatchesInvariant(invariant, codePaths) {
  switch (invariant.type) {
    case INVARIANT_TYPES.FORBIDDEN_FILE:
    case INVARIANT_TYPES.REQUIRED_FILE: {
      const invariantPath = invariant.path;
      if (!invariantPath) {
        return false;
      }
      return codePaths.some(
        (p) => p === invariantPath || minimatch(p, invariantPath) || minimatch(invariantPath, p)
      );
    }
    case INVARIANT_TYPES.MUTUAL_EXCLUSIVITY: {
      const invariantPaths = invariant.paths;
      if (!invariantPaths || invariantPaths.length === 0) {
        return false;
      }
      return codePaths.some(
        (p) => invariantPaths.some((invPath) => p === invPath || minimatch(p, invPath))
      );
    }
    case INVARIANT_TYPES.FORBIDDEN_PATTERN:
    case INVARIANT_TYPES.REQUIRED_PATTERN:
      return invariant.scope?.some(
        (scopePattern) => codePaths.some((p) => minimatch(p, scopePattern))
      ) ?? false;
    // WU-2254: forbidden-import uses 'from' glob instead of 'scope'
    case INVARIANT_TYPES.FORBIDDEN_IMPORT:
      return invariant.from ? codePaths.some((p) => minimatch(p, invariant.from)) : false;
    default:
      return false;
  }
}
function formatInvariantForOutput(inv) {
  const lines = [`### ${inv.id} (${inv.type})`, "", inv.description, ""];
  if (inv.message) {
    lines.push(`**Action:** ${inv.message}`, "");
  }
  if (inv.path) {
    lines.push(`**Path:** \`${inv.path}\``);
  }
  if (inv.paths) {
    const formattedPaths = inv.paths.map((p) => `\`${p}\``).join(", ");
    lines.push(`**Paths:** ${formattedPaths}`);
  }
  if (inv.from) {
    lines.push(`**From:** \`${inv.from}\``);
  }
  if (inv.cannot_import && Array.isArray(inv.cannot_import)) {
    const formattedImports = inv.cannot_import.map((m) => `\`${m}\``).join(", ");
    lines.push(`**Cannot Import:** ${formattedImports}`);
  }
  if (inv.pattern && (inv.type === INVARIANT_TYPES.REQUIRED_PATTERN || inv.type === INVARIANT_TYPES.FORBIDDEN_PATTERN)) {
    lines.push(`**Pattern:** \`${inv.pattern}\``);
  }
  if (inv.scope && Array.isArray(inv.scope)) {
    const formattedScope = inv.scope.map((s) => `\`${s}\``).join(", ");
    lines.push(`**Scope:** ${formattedScope}`);
  }
  lines.push("");
  return lines;
}
function generateInvariantsPriorArtSection(codePaths) {
  if (!codePaths || codePaths.length === 0) {
    return "";
  }
  const invariantsPath = path2.resolve("tools/invariants.yml");
  if (!existsSync2(invariantsPath)) {
    return "";
  }
  let invariants;
  try {
    invariants = loadInvariants(invariantsPath);
  } catch {
    return "";
  }
  if (!invariants || invariants.length === 0) {
    return "";
  }
  const relevantInvariants = invariants.filter((inv) => codePathMatchesInvariant(inv, codePaths));
  if (relevantInvariants.length === 0) {
    return "";
  }
  const lines = [
    "## Invariants/Prior-Art (WU-2252)",
    "",
    "The following repo invariants are relevant to your code_paths:",
    "",
    ...relevantInvariants.flatMap(formatInvariantForOutput),
    "**IMPORTANT:** Do not create specs or acceptance criteria that conflict with these invariants."
  ];
  return lines.join("\n");
}
function generatePreamble(id, strategy) {
  return strategy.getPreamble(id);
}
function generateConstraints(id, options) {
  const includeTdd = options?.includeTddCheckpoint !== false;
  const tddCheckpointBlock = includeTdd ? `
1. TDD CHECKPOINT (VERIFY BEFORE IMPLEMENTATION)
   - Did you write tests BEFORE implementation?
   - Is there at least one failing test for each acceptance criterion?
   - Never skip the RED phase \u2014 failing tests prove the test works

` : "";
  const antiLoopNum = includeTdd ? 2 : 1;
  const stopAskNum = includeTdd ? 3 : 2;
  const verifyNum = includeTdd ? 4 : 3;
  const neverFabNum = includeTdd ? 5 : 4;
  const gitNum = includeTdd ? 6 : 5;
  const memNum = includeTdd ? 7 : 6;
  const skipGatesNum = includeTdd ? 8 : 7;
  return `---

<constraints>
CRITICAL RULES - ENFORCE BEFORE EVERY ACTION:
${tddCheckpointBlock}${antiLoopNum}. ANTI-LOOP GUARD (LumenFlow \xA77.3)
   - Max 3 attempts per unique error before escalating
   - If same error repeats 3x, STOP and report with full context
   - Retry with different approach, not same command

${stopAskNum}. STOP-AND-ASK TRIGGERS (LumenFlow \xA77.2 - narrow scope)
   - Policy changes, auth/permissions modifications
   - PII/safety issues, cloud spend, secrets, backups
   - Same error repeats 3x
   - For ordinary errors: fix and retry autonomously (up to 3 attempts)

${verifyNum}. VERIFY COMPLETION before reporting success
   - Run: node packages/@lumenflow/agent/dist/agent-verification.js ${id} (from shared checkout)
   - Exit 0 = passed, Exit 1 = INCOMPLETE
   - Never report "done" if verification fails

${neverFabNum}. NEVER FABRICATE COMPLETION
   - If blockers remain, report INCOMPLETE
   - If verification fails, summarize failures
   - Honesty over false completion

${gitNum}. GIT WORKFLOW (CRITICAL - GitHub rules reject merge commits)
   - GitHub REJECTS merge commits on main
   - ALWAYS use \`git rebase ${PRIMARY_MAIN_REF}\` before push
   - Push to main via \`git push origin lane/...:main\` (fast-forward only)
   - NEVER use \`git merge\` on main branch
   - Let \`pnpm wu:done\` handle the merge workflow

${memNum}. MEMORY LAYER COORDINATION (INIT-007)
   - Use \`pnpm mem:checkpoint --wu ${id}\` to save progress before risky operations
   - Check \`pnpm mem:inbox --wu ${id}\` periodically for parallel signals from other agents
   - Checkpoint triggers (WU-1943): checkpoint after each acceptance criterion completed, checkpoint before gates, checkpoint every 30 tool calls

${skipGatesNum}. SKIP-GATES AUTONOMY (WU-1142)
   - If gates fail, first check if failure is pre-existing on main: \`git checkout main && pnpm gates\`
   - If failure exists on main (not your change), use: \`pnpm wu:done --id ${id} --skip-gates --reason "pre-existing on main" --fix-wu WU-XXXX\`
   - Do NOT ask for approval - autonomous skip-gates for pre-existing failures is correct
   - This prevents getting stuck on infrastructure debt
</constraints>`;
}
function generateCodexConstraints(id, options) {
  const includeTdd = options?.includeTddCheckpoint !== false;
  const tddLine = includeTdd ? "1. **TDD checkpoint**: tests BEFORE implementation; never skip RED" : "";
  const stopNum = includeTdd ? 2 : 1;
  const verifyNum = includeTdd ? 3 : 2;
  const fabricateNum = includeTdd ? 4 : 3;
  const gitNum = includeTdd ? 5 : 4;
  const scopeNum = includeTdd ? 6 : 5;
  const skipGatesNum = includeTdd ? 7 : 6;
  return `## Constraints (Critical)

${tddLine}${tddLine ? "\n" : ""}${stopNum}. **Stop on errors**: if UnsafeAny command fails, report BLOCKED (never DONE) with the error
${verifyNum}. **Verify before success**: run \`pnpm gates\` in the worktree, then run \`node packages/@lumenflow/agent/dist/agent-verification.js ${id}\` (from the shared checkout)
${fabricateNum}. **No fabrication**: if blockers remain or verification fails, report INCOMPLETE
${gitNum}. **Git workflow**: avoid merge commits; let \`pnpm wu:done\` handle completion
${scopeNum}. **Scope discipline**: stay within \`code_paths\`; capture out-of-scope issues via \`pnpm mem:create\`
${skipGatesNum}. **Skip-gates for pre-existing**: if gates fail due to pre-existing issue on main, use \`--skip-gates --reason "pre-existing" --fix-wu WU-XXX\``;
}
function generateMandatoryAgentSection(mandatoryAgents, _id) {
  if (mandatoryAgents.length === 0) {
    return "";
  }
  const agentList = mandatoryAgents.map((agent) => `  - ${agent}`).join("\n");
  return `
## Mandatory Agents (MUST invoke before wu:done)

Based on code_paths, the following agents MUST be invoked:

${agentList}

Run: pnpm orchestrate:monitor to check agent status
`;
}
function generateEffortScalingRules() {
  return `## Effort Scaling (When to Spawn Sub-Agents)

Use this heuristic to decide complexity:

| Complexity | Approach | Tool Calls |
|------------|----------|------------|
| **Simple** (single file, <50 lines) | Handle inline | 3-10 |
| **Moderate** (2-3 files, clear scope) | Handle inline | 10-20 |
| **Complex** (4+ files, exploration needed) | Spawn Explore agent first | 20+ |
| **Multi-domain** (cross-cutting concerns) | Spawn specialized sub-agents | Varies |

**Rule**: If you need >30 tool calls for a subtask, consider spawning a sub-agent with a focused scope.`;
}
function generateParallelToolCallGuidance() {
  return `## Parallel Tool Calls (Performance)

**IMPORTANT**: Make 3+ tool calls in parallel when operations are independent.

Good examples:
- Reading multiple files simultaneously
- Running independent grep searches
- Spawning multiple Explore agents for different areas

Bad examples:
- Reading a file then editing it (sequential dependency)
- Running tests then checking results (sequential)

Parallelism reduces latency by 50-90% for complex tasks.`;
}
function generateIterativeSearchHeuristics() {
  return `## Search Strategy (Broad to Narrow)

When exploring the codebase:

1. **Start broad**: Use Explore agent or glob patterns to understand structure
2. **Evaluate findings**: What patterns exist? What's relevant?
3. **Narrow focus**: Target specific files/functions based on findings
4. **Iterate**: Refine if initial approach misses the target

Avoid: Jumping directly to specific file edits without understanding context.`;
}
function generateTokenBudgetAwareness(id) {
  return `## Token Budget Awareness

Context limit is ~200K tokens. Monitor your usage:

- **At 50+ tool calls**: Create a checkpoint (\`pnpm mem:checkpoint --wu ${id}\`)
- **At 100+ tool calls**: Consider spawning fresh sub-agent with focused scope
- **Before risky operations**: Always checkpoint first

If approaching limits, summarize progress and spawn continuation agent.`;
}
function generateCompletionFormat(_id) {
  return `## Completion Report Format

When finishing, provide structured output:

\`\`\`
## Summary
<1-3 sentences describing what was accomplished>

## Artifacts
- Files modified: <list>
- Tests added: <list>
- Documentation updated: <list>

## Verification
- Gates: <pass/fail>
- Tests: <X passing, Y failing>

## Blockers (if UnsafeAny)
- <blocker description>

## Follow-up (if needed)
- <suggested next WU or action>
\`\`\`

This format enables orchestrator to track progress across waves.`;
}
function generateQuickFixCommands() {
  return `## Quick Fix Commands

If gates fail, try these before investigating:

\`\`\`bash
pnpm format      # Auto-fix formatting issues
pnpm lint        # Check linting (use --fix for auto-fix)
pnpm typecheck   # Check TypeScript types
\`\`\`

**Use before gates** to catch simple issues early. These are faster than full \`pnpm gates\`.`;
}
function generateWorktreeBlockRecoverySection(worktreePath, config) {
  const worktreePathHint = worktreePath || `${resolveWorktreesDirSegment(config)}/<lane>-wu-xxx`;
  return `## When Blocked by Worktree Hook

If you encounter a "worktree required" or "commit blocked" error:

1. **Check existing worktrees**: \`git worktree list\`
2. **Navigate to the worktree**: \`cd ${worktreePathHint}\`
3. **Retry your operation** from within the worktree
4. **Use relative paths only** (never absolute paths starting with /)

### Common Causes

- Running \`git commit\` from main checkout instead of worktree
- Using absolute paths that bypass worktree isolation
- Forgetting to \`cd\` to worktree after \`wu:claim\`

### Quick Fix

\`\`\`bash
# Check where you are
pwd
git worktree list

# Navigate to your worktree
cd ${worktreePathHint}

# Retry your commit
git add . && git commit -m "your message"
\`\`\``;
}
function generateLaneSelectionSection(laneInferencePath = CONFIG_FILES.LANE_INFERENCE) {
  return `## Lane Selection

When creating new WUs, use the correct lane to enable parallelization:

\`\`\`bash
# Get lane suggestion based on code paths and description
pnpm wu:infer-lane --id WU-XXX

# Or infer from manual inputs
pnpm wu:infer-lane --paths "tools/**" --desc "CLI improvements"
\`\`\`

**Lane taxonomy**: See \`${laneInferencePath}\` for valid lanes and patterns.

**Why lanes matter**: WIP=1 per lane means correct lane selection enables parallel work across lanes.`;
}
function generateWorktreePathGuidance(worktreePath) {
  if (!worktreePath) {
    return "";
  }
  return `## Worktree Path Guidance (WU-2362)

**Your worktree:** \`${worktreePath}\`

### Finding the Worktree Root

Sub-agents may inherit the parent's cwd (main checkout). To find the actual worktree root:

\`\`\`bash
# Get the worktree root (not main checkout)
git rev-parse --show-toplevel
\`\`\`

### Stamp Creation

When creating \`.lumenflow/\` stamps or other artifacts:

1. **ALWAYS** create stamps in the **worktree**, not main
2. Use \`git rev-parse --show-toplevel\` to get the correct base path
3. Stamps created on main will be lost when the worktree merges

\`\`\`bash
# CORRECT: Create stamp in worktree
WORKTREE_ROOT=$(git rev-parse --show-toplevel)
mkdir -p "$WORKTREE_ROOT/.lumenflow/agent-runs"
touch "$WORKTREE_ROOT/.lumenflow/agent-runs/code-reviewer.stamp"

# WRONG: Hardcoded path to main
# touch /path/to/main/.lumenflow/agent-runs/code-reviewer.stamp
\`\`\`

### Why This Matters

- Stamps on main get overwritten by worktree merge
- \`wu:done\` validates stamps exist in the worktree branch
- Parallel WUs in other lanes won't see your stamps if on main`;
}
function generateBugDiscoverySection(id) {
  return `## Bug Discovery (Mid-WU Issue Capture)

If you discover a bug or issue **outside the scope of this WU**:

1. **Capture it immediately** using:
   \`\`\`bash
   pnpm mem:create 'Bug: <description>' --type discovery --tags bug,scope-creep --wu ${id}
   \`\`\`

2. **Continue with your WU** \u2014 do not fix bugs outside your scope
3. **Reference in notes** \u2014 mention the mem node ID in your completion notes

### NEVER use wu:create for discovered issues

**Do NOT use \`wu:create\` directly for bugs discovered mid-WU.**

- \`mem:create\` = **capture** (immediate, no human approval needed)
- \`wu:create\` = **planned work** (requires human triage and approval)

Discovered issues MUST go through human triage before becoming WUs.
Using \`wu:create\` directly bypasses the triage workflow and creates
unreviewed work items.

### When to Capture

- Found a bug in code NOT in your \`code_paths\`
- Discovered an issue that would require >10 lines to fix
- Encountered broken behaviour unrelated to your acceptance criteria

### Triage Workflow

After WU completion, bugs can be promoted to Bug WUs by humans:
\`\`\`bash
pnpm mem:triage --wu ${id}           # List discoveries for this WU
pnpm mem:triage --promote <node-id> --lane "<lane>"  # Create Bug WU (human action)
\`\`\`

See: https://lumenflow.dev/reference/agent-invocation-guide/ \xA7Bug Discovery`;
}
function generateLaneGuidance(lane) {
  if (!lane) return "";
  const laneParent = lane.split(":")[0].trim();
  const guidance = {
    Operations: `## Lane-Specific: Tooling

- Update tool documentation in tools/README.md or relevant docs if adding new CLI commands`,
    Intelligence: `## Lane-Specific: Intelligence

- For prompt/classification work, run the project-specific evaluation command defined by your local templates/config
- Follow prompt versioning guidelines documented for this project`,
    Experience: `## Lane-Specific: Experience

- Follow design system tokens defined in the project
- Ensure accessibility compliance (WCAG 2.1 AA)`,
    Core: `## Lane-Specific: Core

- Maintain hexagonal architecture boundaries
- Update domain model documentation if changing entities`
  };
  return guidance[laneParent] || "";
}
function generateActionSection(doc, id, config) {
  const isAlreadyClaimed = doc.claimed_at && doc.worktree_path;
  if (isAlreadyClaimed) {
    return `This WU is already claimed. Continue implementation in worktree following all standards above.

cd ${doc.worktree_path}`;
  }
  const claimWorktreePathHint = resolveClaimWorktreePathHint(doc.lane, id, config);
  return `**FIRST: Claim this WU before starting work:**

\`\`\`bash
pnpm wu:claim --id ${id} --lane "${doc.lane}"
cd ${claimWorktreePathHint}
\`\`\`

Then implement following all standards above.

**CRITICAL:** Never use \`git worktree add\` directly. Always use \`pnpm wu:claim\` to ensure:
- Event tracking in ${LUMENFLOW_PATHS.WU_EVENTS}
- Lane lock acquisition (WIP=1 enforcement)
- Session tracking for context recovery`;
}
function generateCompletionWorkflowSection2(id) {
  return generateCompletionWorkflowSection(id);
}
function generateClientBlocksSection(clientContext) {
  if (!clientContext?.config?.blocks?.length) return "";
  const blocks = clientContext.config.blocks.map((block) => `### ${block.title}

${block.content}`).join("\n\n");
  return `## Client Guidance (${clientContext.name})

${blocks}`;
}
function tryLoadTemplates(clientName, context, baseDir = DEFAULT_TEMPLATE_BASE_DIR) {
  const result = /* @__PURE__ */ new Map();
  try {
    const templates = loadTemplatesWithOverrides(baseDir, clientName);
    for (const [id, template] of templates) {
      const condition = template.frontmatter.condition;
      if (!evaluateCondition(condition, context)) {
        continue;
      }
      const processed = replaceTokens(template.content, context);
      result.set(id, processed);
    }
  } catch {
  }
  return result;
}
function buildSpawnTemplateContext(doc, id, policy, classification) {
  const lane = doc.lane || "";
  const laneParent = lane.split(":")[0]?.trim() || "";
  const type = (doc.type || "feature").toLowerCase();
  const requiredVerification = formatRequiredVerification(doc);
  const workDomain = classification?.domain || "";
  const workTestMethodologyHint = classification?.testMethodologyHint || "";
  const context = {
    WU_ID: id,
    LANE: lane,
    TYPE: type,
    TITLE: doc.title || "",
    DESCRIPTION: doc.description || "",
    WORKTREE_PATH: doc.worktree_path || "",
    laneParent,
    WORK_DOMAIN: workDomain,
    WORK_TEST_METHODOLOGY_HINT: workTestMethodologyHint,
    REQUIRED_VERIFICATION: requiredVerification,
    // Lowercase aliases for condition evaluation
    type,
    lane,
    worktreePath: doc.worktree_path || "",
    "work.domain": workDomain,
    "work.testMethodologyHint": workTestMethodologyHint,
    hasRequiredVerification: requiredVerification ? "true" : void 0,
    "tests.hasUnit": doc.tests?.unit?.length ? "true" : void 0,
    "tests.hasE2E": doc.tests?.e2e?.length ? "true" : void 0,
    "tests.hasManual": doc.tests?.manual?.length ? "true" : void 0
  };
  if (policy) {
    context["policy.testing"] = policy.testing;
    context["policy.architecture"] = policy.architecture;
  }
  return context;
}
function generateTaskInvocation(doc, id, strategy, options = {}) {
  const codePaths = doc.code_paths || [];
  const mandatoryAgents = detectMandatoryAgents(codePaths);
  const preamble = generatePreamble(id, strategy);
  const clientContext = options.client;
  const config = options.config || getConfig();
  const policy = resolvePolicy(config);
  const classificationConfig = config?.methodology?.work_classification;
  const classification = classifyWork(
    {
      code_paths: doc.code_paths,
      lane: doc.lane,
      type: doc.type,
      description: doc.description
    },
    classificationConfig
  );
  const clientName = options.client?.name || "claude-code";
  const templateContext = buildSpawnTemplateContext(doc, id, policy, classification);
  const templateBaseDir = options.baseDir || DEFAULT_TEMPLATE_BASE_DIR;
  const templates = tryLoadTemplates(clientName, templateContext, templateBaseDir);
  const testGuidanceFallback = [
    generateRequiredVerificationSection(doc),
    generatePolicyBasedTestGuidance(doc.type || "feature", policy, {
      testMethodologyHint: classification.testMethodologyHint
    })
  ].filter((section) => section.length > 0).join("\n\n---\n\n");
  const testGuidance = resolveVerificationGuidanceSection(templates, testGuidanceFallback);
  const enforcementSummary = generateEnforcementSummary(policy, {
    testMethodologyHint: classification.testMethodologyHint
  });
  const mandatoryStandards = generateMandatoryStandards(policy, {
    testMethodologyHint: classification.testMethodologyHint
  });
  const codeCraftGuidance = templates.get("code-craft") || generateCodeCraftGuidance();
  const readBeforeWrite = templates.get("read-before-write") || generateReadBeforeWriteDiscipline();
  const selfReviewDirective = templates.get("self-review") || generateSelfReviewDirective(id);
  const clientSkillsGuidance = generateClientSkillsGuidance(clientContext, doc.lane);
  const skillsTemplateContent = templates.get("skills-selection");
  const skillsGuidanceSuffix = clientSkillsGuidance ? "\n" + clientSkillsGuidance : "";
  const skillsBaseContent = skillsTemplateContent || generateSkillsSelectionSection(doc, config, clientContext?.name);
  const skillsSection = skillsBaseContent + skillsGuidanceSuffix;
  const clientBlocks = generateClientBlocksSection(clientContext);
  const mandatorySection = generateMandatoryAgentSection(mandatoryAgents, id);
  const bugDiscoverySection = templates.get("bug-discovery") || generateBugDiscoverySection(id);
  const shouldIncludeTddCheckpoint = !usesNonTddHint(classification.testMethodologyHint) && policy.testing !== "none";
  const constraints = templates.get("constraints") || generateConstraints(id, {
    includeTddCheckpoint: shouldIncludeTddCheckpoint
  });
  const implementationContext = generateImplementationContext(doc);
  const designContextSection = resolveDesignContextSection(templates, classification);
  const invariantsPriorArt = generateInvariantsPriorArtSection(codePaths);
  const effortScaling = templates.get("effort-scaling") || generateEffortScalingRules();
  const parallelToolCalls = templates.get("parallel-tool-calls") || generateParallelToolCallGuidance();
  const searchHeuristics = templates.get("search-heuristics") || generateIterativeSearchHeuristics();
  const tokenBudget = templates.get("token-budget") || generateTokenBudgetAwareness(id);
  const completionFormat = generateCompletionFormat(id);
  const completionWorkflow = templates.get("completion-workflow") || generateCompletionWorkflowSection2(id);
  const agentCoordination = generateAgentCoordinationSection(id);
  const quickFix = templates.get("quick-fix-commands") || generateQuickFixCommands();
  const laneSelection = templates.get("lane-selection") || generateLaneSelectionSection(CONFIG_FILES.LANE_INFERENCE);
  const worktreePathHint = resolveWorktreePathHint(doc, id, config);
  const worktreeGuidance = generateWorktreePathGuidance(doc.worktree_path);
  const worktreeBlockRecovery = templates.get("worktree-recovery") || generateWorktreeBlockRecoverySection(worktreePathHint, config);
  const laneGuidance = resolveLaneGuidanceSection(templates, doc.lane);
  const shouldIncludeMemoryContext = options.includeMemoryContext && !options.noContext;
  const memoryContextSection = shouldIncludeMemoryContext ? options.memoryContextContent || "" : "";
  const executionModeSection = generateExecutionModeSection(options);
  const thinkToolGuidance = generateThinkToolGuidance(options);
  const thinkingSections = [executionModeSection, thinkToolGuidance].filter((section) => section.length > 0).join("\n\n---\n\n");
  const thinkingBlock = thinkingSections ? `${thinkingSections}

---

` : "";
  const taskPrompt = `${TRUNCATION_WARNING_BANNER}<task>
${preamble}
</task>

---

${testGuidance}

---

# ${id}: ${doc.title || "Untitled"}

## WU Details

- **ID:** ${id}
- **Lane:** ${doc.lane || "Unknown"}
- **Type:** ${doc.type || "feature"}
- **Status:** ${doc.status || "unknown"}
- **Worktree:** ${worktreePathHint}

## Description

${doc.description || "No description provided."}

## Acceptance Criteria

${formatAcceptance(doc.acceptance)}

## Code Paths

${codePaths.length > 0 ? codePaths.map((p) => `- ${p}`).join("\n") : "- No code paths defined"}
${mandatorySection}${invariantsPriorArt ? `---

${invariantsPriorArt}

` : ""}${implementationContext ? `---

${implementationContext}

` : ""}---

${thinkingBlock}${skillsSection}
${memoryContextSection ? `---

${memoryContextSection}

` : ""}---

${mandatoryStandards}

---

${enforcementSummary}

---

${codeCraftGuidance}

---

${readBeforeWrite}

${designContextSection ? `---

${designContextSection}

` : ""}${clientBlocks ? `---

${clientBlocks}

` : ""}${worktreeGuidance ? `---

${worktreeGuidance}

` : ""}---

${bugDiscoverySection}

---

${effortScaling}

---

${parallelToolCalls}

---

${searchHeuristics}

---

${tokenBudget}

---

${completionFormat}

---

${completionWorkflow}

---

${agentCoordination}

---

${quickFix}

---

${laneSelection}

---

${laneGuidance}${laneGuidance ? "\n\n---\n\n" : ""}## Action

${generateActionSection(doc, id, config)}

---

${selfReviewDirective}

---

${worktreeBlockRecovery}

${constraints}

${SPAWN_END_SENTINEL}`;
  const escapedPrompt = taskPrompt.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
  const openTag = '<antml:invoke name="Task">';
  const closeTag = "</antml:invoke>";
  const paramOpen = '<antml:parameter name="';
  const paramClose = "</antml:parameter>";
  const invocation = [
    "<antml:function_calls>",
    openTag,
    `${paramOpen}subagent_type">general-purpose${paramClose}`,
    `${paramOpen}description">Execute ${id}${paramClose}`,
    `${paramOpen}prompt">${escapedPrompt}${paramClose}`,
    closeTag,
    "</antml:function_calls>"
  ].join("\n");
  return invocation;
}
function generateCodexPrompt(doc, id, strategy, options = {}) {
  const codePaths = doc.code_paths || [];
  const mandatoryAgents = detectMandatoryAgents(codePaths);
  const config = options.config || getConfig();
  const clientContext = options.client;
  const policy = resolvePolicy(config);
  const classificationConfig = config?.methodology?.work_classification;
  const classification = classifyWork(
    {
      code_paths: doc.code_paths,
      lane: doc.lane,
      type: doc.type,
      description: doc.description
    },
    classificationConfig
  );
  const preamble = generatePreamble(id, strategy);
  const mandatoryStandards = generateMandatoryStandards(policy, {
    testMethodologyHint: classification.testMethodologyHint
  });
  const enforcementSummary = generateEnforcementSummary(policy, {
    testMethodologyHint: classification.testMethodologyHint
  });
  const mandatorySection = generateMandatoryAgentSection(mandatoryAgents, id);
  const implementationContext = generateImplementationContext(doc);
  const action = generateActionSection(doc, id, config);
  const shouldIncludeTddCheckpoint = !usesNonTddHint(classification.testMethodologyHint) && policy.testing !== "none";
  const constraints = generateCodexConstraints(id, {
    includeTddCheckpoint: shouldIncludeTddCheckpoint
  });
  const worktreePathHint = resolveWorktreePathHint(doc, id, config);
  const clientName = options.client?.name || "claude-code";
  const templateContext = buildSpawnTemplateContext(doc, id, policy, classification);
  const templateBaseDir = options.baseDir || DEFAULT_TEMPLATE_BASE_DIR;
  const templates = tryLoadTemplates(clientName, templateContext, templateBaseDir);
  const testGuidanceFallback = [
    generateRequiredVerificationSection(doc),
    generatePolicyBasedTestGuidance(doc.type || "feature", policy, {
      testMethodologyHint: classification.testMethodologyHint
    })
  ].filter((section) => section.length > 0).join("\n\n---\n\n");
  const testGuidance = resolveVerificationGuidanceSection(templates, testGuidanceFallback);
  const codeCraftGuidance = templates.get("code-craft") || generateCodeCraftGuidance();
  const readBeforeWrite = templates.get("read-before-write") || generateReadBeforeWriteDiscipline();
  const selfReviewDirective = templates.get("self-review") || generateSelfReviewDirective(id);
  const bugDiscoverySection = templates.get("bug-discovery") || generateBugDiscoverySection(id);
  const completionWorkflow = templates.get("completion-workflow") || generateCompletionWorkflowSection2(id);
  const clientSkillsGuidance = generateClientSkillsGuidance(clientContext, doc.lane);
  const skillsTemplateContent = templates.get("skills-selection");
  const skillsBaseContent = skillsTemplateContent || generateSkillsSelectionSection(doc, config, clientContext?.name);
  const skillsSection = skillsBaseContent + (clientSkillsGuidance ? `
${clientSkillsGuidance}` : "");
  const clientBlocks = generateClientBlocksSection(clientContext);
  const laneGuidance = resolveLaneGuidanceSection(templates, doc.lane);
  const designContextSection = resolveDesignContextSection(templates, classification);
  const executionModeSection = generateExecutionModeSection(options);
  const thinkToolGuidance = generateThinkToolGuidance(options);
  const thinkingSections = [executionModeSection, thinkToolGuidance].filter((section) => section.length > 0).join("\n\n---\n\n");
  const thinkingBlock = thinkingSections ? `${thinkingSections}

---

` : "";
  const worktreeBlockRecovery = generateWorktreeBlockRecoverySection(worktreePathHint, config);
  const shouldIncludeMemoryContext = options.includeMemoryContext && !options.noContext;
  const memoryContextSection = shouldIncludeMemoryContext ? options.memoryContextContent || "" : "";
  return `${TRUNCATION_WARNING_BANNER}# ${id}: ${doc.title || "Untitled"}

${testGuidance}

---

## Context

${preamble}

---

## WU Details

- **ID:** ${id}
- **Lane:** ${doc.lane || "Unknown"}
- **Type:** ${doc.type || "feature"}
- **Status:** ${doc.status || "unknown"}
- **Worktree:** ${worktreePathHint}

## Description

${doc.description || "No description provided."}

## Scope (code_paths)

Only change files within these paths:

${codePaths.length > 0 ? codePaths.map((p) => `- ${p}`).join("\n") : "- No code paths defined"}

## Acceptance Criteria

${formatAcceptance(doc.acceptance)}

---

${mandatoryStandards}

---

${enforcementSummary}

---

${codeCraftGuidance}

---

${readBeforeWrite}

${designContextSection ? `---

${designContextSection}

` : ""}${skillsSection}
${memoryContextSection ? `---

${memoryContextSection}

` : ""}---

## Action

${action}

---

${completionWorkflow}

---

## Verification

- Run in worktree: \`pnpm gates\`
- From shared checkout: \`node packages/@lumenflow/agent/dist/agent-verification.js ${id}\`

---

${mandatorySection}${implementationContext ? `${implementationContext}

---

` : ""}${clientBlocks ? `${clientBlocks}

---

` : ""}${thinkingBlock}${bugDiscoverySection}

---

${laneGuidance}${laneGuidance ? "\n\n---\n\n" : ""}${selfReviewDirective}

---

${worktreeBlockRecovery}

---

${constraints}

${SPAWN_END_SENTINEL}
`;
}

// src/wu-brief-sizing.ts
function checkBriefSizing(input) {
  const { wuId, logPrefix, strictSizing, sizingEstimate } = input;
  const warnings = [];
  const errors = [];
  if (!sizingEstimate) {
    if (strictSizing) {
      errors.push(
        `${wuId}: --strict-sizing requires sizing_estimate metadata in WU YAML. Add sizing_estimate with estimated_files, estimated_tool_calls, and strategy.`
      );
      return { pass: false, warnings, errors };
    }
    return { pass: true, warnings, errors };
  }
  const advisory = checkSizingAdvisory(sizingEstimate);
  if (advisory.oversize) {
    if (strictSizing) {
      errors.push(...advisory.warnings.map((w) => `${wuId}: ${w}`));
      return { pass: false, warnings, errors };
    }
    for (const w of advisory.warnings) {
      const message = `${logPrefix} WARNING (${wuId}): ${w}`;
      warnings.push(message);
      console.warn(message);
    }
    return { pass: true, warnings, errors };
  }
  return { pass: true, warnings, errors };
}

// src/wu-spawn-strategy-resolver.ts
import crypto from "crypto";
var BRIEF_LOG_PREFIX = "[wu:brief]";
var DELEGATE_LOG_PREFIX = "[wu:delegate]";
var BRIEF_EVIDENCE_PROGRESS = "wu:brief executed";
function buildBriefAttestation(output, clientName, generatedAt = (/* @__PURE__ */ new Date()).toISOString()) {
  return {
    algorithm: "sha256",
    promptHash: crypto.createHash("sha256").update(output, "utf8").digest("hex"),
    promptLength: output.length,
    generatedAt,
    clientName
  };
}
function checkLaneOccupation(lane) {
  const lockPolicy = getLockPolicyForLane(lane);
  if (lockPolicy === "none") {
    return null;
  }
  const lockStatus = checkLaneLock(lane);
  if (lockStatus.locked && lockStatus.metadata) {
    return lockStatus.metadata;
  }
  return null;
}
function generateLaneOccupationWarning(lockMetadata, targetWuId, options = {}) {
  const { isStale = false } = options;
  let warning = `\u26A0\uFE0F  Lane "${lockMetadata.lane}" is occupied by ${lockMetadata.wuId}
`;
  const lockPolicy = options.lockPolicy ?? getLockPolicyForLane(lockMetadata.lane);
  const wipLimit = options.wipLimit ?? getWipLimitForLane(lockMetadata.lane);
  warning += `   This violates WIP=${wipLimit} (lock_policy=${lockPolicy}).

`;
  if (isStale) {
    warning += `   \u23F0 This lock is STALE (>24 hours old) - the WU may be abandoned.
`;
    warning += `   Consider using pnpm wu:block --id ${lockMetadata.wuId} if work is stalled.

`;
  }
  warning += `   Options:
`;
  warning += `   1. Wait for ${lockMetadata.wuId} to complete or block
`;
  warning += `   2. Choose a different lane for ${targetWuId}
`;
  warning += `   3. Block ${lockMetadata.wuId} if work is stalled: pnpm wu:block --id ${lockMetadata.wuId}`;
  return warning;
}
var BRIEF_PARSER_CONFIG = {
  name: "wu-brief",
  description: "Generate handoff prompt for sub-agent WU execution"
};
var DELEGATE_PARSER_CONFIG = {
  name: "wu-delegate",
  description: "Generate delegation prompt and record explicit lineage intent"
};
function parseAndValidateArgs(parserConfig = BRIEF_PARSER_CONFIG) {
  const args = createWUParser({
    name: parserConfig.name,
    description: parserConfig.description,
    options: [
      WU_OPTIONS.id,
      WU_OPTIONS.thinking,
      WU_OPTIONS.noThinking,
      WU_OPTIONS.budget,
      WU_OPTIONS.codex,
      WU_OPTIONS.parentWu,
      // WU-1945: Parent WU for spawn registry tracking
      WU_OPTIONS.client,
      WU_OPTIONS.vendor,
      WU_OPTIONS.noContext,
      // WU-1240: Skip memory context injection
      WU_OPTIONS.evidenceOnly,
      // WU-2222: Evidence recording without prompt generation
      WU_OPTIONS.strictSizing
      // WU-2141: Strict sizing enforcement
    ],
    required: ["id"],
    allowPositionalId: true
  });
  try {
    validateSpawnArgs(args);
  } catch (e) {
    die(e.message);
  }
  return args;
}
function loadWUDocument(id, wuPath) {
  if (!existsSync3(wuPath)) {
    die(
      `WU file not found: ${wuPath}

Cannot spawn a sub-agent for a WU that doesn't exist.

Options:
  1. Create the WU first: pnpm wu:create --id ${id} --lane <lane> --title "..."
  2. Check if the WU ID is correct`
    );
  }
  let text;
  try {
    text = readFileSync(wuPath, { encoding: FILE_SYSTEM.UTF8 });
  } catch (e) {
    die(
      `Failed to read WU file: ${wuPath}

Error: ${e.message}

Options:
  1. Check file permissions: ls -la ${wuPath}
  2. Ensure the file exists and is readable`
    );
  }
  try {
    return parseYAML(text);
  } catch (e) {
    die(
      `Failed to parse WU YAML ${wuPath}

Error: ${e.message}

Options:
  1. Validate YAML syntax: pnpm wu:validate --id ${id}
  2. Fix YAML errors manually and retry`
    );
  }
}
function resolveClientName(args, config, logPrefix = BRIEF_LOG_PREFIX) {
  let clientName = args.client;
  if (!clientName && args.vendor) {
    console.warn(`${logPrefix} ${EMOJI.WARNING} Warning: --vendor is deprecated. Use --client.`);
    clientName = args.vendor;
  }
  if (args.codex && !clientName) {
    console.warn(
      `${logPrefix} ${EMOJI.WARNING} Warning: --codex is deprecated. Use --client codex-cli.`
    );
    clientName = "codex-cli";
  }
  const resolved = clientName || config.agents.defaultClient || "claude-code";
  if (!clientName && !config.agents.defaultClient) {
    console.warn(
      `${logPrefix} Warning: No --client specified. Falling back to 'claude-code'. Available clients: claude-code, codex-cli, cursor, gemini-cli, windsurf`
    );
  }
  return resolved;
}
async function checkAndWarnLaneOccupation(lane, id, logPrefix = BRIEF_LOG_PREFIX) {
  if (!lane) return;
  const existingLock = checkLaneOccupation(lane);
  if (existingLock && existingLock.wuId !== id) {
    const { isLockStale } = await import("./lane-lock-6J36HD5O.js");
    const isStale = isLockStale(existingLock);
    const warning = generateLaneOccupationWarning(existingLock, id, { isStale });
    console.warn(`${logPrefix} ${EMOJI.WARNING}
${warning}
`);
  }
}
async function recordWuBriefEvidence(options, dependencies = {}) {
  const { wuId, workspaceRoot, clientName, promptHash, forceRecord, claimedMode, claimedBranch } = options;
  const checkWorktree = dependencies.isInWorktree ?? isInWorktree;
  const isInWorktree2 = checkWorktree({ cwd: workspaceRoot });
  let shouldRecordEvidence = forceRecord === true || isInWorktree2;
  if (!shouldRecordEvidence) {
    const normalizedClaimedMode = typeof claimedMode === "string" ? claimedMode.trim() : "";
    const isBranchClaim = normalizedClaimedMode === "branch-pr" || normalizedClaimedMode === "branch-only";
    if (isBranchClaim) {
      const getCurrentBranch = dependencies.getCurrentBranch ?? (async (cwd) => {
        return createGitForPath(cwd).getCurrentBranch();
      });
      const activeBranch = await getCurrentBranch(workspaceRoot).then((branch) => branch.trim()).catch(() => "");
      const normalizedClaimedBranch = typeof claimedBranch === "string" ? claimedBranch.trim() : "";
      if (normalizedClaimedBranch.length > 0) {
        shouldRecordEvidence = activeBranch === normalizedClaimedBranch;
      } else {
        shouldRecordEvidence = activeBranch.length > 0 && activeBranch !== BRANCHES.MAIN && activeBranch !== BRANCHES.MASTER;
      }
    }
  }
  if (!shouldRecordEvidence) {
    return;
  }
  const stateDir = resolveStateDir(workspaceRoot);
  const createStore = dependencies.createStore ?? ((dir) => new WUStateStore(dir));
  const store = createStore(stateDir);
  const note = `${WU_BRIEF_EVIDENCE_NOTE_PREFIX} generated via ${clientName}`;
  const nextSteps = promptHash ? `client=${clientName};hash=${promptHash}` : `client=${clientName}`;
  await store.checkpoint(wuId, note, {
    progress: BRIEF_EVIDENCE_PROGRESS,
    nextSteps
  });
}
async function emitSpawnOutputWithRegistry(options, dependencies = {}) {
  const {
    id,
    output,
    isCodexClient,
    parentWu,
    lane,
    briefAttestation,
    recordDelegationIntent = false,
    logPrefix: prefix = BRIEF_LOG_PREFIX
  } = options;
  const log = dependencies.log ?? console.log;
  const recordSpawn = dependencies.recordSpawn ?? recordSpawnToRegistry;
  const formatSpawnMessage = dependencies.formatSpawnMessage ?? formatSpawnRecordedMessage;
  if (isCodexClient) {
    log(`${prefix} Generated Codex/GPT prompt for ${id}`);
    log(`${prefix} Copy the Markdown below:
`);
    log(output.trimEnd());
  } else {
    log(`${prefix} Generated Task tool invocation for ${id}`);
    log(`${prefix} Copy the block below to spawn a sub-agent:
`);
    log(output);
  }
  if (!recordDelegationIntent || !parentWu) {
    return;
  }
  const config = getConfig({ projectRoot: process.cwd() });
  const registryResult = await recordSpawn({
    parentWuId: parentWu,
    targetWuId: id,
    lane: lane || "Unknown",
    baseDir: config.state.stateDir,
    briefAttestation
  });
  const registryMessage = formatSpawnMessage(registryResult.spawnId, registryResult.error);
  log(`
${registryMessage}`);
}
async function runBriefLogic(options = {}) {
  const {
    mode = "brief",
    parserConfig = mode === "delegate" ? DELEGATE_PARSER_CONFIG : BRIEF_PARSER_CONFIG,
    logPrefix = BRIEF_LOG_PREFIX
  } = options;
  const args = parseAndValidateArgs(parserConfig);
  const explicitDelegation = mode === "delegate";
  const effectiveLogPrefix = explicitDelegation ? DELEGATE_LOG_PREFIX : logPrefix;
  const commandLabel = explicitDelegation ? "wu:delegate" : "wu:brief";
  const depResult = await validateSpawnDependencies();
  if (!depResult.valid) {
    die(formatDependencyError(commandLabel, depResult.missing));
  }
  if (explicitDelegation && !args.parentWu) {
    die(
      "wu:delegate requires --parent-wu to record delegation lineage intent.\n\nExample:\n  pnpm wu:delegate --id WU-123 --parent-wu WU-100 --client <client>"
    );
  }
  if (explicitDelegation && args.evidenceOnly) {
    die(
      "wu:delegate does not support --evidence-only.\n\nUse:\n  - pnpm wu:delegate --id WU-123 --parent-wu WU-100 --client <client>  # delegation prompt + lineage\n  - pnpm wu:brief --id WU-123 --evidence-only                           # self-implementation evidence only"
    );
  }
  if (!explicitDelegation && args.parentWu) {
    console.warn(
      `${effectiveLogPrefix} ${EMOJI.WARNING} --parent-wu does not record lineage in generation-only mode.`
    );
    console.warn(
      `${effectiveLogPrefix} ${EMOJI.WARNING} Use wu:delegate for explicit, side-effectful delegation intent tracking.`
    );
    console.warn("");
  }
  const id = args.id.toUpperCase();
  if (!PATTERNS.WU_ID.test(id)) {
    die(`Invalid WU id '${args.id}'. Expected format WU-123`);
  }
  const wuPath = WU_PATHS.WU(id);
  const doc = loadWUDocument(id, wuPath);
  const validStatuses = [WU_STATUS.READY, WU_STATUS.IN_PROGRESS];
  const status = doc.status || "unknown";
  if (!validStatuses.includes(status)) {
    console.warn(`${effectiveLogPrefix} ${EMOJI.WARNING} Warning: ${id} has status '${status}'.`);
    console.warn(
      `${effectiveLogPrefix} ${EMOJI.WARNING} Sub-agents typically work on ready or in_progress WUs.`
    );
    console.warn("");
  }
  await checkAndWarnLaneOccupation(doc.lane, id, effectiveLogPrefix);
  const sizingEstimate = doc.sizing_estimate;
  const sizingResult = checkBriefSizing({
    wuId: id,
    logPrefix: effectiveLogPrefix,
    strictSizing: Boolean(args.strictSizing),
    sizingEstimate
  });
  if (!sizingResult.pass) {
    const errorList = sizingResult.errors.map((e) => `  - ${e}`).join("\n");
    die(
      `${effectiveLogPrefix} Sizing check failed (--strict-sizing):

${errorList}

Options:
  1. Add sizing_estimate metadata to WU YAML
  2. Add exception_type and exception_reason if thresholds are intentionally exceeded
  3. Remove --strict-sizing to use advisory mode`
    );
  }
  const thinkingOptions = {
    thinking: args.thinking,
    noThinking: args.noThinking,
    budget: args.budget
  };
  const config = getConfig();
  const clientName = resolveClientName(args, config, effectiveLogPrefix);
  const baseDir = process.cwd();
  const recordEvidenceOrFail = async (options2 = {}) => {
    try {
      await recordWuBriefEvidence({
        wuId: id,
        workspaceRoot: baseDir,
        clientName,
        promptHash: options2.promptHash,
        forceRecord: options2.forceRecord,
        claimedMode: typeof doc.claimed_mode === "string" ? doc.claimed_mode : void 0,
        claimedBranch: typeof doc.claimed_branch === "string" ? doc.claimed_branch : void 0
      });
    } catch (error) {
      die(
        `${effectiveLogPrefix} Failed to record wu:brief evidence for ${id}: ${error.message}

Fix options:
  1. Ensure state directory is writable
  2. Retry: pnpm wu:brief --id ${id}`
      );
    }
  };
  if (args.evidenceOnly) {
    await recordEvidenceOrFail();
    console.log(
      `${effectiveLogPrefix} Recorded wu:brief evidence for ${id} (evidence-only mode; no handoff prompt generated).`
    );
    console.log(`${effectiveLogPrefix} Continue implementing ${id} in the current session.`);
    return;
  }
  let memoryContextContent = "";
  const shouldIncludeMemoryContext = !args.noContext;
  if (shouldIncludeMemoryContext) {
    const isMemoryInitialized = await checkMemoryLayerInitialized(baseDir);
    if (isMemoryInitialized) {
      const maxSize = getMemoryContextMaxSize(config);
      memoryContextContent = await generateMemoryContextSection(baseDir, {
        wuId: id,
        lane: doc.lane,
        maxSize
      });
      if (memoryContextContent) {
        console.log(
          `${effectiveLogPrefix} Memory context loaded (${memoryContextContent.length} bytes)`
        );
      }
    }
  }
  const strategy = SpawnStrategyFactory.create(clientName);
  const clientContext = { name: clientName, config: resolveClientConfig(config, clientName) };
  const isCodexClient = clientName === "codex-cli" || args.codex;
  if (isCodexClient) {
    const prompt = generateCodexPrompt(doc, id, strategy, {
      ...thinkingOptions,
      client: clientContext,
      config
    });
    const briefAttestation2 = explicitDelegation ? buildBriefAttestation(prompt, clientName) : void 0;
    await emitSpawnOutputWithRegistry({
      id,
      output: prompt,
      isCodexClient: true,
      parentWu: args.parentWu,
      lane: doc.lane,
      briefAttestation: briefAttestation2,
      recordDelegationIntent: explicitDelegation,
      logPrefix: effectiveLogPrefix
    });
    await recordEvidenceOrFail({
      promptHash: briefAttestation2?.promptHash,
      forceRecord: explicitDelegation
    });
    return;
  }
  const invocation = generateTaskInvocation(doc, id, strategy, {
    ...thinkingOptions,
    client: clientContext,
    config,
    // WU-1240: Include memory context in spawn prompt
    baseDir,
    includeMemoryContext: shouldIncludeMemoryContext && memoryContextContent.length > 0,
    memoryContextContent,
    noContext: args.noContext
  });
  const briefAttestation = explicitDelegation ? buildBriefAttestation(invocation, clientName) : void 0;
  await emitSpawnOutputWithRegistry({
    id,
    output: invocation,
    isCodexClient: false,
    parentWu: args.parentWu,
    lane: doc.lane,
    briefAttestation,
    recordDelegationIntent: explicitDelegation,
    logPrefix: effectiveLogPrefix
  });
  await recordEvidenceOrFail({
    promptHash: briefAttestation?.promptHash,
    forceRecord: explicitDelegation
  });
}

export {
  recordWuBriefEvidence,
  runBriefLogic
};
