export const repairPlaybook = {
  principle: "Repair operational failures automatically; produce code patch plans for source changes unless a bounded, reversible executor is explicitly added.",
  codingTools: [
    {
      id: "syntax_check",
      command: "npm run check",
      useFor: "JavaScript syntax errors, import/export mistakes, malformed files",
      safeToRunAutomatically: true
    },
    {
      id: "agentic_eval",
      command: "npm test",
      useFor: "Hermes agent behavior regressions and repair validation",
      safeToRunAutomatically: true
    },
    {
      id: "scale_audit",
      command: "npm run audit:scale",
      useFor: "Run-output quality, owner-agent yield, timeout and fallback counters",
      safeToRunAutomatically: true
    },
    {
      id: "tool_bootstrap",
      command: "bash scripts/bootstrap_tools.sh",
      useFor: "Missing scraper, enrichment, LinkedIn, owner-profile, or optional OSINT owner-evidence tools",
      safeToRunAutomatically: true
    },
    {
      id: "owner_evidence_toolkit_probe",
      command: "node --input-type=module -e \"const {OwnerEvidenceToolsAdapter}=await import('./src/adapters/ownerEvidenceTools.js'); const t=new OwnerEvidenceToolsAdapter({rootDir:process.cwd()}); console.log(JSON.stringify(t.available(), null, 2));\"",
      useFor: "Check optional theHarvester, Photon, Maigret, Sherlock, Social Analyzer, and Reacher installation state",
      safeToRunAutomatically: true
    },
    {
      id: "node_probe",
      command: "node --input-type=module -e '<bounded probe>'",
      useFor: "Small API/client probes such as MiniMax JSON behavior or adapter availability",
      safeToRunAutomatically: true
    },
    {
      id: "dashboard_syntax_check",
      command: "node --check public/app.js",
      useFor: "Dashboard JavaScript parse failures, broken tabs, and loading errors",
      safeToRunAutomatically: true
    },
    {
      id: "health_probe",
      command: "curl -sS http://localhost:8787/api/health",
      useFor: "Server readiness, active worker count, provider status, and scraper tool availability",
      safeToRunAutomatically: true
    },
    {
      id: "repair_playbook_probe",
      command: "curl -sS http://localhost:8787/api/repair-playbook",
      useFor: "Verify the dashboard and Hermes can see the current repair training kit",
      safeToRunAutomatically: true
    },
    {
      id: "dependency_inventory",
      command: "npm ls --depth=0",
      useFor: "Broken or missing Node dependencies before deeper patch work",
      safeToRunAutomatically: true
    },
    {
      id: "run_state_audit",
      command: "curl -sS http://localhost:8787/api/runs/<runId>",
      useFor: "Inspect current run status, counters, FlowWatchdog repairs, pending owner backlog, and terminal reason",
      safeToRunAutomatically: true
    },
    {
      id: "portfolio_defaults_probe",
      command: "curl -sS http://localhost:8787/api/portfolio-defaults",
      useFor: "Verify no-input Hermes portfolio defaults still target Google Maps seed discovery plus owner-contact rabbit-hole research",
      safeToRunAutomatically: true
    },
    {
      id: "workflow_probe",
      command: "curl -sS http://localhost:8787/api/workflow",
      useFor: "Verify the visible Hermes workflow arrows and self-evolving loop are available to the dashboard",
      safeToRunAutomatically: true
    },
    {
      id: "server_import_probe",
      command: "node --input-type=module -e \"await import('./server.js')\"",
      useFor: "Server import/startup failures after route, adapter, or playbook edits",
      safeToRunAutomatically: false
    },
    {
      id: "playbook_consistency_probe",
      command: "node --input-type=module -e \"const {repairPlaybook}=await import('./src/repairPlaybook.js'); const ids=new Set(repairPlaybook.codingTools.map(t=>t.id)); for (const id of repairPlaybook.executionPolicy.autoRunnableTools) if (!ids.has(id)) throw new Error('unknown auto tool '+id);\"",
      useFor: "Verify every auto-runnable repair tool is defined before MiniMax can choose it",
      safeToRunAutomatically: true
    },
    {
      id: "provider_module_probe",
      command: "node --input-type=module -e \"await import('./src/minimax.js')\"",
      useFor: "MiniMax client import, syntax, and module-shape failures before deeper provider debugging",
      safeToRunAutomatically: true
    },
    {
      id: "export_module_probe",
      command: "node --input-type=module -e \"const m=await import('./src/export.js'); if (typeof m.leadsCsv !== 'function') throw new Error('missing leadsCsv');\"",
      useFor: "CSV/export mapping failures before patching final delivery fields",
      safeToRunAutomatically: true
    },
    {
      id: "env_config_probe",
      command: "node --input-type=module -e \"const required=['MINIMAX_API_KEY']; console.log(required.map(k=>`${k}=${process.env[k]?'set':'missing'}`).join('\\n'))\"",
      useFor: "Provider configuration and environment drift without printing secret values",
      safeToRunAutomatically: true
    },
    {
      id: "recent_log_probe",
      command: "tail -n 120 logs/*.log",
      useFor: "Recent server, scraper, timeout, and provider stack traces when a run stalls",
      safeToRunAutomatically: true
    },
    {
      id: "owner_evidence_audit",
      command: "node scripts/scale_run_audit.js --min-owner-agents 1",
      useFor: "Owner-agent deployment, owner-contact evidence, exhausted leads, timeout counters, and portfolio stop reason",
      safeToRunAutomatically: true
    },
    {
      id: "code_patch_plan",
      command: "generate_patch_plan",
      useFor: "Source-code fixes that need a diff, review, restart, and rollback point",
      safeToRunAutomatically: false
    }
  ],
  skills: [
    {
      id: "provider_reliability",
      trigger: "MiniMax timeout, 429, 5xx, non-JSON, malformed tool output",
      repair: "Run a bounded provider probe, retry with backoff, parse provider wrappers, use deterministic fallback, keep provider telemetry, avoid opening circuit on one transient failure."
    },
    {
      id: "checkpoint_recovery",
      trigger: "queued/running/interrupted run with no active worker",
      repair: "Mark checkpoint, ask FlowWatchdog for repair action, run preflight/tool repair, resume from saved state."
    },
    {
      id: "toolchain_repair",
      trigger: "missing dependency, missing scraper, missing Python environment, missing vendor tool",
      repair: "Run bootstrap_tools, recheck availability, record repair evidence, resume only if required tools are present."
    },
    {
      id: "skill_tool_safety_gate",
      trigger: "new external skill or GitHub tool is proposed for Hermes",
      repair: "Run a source and permission review first, reject tools that read credentials or use unsafe network/system behavior, then install only behind a bounded adapter."
    },
    {
      id: "owner_yield_repair",
      trigger: "owner rabbit-hole attempts are high but owner contacts are zero or low",
      repair: "Broaden owner identity routes: registries, registered agents, articles, exact business/city social profiles, then owner-level contact search."
    },
    {
      id: "search_stagnation_repair",
      trigger: "duplicate queries, no qualified leads, exhausted city, repeated low-score results",
      repair: "Change one search variable at a time: niche synonym, location split, directory query, official-site query, or nearby USA market."
    },
    {
      id: "evidence_gate_repair",
      trigger: "business contact is being mistaken for owner contact",
      repair: "Reject business-only contact; require owner name plus owner email or owner phone with owner-level evidence."
    },
    {
      id: "dashboard_repair",
      trigger: "dashboard loads blank, buttons disabled, defaults missing, run keeps working after loading",
      repair: "Run dashboard_syntax_check and health_probe, verify activeRuns, then patch only the affected UI binding or lifecycle handler."
    },
    {
      id: "export_repair",
      trigger: "CSV/report misses owner contact fields, business details, exhaustion reason, or repair evidence",
      repair: "Patch export mapping and add regression coverage so final CSV preserves business seed data plus owner-level contact evidence."
    },
    {
      id: "process_lifecycle_repair",
      trigger: "dashboard is open but work never stops, no worker is active, or a stale worker writes after terminal status",
      repair: "Audit run state and active worker count, preserve terminal statuses, resume only from explicit recoverable checkpoints, and prevent stale persist from resurrecting killed/cancelled runs."
    },
    {
      id: "playbook_drift_repair",
      trigger: "FlowWatchdog recommends missing tools, unknown patch templates, or commands not listed in the repair playbook",
      repair: "Run playbook_consistency_probe, reject unknown ids, and force MiniMax to choose only allowed repair variables, tools, runbooks, and patch templates."
    },
    {
      id: "log_triage_repair",
      trigger: "failure reason is unclear, repeated stack traces appear, or provider/tool errors are hidden behind generic timeout text",
      repair: "Run recent_log_probe, classify the first concrete error, choose one matching runbook, and avoid changing search strategy until infrastructure errors are ruled out."
    }
  ],
  plugins: [
    {
      id: "flow_watchdog",
      useFor: "Detect stalls/failures during a live run and ask MiniMax for one repair action.",
      permissions: ["read run state", "record repair decision", "recommend one bounded action"]
    },
    {
      id: "codexsaver_minimax_worker",
      useFor: "Low-risk code search, docs, tests, boilerplate, and bounded patch drafts.",
      permissions: ["read scoped files", "propose patch", "run allowlisted checks"]
    },
    {
      id: "tool_bootstrapper",
      useFor: "Install or refresh scraper/profile support tools with scripts/bootstrap_tools.sh.",
      permissions: ["run bootstrap script", "recheck availability"]
    },
    {
      id: "owner_profile_toolkit",
      useFor: "Search public owner profiles and owner-level contact evidence using built-in search, LinkedIn helpers, and optional OSINT owner-evidence tools.",
      permissions: ["public-web search", "profile/contact extraction", "evidence scoring"]
    },
    {
      id: "owner_evidence_toolkit",
      useFor: "Normalize optional theHarvester, Photon, Maigret, Sherlock, Social Analyzer, and Reacher evidence into Hermes lead records.",
      permissions: ["read public webpages", "run isolated vendor tools", "record source-backed evidence"]
    },
    {
      id: "scale_auditor",
      useFor: "Audit full-run output quality, owner yield, timeout counters, and partial completion causes.",
      permissions: ["read run artifacts", "produce audit findings"]
    },
    {
      id: "playbook_consistency_guard",
      useFor: "Validate that every FlowWatchdog tool/runbook/patch id exists before MiniMax can use it.",
      permissions: ["read repair playbook", "read execution policy", "emit validation warning"]
    },
    {
      id: "runtime_state_auditor",
      useFor: "Compare API health, run state, active worker count, counters, and stale terminal writes.",
      permissions: ["read health endpoint", "read run endpoint", "recommend lifecycle repair"]
    },
    {
      id: "export_integrity_guard",
      useFor: "Check that final CSV/report keeps business seed data, owner evidence, exhaustion status, and repair evidence.",
      permissions: ["read run artifacts", "read export mapping", "recommend export patch"]
    }
  ],
  diagnosticRunbooks: [
    {
      id: "provider_timeout_drill",
      trigger: "MiniMax timeout, malformed JSON, or provider parse error",
      steps: [
        "Record provider metadata and failure text without stopping the whole run.",
        "Run node_probe against a tiny JSON-only MiniMax request when credentials are configured.",
        "Use deterministic fallback for the current strategy decision.",
        "If repeated failures cross the retry threshold, produce a code_patch_plan for src/minimax.js and validate with npm test."
      ]
    },
    {
      id: "dashboard_not_working_drill",
      trigger: "Dashboard blank, stuck loading, or controls not wired",
      steps: [
        "Run dashboard_syntax_check.",
        "Run health_probe and confirm activeRuns is expected.",
        "Verify /api/portfolio-defaults and /api/repair-playbook load.",
        "Patch only the failing selector, renderer, or lifecycle handler, then re-run the syntax and health checks."
      ]
    },
    {
      id: "owner_yield_zero_drill",
      trigger: "Owner rabbit-hole attempts grow but owner contacts remain zero",
      steps: [
        "Keep Google Maps discovery running and drain the owner backlog concurrently.",
        "Broaden one owner identity route at a time: LinkedIn, local press, registries, leadership pages, social profiles.",
        "Reject business-only phone/email as final contact.",
        "Mark exhausted with evidence when owner contact is not provable, then continue to the next business."
      ]
    },
    {
      id: "checkpoint_no_worker_drill",
      trigger: "Run interrupted while no worker is active",
      steps: [
        "Ask FlowWatchdog for repair action.",
        "Run preflight and repair missing tools if needed.",
        "Resume from saved checkpoint instead of restarting from zero.",
        "Record selfHealing and repair evidence on the run."
      ]
    },
    {
      id: "playbook_consistency_drill",
      trigger: "MiniMax suggests an unknown tool, unknown patch template, arbitrary shell command, or unsafe action",
      steps: [
        "Run playbook_consistency_probe.",
        "Normalize the repair through allowedRepairVariables, codingTools, diagnosticRunbooks, and patchTemplates.",
        "Reject unknown commands and fall back to the closest safe tool.",
        "Record the rejected suggestion and the safe replacement in run.agentDecisions."
      ]
    },
    {
      id: "run_lifecycle_drill",
      trigger: "Dashboard loads while a run keeps working unexpectedly, or status says interrupted while no worker is active",
      steps: [
        "Run health_probe and run_state_audit for the affected run.",
        "Compare status, activeRuns, updatedAt, counters, and last steps.",
        "If no worker is active and status is recoverable, use checkpoint_no_worker_drill.",
        "If status is terminal, preserve it and do not let stale workers persist over it."
      ]
    },
    {
      id: "export_integrity_drill",
      trigger: "Delivery output is missing owner contact, owner evidence, business details, exhausted status, or repair history",
      steps: [
        "Run export_module_probe.",
        "Run owner_evidence_audit against the target run.",
        "Compare CSV/report headers with business seed fields and owner-level evidence fields.",
        "Produce an export_field_patch plan if any required field is missing."
      ]
    },
    {
      id: "log_triage_drill",
      trigger: "The failure is vague, repeated, or hidden behind a timeout message",
      steps: [
        "Run recent_log_probe.",
        "Classify the first concrete error as provider, scraper, dashboard, export, lifecycle, or evidence gate.",
        "Choose exactly one matching patch template.",
        "Validate with the narrowest check first, then npm test if source code changed."
      ]
    }
  ],
  patchTemplates: [
    {
      id: "provider_timeout_patch",
      symptom: "MiniMax timeout, malformed JSON, provider parse failure",
      files: ["src/minimax.js", "src/flowWatchdog.js", "scripts/agentic_eval.js"],
      recipe: "Add timeout/retry telemetry, parse wrapped JSON conservatively, fall back deterministically, and test malformed provider responses.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "dashboard_binding_patch",
      symptom: "Dashboard loads but controls/defaults/repairs do not render",
      files: ["public/index.html", "public/app.js"],
      recipe: "Find the missing selector or event binding, add a static safe default where possible, and keep API-loaded defaults as enhancement.",
      validation: ["node --check public/app.js", "curl -sS http://localhost:8787/api/health"]
    },
    {
      id: "owner_contact_gate_patch",
      symptom: "Business contact is accepted as owner contact",
      files: ["src/adapters/ownerRabbitHole.js", "src/minimax.js", "src/hermes.js", "scripts/agentic_eval.js"],
      recipe: "Separate business seed contact from owner-level contact, require owner identity evidence, and add a regression that rejects business-only contact.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "resume_worker_patch",
      symptom: "Saved checkpoint exists but no worker resumes",
      files: ["src/hermes.js", "server.js", "scripts/agentic_eval.js"],
      recipe: "Detect terminal/no-worker state, ask FlowWatchdog for repair, preflight tools, resume checkpoint, and prevent stale workers from resurrecting terminal runs.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "portfolio_continuation_patch",
      symptom: "Run stops partial while more locations/businesses can still be searched",
      files: ["src/hermes.js", "server.js", "scripts/agentic_eval.js"],
      recipe: "Continue location expansion and backlog draining until the target is reached or maxPlannedLocations is exhausted.",
      validation: ["npm run check", "npm test", "npm run audit:scale"]
    },
    {
      id: "playbook_consistency_patch",
      symptom: "FlowWatchdog or MiniMax recommends unknown repair ids, arbitrary shell, or unsafe automatic actions",
      files: ["src/repairPlaybook.js", "src/flowWatchdog.js", "scripts/agentic_eval.js"],
      recipe: "Add allowlist validation for tools/runbooks/templates, reject unknown ids, preserve forbiddenAutomaticActions, and test that compactRepairPlaybook exposes only approved repair choices.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "lifecycle_stale_worker_patch",
      symptom: "Dashboard loading, cancelling, killing, or interruption leaves stale workers writing over terminal run state",
      files: ["src/hermes.js", "server.js", "scripts/agentic_eval.js"],
      recipe: "Guard persist against stale terminal writes, require explicit recoverable statuses for resume, and test cancelled/killed/interrupted checkpoint behavior.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "export_field_patch",
      symptom: "Final CSV/report drops business seed data, owner contact evidence, exhaustion status, or repair history",
      files: ["src/export.js", "scripts/agentic_eval.js"],
      recipe: "Map ownerContactEvidence, owner social/profile URLs, rabbitHoleStatus, exhausted reason, and latest repair decision into delivery outputs with regression coverage.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "tool_preflight_patch",
      symptom: "Run starts even though Google Maps scraper, Scrapling enrichment, owner profile tools, or MiniMax configuration are unavailable",
      files: ["src/hermes.js", "server.js", "scripts/agentic_eval.js"],
      recipe: "Add preflight checks before discovery, classify missing tools as repairable, run bootstrap where safe, and only continue when required tools are available or a deterministic fallback exists.",
      validation: ["npm run check", "npm test"]
    },
    {
      id: "log_classification_patch",
      symptom: "Failures are recorded as generic timeout or failed without actionable class",
      files: ["src/hermes.js", "src/flowWatchdog.js", "scripts/agentic_eval.js"],
      recipe: "Classify errors into provider, scraper, dashboard, export, lifecycle, evidence gate, or unknown, then route each class to one repair runbook.",
      validation: ["npm run check", "npm test"]
    }
  ],
  executionPolicy: {
    autoRunnableTools: [
      "syntax_check",
      "agentic_eval",
      "scale_audit",
      "tool_bootstrap",
      "node_probe",
      "dashboard_syntax_check",
      "health_probe",
      "repair_playbook_probe",
      "dependency_inventory",
      "run_state_audit",
      "portfolio_defaults_probe",
      "workflow_probe",
      "playbook_consistency_probe",
      "provider_module_probe",
      "export_module_probe",
      "env_config_probe",
      "recent_log_probe",
      "owner_evidence_audit"
    ],
    reviewRequiredTools: ["code_patch_plan", "server_import_probe"],
    forbiddenAutomaticActions: [
      "git reset --hard",
      "delete data",
      "send outreach",
      "weaken owner-contact qualification",
      "invent owner evidence",
      "deploy production changes"
    ]
  },
  patchIdeas: [
    {
      symptom: "MiniMax timeout or non-JSON failure",
      files: ["src/minimax.js", "src/hermes.js"],
      idea: "Increase timeout, retry retryable failures, strip provider reasoning wrappers, parse balanced JSON objects, track consecutive failures only."
    },
    {
      symptom: "Dashboard loads but run has no worker",
      files: ["src/hermes.js", "server.js"],
      idea: "Add checkpoint self-heal path: detect interrupted status, request repair advice, run preflight/tool repair, resume saved run."
    },
    {
      symptom: "Tools missing or scraper fails before discovery",
      files: ["src/hermes.js", "scripts/bootstrap_tools.sh"],
      idea: "Classify missing tool as repairable, run bootstrap, recheck tool availability, keep run state instead of failing the whole workflow."
    },
    {
      symptom: "Owner agents find business contact but not owner contact",
      files: ["src/adapters/ownerRabbitHole.js", "src/hermes.js"],
      idea: "Strengthen owner-contact proof gate, add owner identity search routes, and promote contacts only when tied to owner evidence."
    },
    {
      symptom: "Google Maps discovery stalls or repeats",
      files: ["src/hermes.js", "src/minimax.js"],
      idea: "Use MiniMax strategy to generate non-duplicate USA-only queries, then fall back to deterministic query families."
    },
    {
      symptom: "Run completes partial with low owner yield",
      files: ["src/flowWatchdog.js", "src/export.js"],
      idea: "Have FlowWatchdog record the yield failure, propose one repair variable, and include repair evidence in reports."
    },
    {
      symptom: "FlowWatchdog recommends an unknown tool, arbitrary shell, or missing patch template",
      files: ["src/repairPlaybook.js", "src/flowWatchdog.js"],
      idea: "Validate all repair ids against the playbook allowlists, reject unknown commands, and fall back to the closest safe drill."
    },
    {
      symptom: "Dashboard says loading but the agent keeps running or no worker owns the run",
      files: ["src/hermes.js", "server.js", "public/app.js"],
      idea: "Separate UI loading from worker lifecycle, expose activeRuns/run status clearly, preserve terminal statuses, and resume only explicit recoverable checkpoints."
    },
    {
      symptom: "Final CSV misses owner evidence or repair history after self-healing",
      files: ["src/export.js", "scripts/agentic_eval.js"],
      idea: "Add ownerContactEvidence, owner profile URL, rabbitHoleStatus, exhaustion reason, and latest repair decision to delivery exports with regression coverage."
    },
    {
      symptom: "Error is vague and the agent changes search strategy instead of fixing infrastructure",
      files: ["src/hermes.js", "src/flowWatchdog.js"],
      idea: "Classify failures from recent logs first, then choose one provider/scraper/dashboard/export/lifecycle/evidence-gate runbook before touching search strategy."
    }
  ],
  guardrails: [
    "Never weaken the final owner-contact requirement.",
    "Never fabricate owner names, emails, phone numbers, or social profiles.",
    "Never run destructive git, filesystem, database, payment, email-send, or deploy actions automatically.",
    "Runtime source-code editing requires a bounded patch executor with diff review and rollback; until then, produce patch plans only.",
    "Every repair must be recorded in run.agentDecisions or run.flowWatchdog.repairs.",
    "Never promote patchTemplates to auto-runnable actions; they are instructions for code_patch_plan and review.",
    "Never print secret values while probing environment configuration.",
    "Never ignore a stale worker writing after a terminal status; preserve the terminal state and record the stale write.",
    "Never let repair-playbook ids drift; unknown tool, runbook, variable, or patch ids must be rejected or normalized."
  ],
  allowedRepairVariables: [
    "query",
    "owner_strategy",
    "fetch_mode",
    "page_list",
    "location_split",
    "tool_repair",
    "evidence_threshold",
    "provider_repair",
    "checkpoint_recovery",
    "syntax_check",
    "test_run",
    "code_patch_plan",
    "dashboard_repair",
    "export_repair",
    "process_lifecycle",
    "playbook_drift",
    "log_triage",
    "preflight_repair"
  ]
};

export function compactRepairPlaybook() {
  return {
    codingTools: repairPlaybook.codingTools.map(({ id, useFor, safeToRunAutomatically }) => ({ id, useFor, safeToRunAutomatically })),
    skills: repairPlaybook.skills,
    plugins: repairPlaybook.plugins,
    diagnosticRunbooks: repairPlaybook.diagnosticRunbooks,
    patchTemplates: repairPlaybook.patchTemplates.map(({ id, symptom, files, recipe, validation }) => ({ id, symptom, files, recipe, validation })),
    executionPolicy: repairPlaybook.executionPolicy,
    patchIdeas: repairPlaybook.patchIdeas,
    guardrails: repairPlaybook.guardrails,
    allowedRepairVariables: repairPlaybook.allowedRepairVariables
  };
}
