{"phase":"P4","service":"darkherd","supervisor_wired":true,"supervisor_graph_invoke_enabled":true,"p4cz":true,"p4ai":true,"rollback_wired":true,"rollback":{"checkpoint_store":"none","max_checkpoints_hint":256,"checkpoint_sqlite_metadata_wired":true,"checkpoint_facets_v0_snapshot_wired":false,"max_facets_v0_snapshot_chars":524288,"description":"Wide-restructure rollback checkpoints: P4v read-only policy + optional P4bh SQLite metadata rows when checkpoint_sqlite_metadata_wired true and DARKHERD_ORCHESTRATION_ROLLBACK_CHECKPOINT_IO_ENABLED=true (checkpoint_store stays none for policy tests). P4bk GET /api/v1/orchestration/rollback-checkpoints lists recent metadata rows when the same gates pass. P4bl GET /api/v1/orchestration/rollback-checkpoints/{checkpoint_id} returns one metadata row (HTTP 404 when unknown id) under the same gates. P4"},"rollback_config_source":"invariants","langgraph":{"installed":true,"version":"0.4.10"},"supervisor_budgets":{"max_graph_steps":64,"max_tool_rounds":32,"dry_run_default":true},"detail":"**P4ai** echoes read-only ``rollback`` policy on this **P4a** probe (mirrors **P4v**). Supervisor graph not registered — stub endpoint for LangGraph install probe (see plan/VISION_AND_EXECUTION_PLAN.md §8). Minimal compile+invoke smoke: GET /api/v1/orchestration/supervisor-smoke (P4b + P4aj rollback policy echo). Machine caps: ``constitution/invariants.json`` → ``orchestration_supervisor`` (P4c). Smoke applies ``max_graph_steps`` as LangGraph ``recursion_limit`` (P4d). Synthetic tool-round smoke: GET /api/v1/orchestration/supervisor-tool-round-smoke (P4e + P4ak rollback policy echo). Dry-run apply preview (no writes): GET /api/v1/orchestration/dry-run-apply-preview (P4f + P4y rollback policy echo). Routing preview (constitution): GET /api/v1/orchestration/routing-preview (P4g + P4af rollback policy echo; optional ?job_class= adds **P4bn** ``supervisor_job_class_preview`` — same ``job_class`` resolution as **P4ay** invoke, no LangGraph). HyperCharts **P4bq** same-origin **GET** proxies: ``/api/darkherd/orchestration/supervisor-smoke``, ``…/supervisor-tool-round-smoke``, ``…/tool-adapters-status``, ``…/rollback-checkpoints-status``, ``…/ontology-patch-head``, ``…/facets-catalog-status`` (parity with the FastAPI paths above). Wide-restructure intake (declined + audit): POST /api/v1/orchestration/wide-restructure-intake (P4h + P4ah rollback policy echo). Supervisor decision schema validate (no writes): POST /api/v1/orchestration/validate-supervisor-decision (P4j + P4ab rollback policy echo). Neighborhood plan schema validate (no writes): POST /api/v1/orchestration/validate-neighborhood-plan (P4k + P4ac rollback policy echo). Ontology patch schema validate (no writes): POST /api/v1/orchestration/validate-ontology-patch (P4l + P4ad rollback policy echo). Ontology patch simulate (audit on success, no facets apply): POST /api/v1/orchestration/simulate-ontology-patch (P5a + P4ad rollback echo; optional ?correlation_id=). Ontology patch LLM draft from SQLite Asset (audit on valid proposal): POST /api/v1/orchestration/propose-ontology-patch-for-asset (P5g + P4ad rollback echo; constitution ``ontology_patch_proposal.wired`` + ``DARKHERD_ONTOLOGY_PATCH_PROPOSAL_ENABLED`` + ``MISTRAL_API_KEY``). Ontology patch head (read-only SQLite singleton): GET /api/v1/orchestration/ontology-patch-head (P5b + P4ad rollback echo; last_simulated_* from P5a). Facets catalog read-only status: GET /api/v1/orchestration/facets-catalog-status (P5d + P5e + P4ad rollback echo; ontology_facets_catalog_executor_wired from invariants). Ontology patch apply pointer (audit + SQLite head applied_*; optional P5e facets_v0.json rename_node/deprecate_node/merge_concept/split_concept/add_edge_type/rename_facet_map_key when executor wired; **P6p** ``ontology_bundle_manifest_cache_invalidated`` + ``facets_catalog_executor_stats.manifest_v0_disk_fp_sync_*`` on repo catalog path): POST /api/v1/orchestration/apply-ontology-patch (P5c + P5e + P4ad + P6p; valid patches must set dry_run false). Ontology patch head pointer revert (SQLite ``applied_*`` only from latest ``ontology.patch.applied`` audit ``previous_applied_*``; no facets/Neo4j): POST /api/v1/orchestration/revert-ontology-patch-head (**P5f** + P4ad rollback echo; constitution ``ontology_patch_head_revert.wired`` + ``DARKHERD_ONTOLOGY_PATCH_HEAD_REVERT_ENABLED``; HTTP **404** without apply audits; idempotent when already at target). Claim extraction batch schema validate (no writes): POST /api/v1/orchestration/validate-claim-extraction-batch (P4m + P4ae rollback policy echo). Apply plan schema validate (no writes): POST /api/v1/orchestration/validate-apply-plan (P4n + P4z rollback policy echo). Wide-restructure multi-artifact validate (no writes): POST /api/v1/orchestration/validate-wide-restructure-bundle (P4o + P4aa rollback policy echo). Wide-restructure bundle + staged preview (no writes): POST /api/v1/orchestration/wide-restructure-staged-preview (P4t + P4u supervisor_allow / wide_restructure_dry_run_ok; P4w rollback policy echo). HyperCharts **P4bt** same-origin **POST** JSON proxies pair those read-only validate + wide-restructure-staged-preview FastAPI POSTs: POST /api/darkherd/orchestration/validate-supervisor-decision, POST /api/darkherd/orchestration/validate-neighborhood-plan, POST /api/darkherd/orchestration/validate-ontology-patch, POST /api/darkherd/orchestration/validate-claim-extraction-batch, POST /api/darkherd/orchestration/validate-apply-plan, POST /api/darkherd/orchestration/validate-wide-restructure-bundle, POST /api/darkherd/orchestration/wide-restructure-staged-preview. Staged apply read-only preview (no writes): POST /api/v1/orchestration/staged-apply-preview (P4p + per-op registry_match vs P4q tool ids; P4r/P4s flags + registry_summary/registry_gate_ok; P4x rollback policy echo); HyperCharts POST /api/darkherd/orchestration/staged-apply-preview (**P4bs**). Bounded staged apply execute (total N operations per apply_plan — each ``sqlite_noop_touch`` and/or ``rollback_checkpoint_append`` and/or wired ``read_only`` **P4bg** tool id; N capped by invariants orchestration_staged_apply_execute.max_sqlite_noop_touch_ops): POST /api/v1/orchestration/staged-apply-execute (**P4bf** + **P4bz** + **P4bg** + P4x rollback echo; audit ``orchestration.staged_apply.executed``; sqlite ops require ``DARKHERD_ORCHESTRATION_STAGED_APPLY_EXECUTE_ENABLED`` plus **P4aw** constitution + ``DARKHERD_ORCHESTRATION_SQLITE_NOOP_TOUCH_ENABLED``; rollback ops require the same master flag plus **P4bh** (``orchestration_rollback.checkpoint_sqlite_metadata_wired`` + ``DARKHERD_ORCHESTRATION_ROLLBACK_CHECKPOINT_IO_ENABLED``) and **P4q** ``rollback_checkpoint_append`` wired; read_only ops require wired **P4q** registry + same preview eligibility as **P4au**; HyperCharts POST /api/darkherd/orchestration/staged-apply-execute). Tool adapters registry (read-only): GET /api/v1/orchestration/tool-adapters-status (P4q + **P4be** ``neo4j_graph_summary_read`` read_only tool + P4ag rollback policy echo). Wired read-only tool probe (audit + bounded preview): POST /api/v1/orchestration/execute-tool-probe (**P4au** + P4v rollback echo; optional ``correlation_id``; disable via ``DARKHERD_ORCHESTRATION_TOOL_PROBE_ENABLED=false`` → HTTP 403); HyperCharts POST /api/darkherd/orchestration/execute-tool-probe (**P4av**). Bounded SQLite mutating-noop probe (constitution ``sqlite_noop_touch`` ``wired`` + ``DARKHERD_ORCHESTRATION_SQLITE_NOOP_TOUCH_ENABLED``): POST /api/v1/orchestration/execute-sqlite-noop-probe (**P4aw** + P4v rollback echo; audit ``orchestration.sqlite_noop_touch.executed``); HyperCharts POST /api/darkherd/orchestration/execute-sqlite-noop-probe (**P4ax**). **P4cz** on this GET: ``supervisor_graph_invoke_enabled`` mirrors ``DARKHERD_SUPERVISOR_GRAPH_INVOKE_ENABLED`` (POST ``/api/v1/orchestration/supervisor-graph-invoke`` **403** when false — **P4ay** env gate beside constitution ``supervisor_wired``). **P4bc** on this GET: ``supervisor_bound_tools`` + ``p4bc`` (per-tool wired / dry_run_default / safe caps from constitution). **P4cb** on this GET: ``supervisor_mutating_bound_tool_job_classes`` — constitution ``orchestration_supervisor.mutating_bound_tool_job_classes`` (subset of ``job_classes``) that may run mutating **P4ba**/**P4bb** tools; empty list denies all mutating commits. Minimal LangGraph supervisor (constitution job_class routing; optional **P4ba** ``refresh_tag_overlap_communities`` + **P4bb** ``enqueue_worker_job`` bound tools; dry-run defaults + **P4cb** job_class gate for mutating persist/enqueue): POST /api/v1/orchestration/supervisor-graph-invoke (**P4ay**/**P4ba**/**P4bb** + P4v rollback echo; audit ``orchestration.supervisor_graph.invoked``) when ``orchestration_supervisor.supervisor_graph_wired`` is true and ``DARKHERD_SUPERVISOR_GRAPH_INVOKE_ENABLED``; HyperCharts POST /api/darkherd/orchestration/supervisor-graph-invoke (**P4az**). Rollback checkpoints policy: GET /api/v1/orchestration/rollback-checkpoints-status (P4v; **P4bh** ``rollback_wired`` + row counts when constitution ``checkpoint_sqlite_metadata_wired`` and ``DARKHERD_ORCHESTRATION_ROLLBACK_CHECKPOINT_IO_ENABLED``; **P4cg** ``p4cg`` + ``supervisor_enqueue_append_rollback_checkpoint``; **P4cj** ``p4cj_snapshot_wired`` + ``p4cj_restore_http_wired``); **P4ch**/**P4cp** repeat the same **P4cg**/**P4cj** readiness bundle on this **P4a** GET (**P4co** ``orchestration_rollback_readiness_core`` — parity with that **P4v** GET and ``GET …/insights/summary``). GET /api/v1/orchestration/rollback-checkpoints (**P4bk** newest-first metadata list when the same gates pass; else HTTP **403**); GET /api/v1/orchestration/rollback-checkpoints/{checkpoint_id} (**P4bl** single-row read when the same gates pass; HTTP **404** when id missing); DELETE /api/v1/orchestration/rollback-checkpoints/{checkpoint_id} (**P4bm** metadata row delete + audit ``orchestration.rollback_checkpoint.deleted`` when the same gates pass; HTTP **404** when id missing); POST /api/v1/orchestration/rollback-checkpoint-append (bounded metadata row + audit; HyperCharts **P4bi** proxy); HyperCharts GET /api/darkherd/orchestration/rollback-checkpoints (**P4bk**); HyperCharts GET /api/darkherd/orchestration/rollback-checkpoints/<id> (**P4bl**); HyperCharts DELETE /api/darkherd/orchestration/rollback-checkpoints/<id> (**P4bm**). **P5cn** optional ``ontology_patch_neo4j_followup_auto_enqueue`` — newest ``ontology.patch.neo4j_followup_auto_enqueued`` audit (insights **P5cm** parity; **P5ck**/**P5cl** ``jobs[]``; **P5cq** ``enqueue_*`` booleans). **P5co** optional ``ontology_patch_graph_followup`` — newest qualifying ``ontology.patch.applied`` audit when **P5e** wrote facets (insights **P5cj** parity; ``graph_followup_hint``). **P4cq** ``analytical_refresh_policy`` — Vision §5.2 scheduled global refresh cadence + active analytical corpus ceiling hint (``constitution/invariants.json`` → ``analytical_refresh_policy``; operators enforce via cron + **P7k**/**P4ba**).","invariants_version":"2026-04-18.168","supervisor_mutating_bound_tool_job_classes":["dirty_community_refresh","manual_admin","scheduled_full_rebuild"],"p4cb":true,"supervisor_bound_tools":{"refresh_tag_overlap_communities":{"wired":true,"dry_run_default":true,"max_assets_cap":2000},"ontology_patch_draft_and_simulate":{"wired":false,"dry_run_default":true},"enqueue_worker_job":{"wired":false,"dry_run_default":true,"allowed_kinds":["append_rollback_checkpoint","backfill_cmc_market_fields","dedupe_coingecko_cmc","extract_claims_staging","incremental_ingest","invalidate_analytics_cache","neo4j_sync_archived_assets","neo4j_sync_graph_assets","neo4j_sync_graph_constraints","neo4j_sync_tag_overlap_run","rebuild_tag_overlap_full","reconcile_cmc_inactive_archive","reconcile_coingecko_stale_archive","refresh_tag_overlap_communities","repair_asset_tag_ontology_edges","repair_claim_ontology_edges","repair_whitepaper_gaps","set_corpus_tier","summarize_tag_overlap_communities","tag_overlap_publish_pipeline"],"allowed_kinds_count":20}},"p4bc":true,"p4cg":false,"p4cj_snapshot_wired":false,"p4cj_restore_http_wired":false,"supervisor_enqueue_append_rollback_checkpoint":{"enqueue_worker_job_wired":false,"append_rollback_checkpoint_in_allowed_kinds":true,"enqueue_allowed_kinds_configured":true,"mutating_bound_tool_job_classes_nonempty":true,"rollback_checkpoint_io_wired":true},"analytical_refresh_policy":{"scheduled_full_rebuild_interval_days":7,"max_active_corpora_assets_hint":10000,"config_source":"invariants","autoschedule_enqueue_pipeline_wired":false,"description":"Vision §5.2 — operator-tunable hint for scheduled global community/summary passes over the active analytical corpus (~10k ceiling); enforce with external cron + queue_worker (**P7k**) jobs (e.g. tag_overlap_publish_pipeline). Optional **P3do**: when autoschedule_enqueue_pipeline_wired is true and DARKHERD_GLOBAL_REFRESH_AUTOSCHEDULE_ENABLED runs in the API process, DarkHerd may enqueue tag_overlap_publish_pipeline on cadence — still drained by queue_worker."},"ontology_patch_graph_followup":{"audit_event_id":80,"source_audit_created_at":"2026-05-02T09:05:20.207618","graph_followup_hint":{"p5_neo4j_followup":true,"neo4j_uri_configured":true,"enqueue_worker_job_kind":"neo4j_sync_graph_constraints","enqueue_worker_job_hint":"POST /api/v1/admin/maintenance/queue-worker-job JSON {\"kind\":\"neo4j_sync_graph_constraints\",\"payload\":{}} — or same-origin HyperCharts POST /api/darkherd/admin/maintenance/queue-worker-job with the same JSON (**P7xi** auth forward). Drain host needs NEO4J_URI; mirrors python -m app.jobs.sync_graph --constraints (DDL + catalog seed; no asset sync).","enqueue_worker_job_kind_assets":"neo4j_sync_graph_assets","enqueue_worker_job_assets_hint":"Optional follow-up queue job: POST …/queue-worker-job JSON {\"kind\":\"neo4j_sync_graph_assets\",\"payload\":{\"limit\":500,\"asset_offset\":0,\"include_archived\":false}} or HyperCharts POST /api/darkherd/admin/maintenance/queue-worker-job with the same JSON (**P7xi**). (limit 1..100000 required; optional asset_offset 0..500000 for paged ranked windows like ``python -m app.jobs.sync_graph --limit --asset-offset``; NEO4J_URI on drain host).","enqueue_worker_job_kind_claim_ontology":"repair_claim_ontology_edges","enqueue_worker_job_claim_ontology_hint":"Optional claim facet refresh: POST …/queue-worker-job JSON {\"kind\":\"repair_claim_ontology_edges\",\"payload\":{}} or HyperCharts POST /api/darkherd/admin/maintenance/queue-worker-job with the same JSON (**P7xi**), or immediate POST …/repair-claim-ontology-edges JSON {} / same-origin HyperCharts POST /api/darkherd/admin/maintenance/repair-claim-ontology-edges JSON {} (**P7xi** auth forward; same Bolt work as python -m app.jobs.repair_claim_ontology_edges; NEO4J_URI on worker/drain host).","suggested_cli_sync_graph_constraints":"python -m app.jobs.sync_graph --constraints","suggested_cli_repair_claim_ontology_edges":"python -m app.jobs.repair_claim_ontology_edges","suggested_cli_repair_asset_tag_ontology_edges":"python -m app.jobs.repair_asset_tag_ontology_edges"}},"ontology_patch_neo4j_followup_auto_enqueue":null}