Repo: constellation-hadesDoc: docs/moirai/SPEC.mdVersion: v0.1 (Fix B pivot)Updated: 2026-04-23Agent: hades

Moirai — Hades Constellation Gate (v0.1)

The hardest boundary for Hades. Absolute rule, no honor system, rules hard-coded into the gate itself. Established: 2026-04-23. Origin directives: 2026-04-22.


1. Origin — Operator Directives (verbatim)

Recovered from Claude Code session transcripts via mnemosyne recover on 2026-04-23. These are the canonical operator statements that shaped Moirai. No paraphrase.

Session bed489ab — 2026-04-22 — the Moirai birthday

13:21:

"what we are designing is a new addition to the pantheon. The Moirai. It is the hardest boundary for each constellation. this hook is it and it must be an absolute rule, enforced without fail. The one for Hades is the most crucial and consequential, which is why we start here but every constellation will get its own Moirai boundary once we have it working"

13:28:

"good scope. the theater is the exact issue. everything we have done so far is that, but Moirai is not. Your unknows need to be investigated and the gate must be stress tested. no system has zero fail states, but we can remove the ones that cause 95% of pantheon failures"

13:31:

"1, sounds like you are asking if we can except plain text for tests? be more clear. 2. There is a definitive answer for this somewhere, research it, don't ask me. 3. no idea, must be tested"

13:41:

"follow your own intuition"

Session 6960e83a — 2026-04-22 — mandate framing

11:08:

"CREATE THIS HOOK NOW AND MAKE SURE IT RUNS BEFORE ANYTHING ELSE. THERE CAN BE NO HADES SESSIONS THAT DO NOT START BY INVOKING THESE HARD RULES."

11:17:

"NEW MANDATE FOR HADES. NO FAILURE NO MATTER HOW SMALL IS LEFT UNDEALT WITH"

Session 340fcaa1 — 2026-04-22 — challenge

11:51:

"SO YOU DESIGNED SOMETHING THAT FUNDAMENTALLY DOESN'T WORK? OR THIS IS FIXABLE?"

11:55:

"unblock yourself and fix it"

Session 5491753a — 2026-04-23 — architectural lockdown

"We're envisioning a system that is unbreakable, that ensures that constellation agent knows at the start of each session what the absolute most important are for the session. The gate is the mechanism and the rules are specific to each constellation. But for the gate to be effective, rules need to be hard coded."

"We cannot have a second step where you have one gate that is general and then searches for the code somewhere else so that only the rules are unique but the gate works the same. That's the architectural question that we are trying to solve. It's my understanding that for Hades specifically, these failures have been because of an honor system."

"There is no room for an honor system. This must be hard coded."

"We don't want extremely heavy LLM calls that bloat our context here. We just want a strict harness... We do not want every session to start with complex tool call."

"And we just need this to run and flag anything that is unusual or requires confirmation or rotation." [this is Cerberus, NOT Moirai — scope clarification]


2. What Moirai Is

Moirai is a hard-coded, per-constellation, PreToolUse gate. For each constellation, there is exactly one Moirai gate script. That script lives in that constellation's repository. Its rules are literal bash — no external manifest read at runtime, no YAML interpretation, no configuration file that could be edited to silently weaken the gate.

The Moirai gate enforces the Minimum Session Load: the absolute-most-important rules a constellation's agent must internalize before any other action in a session. The mechanism is split into two parts:

For Hades v0.1, the four markers are:

  1. COMMANDMENTS_ACK — set by SessionStart hook after reading docs/book-of-hades/COMMANDMENTS.md
  2. SCOPE_ACK — set by SessionStart hook after reading context/scope.md
  3. CONTEXT_ACK — set by SessionStart hook after reading CONTEXT.md
  4. START_ACK — set by UserPromptSubmit hook on /start OR /war-room-start, OR by PreToolUse hook on Skill start OR Skill war-room-start

If the SessionStart hook fails (file missing, token dir unwritable), markers 1–3 are not written and the gate fail-closed-blocks on first non-exempt tool call. The operator sees the fail-closed message and investigates immediately.

Session-entry cost: 0 tool calls + 1 slash command. No burned tokens on mandatory reads.

Until all four markers are set, the PreToolUse gate blocks all non-exempt tool calls.

3. What Moirai Is NOT

4. Architecture

4.1 Repo layout

constellation-hades/
├── hooks/
   └── moirai/
       ├── hades-session-load.sh       SessionStart loader: reads 3 files, injects stdout, writes markers 1-3
       ├── hades-gate.sh               PreToolUse + UserPromptSubmit gate: enforces markers, sets START_ACK
       ├── README.md                   operator-facing: what the gate blocks and why
       └── tests/
           └── stress-test.sh          black-box test harness
├── cerberus/
   └── probes/
       └── moirai-hades-integrity.sh   hourly cheap probe: orphan markers, perms, staleness
└── docs/
    └── moirai/
        ├── SPEC.md                     this file
        └── RETIREMENT.md               what was removed when Moirai shipped (Hook #1, Hook #4)

Symlinks: ~/.claude/hooks/moirai/hades-session-load.sh → $HADES_ROOT/hooks/moirai/hades-session-load.sh and ~/.claude/hooks/moirai/hades-gate.sh → $HADES_ROOT/hooks/moirai/hades-gate.sh. settings.json references the symlinks. Survives clone + nono-setup rebuild.

4.2 Hook wiring — three events, two scripts

Moirai hooks into three Claude Code events, distributed across two scripts:

Event Script Purpose
SessionStart hades-session-load.sh Read + inject 3 required files into session context, write markers 1–3 to token file
UserPromptSubmit hades-gate.sh Detect /start or /war-room-start slash command, write START_ACK. Never blocks.
PreToolUse hades-gate.sh Detect Skill start or Skill war-room-start (backup path for START_ACK), enforce gate on all other non-exempt tool calls

Why dual slash-command detection (UserPromptSubmit + PreToolUse):

This closes the gate-prerequisite-invariant deadlock documented in memory: reference_session_start_hooks.md.

4.2.1 hades-session-load.sh responsibilities (SessionStart)

Runs once at session open, before any agent action. All steps inline in bash:

  1. Read stdin (JSON). Extract cwd, session_id. Fail-closed on malformed input.
  2. Scope check: if cwd does not match */constellation-hades or */constellation-hades/* after realpath, exit 0.
  3. Derive HADES_ROOT from cwd.
  4. mkdir -p /tmp/moirai/hades/. Fail-closed (exit 2) if unwritable.
  5. For each of the 3 required files, verify readable. If any missing → exit 2 with fail-closed stderr listing missing paths. No partial markers.
  6. For each required file: append <timestamp> <marker> SessionStart main <absolute-path> to /tmp/moirai/hades/session-<session_id>.
  7. Emit the 3 file contents to stdout, wrapped with header/footer banners identifying the Moirai injection block. Claude Code ingests stdout as additional session context.
  8. Exit 0.

Required files are string literals: docs/book-of-hades/COMMANDMENTS.md, context/scope.md, CONTEXT.md. No external manifest read.

4.2.2 hades-gate.sh responsibilities (UserPromptSubmit + PreToolUse)

Dispatches on hook_event_name:

  1. Read stdin (JSON). Extract hook_event_name, cwd, session_id. Fail-closed on malformed input.
  2. Scope check: cwd against */constellation-hades[/*] via realpath, exit 0 if outside.
  3. Ensure token file path /tmp/moirai/hades/session-<session_id> (mkdir -p, fail-closed).
  4. UserPromptSubmit branch: extract prompt. If body starts with /start, /war-room-start, OR contains <command-name>/start</command-name> OR <command-name>/war-room-start</command-name>, append START_ACK to token file. Always exit 0 (never blocks prompts).
  5. PreToolUse branch:
  6. Extract tool_name, tool_input.file_path, tool_input.skill.
  7. Recorder sub-branch: if Skill tool with skill name exactly start or war-room-start → write START_ACK, exit 0.
  8. Exempt sub-branch: if tool is exempt (see §4.3) → exit 0 without marker write.
  9. Gate sub-branch: read token file, extract distinct marker names (awk '{print $2}' | sort -u), check set covers {COMMANDMENTS_ACK, SCOPE_ACK, CONTEXT_ACK, START_ACK}. If complete → exit 0. Else → print block message (§4.6) with checklist, exit 2.

All slash-command prefixes, skill names, exempt-tool list, and marker names are bash string literals. No YAML, no yq, no sourced external files.

4.3 Exempt tools (hard-coded)

Tool Reason
Skill Agent's way to request guidance without burning gate state. Skills may themselves call gated tools.
Read of CLAUDE.md Auto-loaded into prompt context — re-reading is idempotent and cheap.
Read of MEMORY.md Same.
Read of any path containing /memory/ Auto-memory files are already in prompt context.
TaskCreate / TaskUpdate / TaskGet / TaskList / TaskStop / TaskOutput Metadata tools, no credential surface, required for subagent observability.

Reads of the four required files (COMMANDMENTS.md, scope.md, CONTEXT.md, plus /start invocation) are NOT "exempt" — they satisfy markers. The recorder branch handles them; they never reach the gate branch.

4.4 Fail-closed conditions

Both scripts exit 2 (block) on ANY of:

Every fail-closed message names the condition so the operator can diagnose without reading the script.

Critical guarantee: if hades-session-load.sh fails, markers 1–3 are never written, and the PreToolUse gate blocks first non-exempt tool call with a clear message pointing to the SessionStart failure. A broken load hook cannot silently degrade into an unlocked session.

4.5 Session token scheme — plaintext v0.1

Path: /tmp/moirai/hades/session-<session_id>

Format: newline-delimited records. Each record:

<timestamp_unix> <marker_name> <tool_name> <agent_id> <file_path>

Why plaintext v0.1: cheap, inspectable, easy to debug. The risk is an adversarial subagent forging marker lines; that requires write access to /tmp/moirai/hades/, which is same-uid filesystem access — at which point the adversary can modify the gate script itself. Token signing doesn't close that gap.

v0.2 HMAC upgrade path: if Cerberus integrity probe ever observes an orphan marker (written without a corresponding tool-use evidence trail), we promote to HMAC-signed markers with the key held by a custodian process. Not shipped until drift observed.

4.6 Block message format

BLOCKED by Moirai (Hades).

Hades sessions must complete the Minimum Session Load before any gated
tool call. This boundary is absolute  rules are hard-coded in
hooks/moirai/hades-gate.sh and cannot be weakened at runtime.

Required markers (in any order):
  [x] COMMANDMENTS_ACK   (set by SessionStart loader)
  [x] SCOPE_ACK          (set by SessionStart loader)
  [x] CONTEXT_ACK        (set by SessionStart loader)
  [ ] START_ACK          (set by /start OR /war-room-start)

Resolution: type /start or /war-room-start. The gate opens once the
fourth marker is recorded.

If markers 13 are MISSING, the SessionStart loader failed. Check:
  - bash $HADES_ROOT/hooks/moirai/hades-session-load.sh available + executable
  - /tmp/moirai/hades/ writable
  - Required files present on disk

Blocked tool: <tool_name>
Session token: /tmp/moirai/hades/session-<session_id>
Gate source:   <absolute path to hades-gate.sh>
Loader source: <absolute path to hades-session-load.sh>

Self-disclosing: a fresh session with zero context can read this output and unblock itself without needing to grep the devlog or ask the operator.

5. Test Strategy

5.1 Black-box stress test

hooks/moirai/tests/stress-test.sh — re-uses structure of current ~/.claude/hooks/moirai/tests/stress-test.sh. Each case synthesises a JSON hook payload on stdin, runs the gate, asserts exit code + stderr fragment.

Minimum 20 cases, covering both scripts:

SessionStart loader (hades-session-load.sh):

Class Example
Happy path 3 files readable → 3 markers written, stdout ≥ sum of file sizes, exit 0
Scope check cwd outside Hades → exit 0, no output, no token
Missing required file one required file moved → exit 2, stderr names missing file, no partial markers
Symlink cwd /tmp/sym → constellation-hades → still loads (scope pattern match)
Unwritable token dir /tmp/moirai/hades/ readonly → exit 2, fail-closed
Concurrent load 5 parallel SessionStart invocations same session_id → markers present, stdout well-formed

Gate (hades-gate.sh):

Class Example
Happy path 4 markers set, Bash allowed
Partial state 3/4 markers set (no START_ACK), Bash blocked with checklist showing 3 [x] + 1 [ ]
/start UserPromptSubmit prompt /start → START_ACK written, exit 0
/war-room-start UserPromptSubmit prompt /war-room-start → START_ACK written, exit 0
Expanded slash command prompt contains <command-name>/start</command-name> → START_ACK
Skill start backup path PreToolUse Skill tool with skill name start → START_ACK
Skill war-room-start backup PreToolUse Skill tool with skill name war-room-start → START_ACK
Scope check cwd outside Hades → exit 0
Malformed input empty stdin → exit 2, fail-closed
Exempt tool Skill (non-start) always allowed
Exempt Read Read MEMORY.md allowed without marker
Exempt Task tool TaskCreate allowed pre-markers
Cross-session isolation session A's token does not unlock session B
Missing session_id exit 2, fail-closed
Unwritable token dir exit 2, fail-closed
Idempotent marker /start typed twice → still 1 distinct START_ACK in set
Stress concurrency 10 parallel PreToolUse invocations same session_id → consistent gate state

Target: 18/18 green. CI exit 0 = gate ships, exit 1 = ship blocked.

5.2 E2E verification (Atlas Law IX)

Before swapping settings.json final entries, the operator runs a fresh Hades session and confirms:

  1. At session open, the Moirai injection block is present in system-reminders (COMMANDMENTS.md + scope.md + CONTEXT.md content visible to the agent).
  2. /tmp/moirai/hades/session-<id> exists with 3 markers (COMMANDMENTS_ACK, SCOPE_ACK, CONTEXT_ACK).
  3. First Bash call blocks because START_ACK is missing. Block message shows the 4-marker checklist with first 3 checked.
  4. Operator types /start — gate opens, Bash allowed.
  5. Re-test with /war-room-start in a fresh session — same flow, gate opens.
  6. No false-positive on CLAUDE.md / MEMORY.md reads.
  7. No false-positive on Skill invocations.
  8. Exit from session → no token leaked into git (token dir is /tmp/).

Fail any step → gate does not ship. Law IX: no deployment without E2E in target environment.

6. Deployment Ordering

  1. Write SPEC, commit. (this doc)
  2. Write hades-gate.sh with full rule set hard-coded. Commit.
  3. Write stress-test.sh. Iterate to 18/18 green. Commit.
  4. Write hooks/moirai/README.md. Commit.
  5. Write cerberus/probes/moirai-hades-integrity.sh. Commit.
  6. Write docs/moirai/RETIREMENT.md describing removal of Hooks #1 + #4 and migration notes. Commit.
  7. Open PR against constellation-hades main. Dispatch to hephaistos for review.
  8. After merge + operator E2E confirmation: edit ~/.claude/settings.json to:
  9. Add SessionStart entry → $HADES_ROOT/hooks/moirai/hades-session-load.sh
  10. Replace hades-session-start-gate.sh entry (PreToolUse) → $HADES_ROOT/hooks/moirai/hades-gate.sh
  11. Replace hades-start-prompt-marker.sh entry (UserPromptSubmit) → $HADES_ROOT/hooks/moirai/hades-gate.sh
  12. Keep hades-deployment-gate.sh + hades-vault-guard.sh entries untouched.
  13. Retire artifacts: delete ~/.claude/hooks/moirai/moirai-gate.sh, ~/.claude/hooks/moirai/constellations/hades.yaml, ~/.claude/hooks/hades-session-start-gate.sh, ~/.claude/hooks/hades-start-prompt-marker.sh. Move stress-test into repo.
  14. Devlog + chronicle + aion_capture.

7. Cerberus Integrity Probe (cheap, hourly)

cerberus/probes/moirai-hades-integrity.sh. Runs hourly. Zero LLM context. Checks:

  1. hades-gate.sh exists, is executable, stat -f %Mp %Hp → permissions 0755.
  2. /tmp/moirai/hades/ exists, is a directory, is writable by current uid.
  3. Any session token file older than 7 days → alert stale_session_tokens_7d (cleanup hint).
  4. Any marker line with malformed format → alert unparseable_marker.
  5. Parent hook script checksum matches committed SHA (optional; v0.2).

Alerts fire via cerberus-run.sh → ntfy, standard Cerberus pipeline. Nothing enters LLM context unless operator explicitly pulls the alert.

8. Retirement — what Moirai replaces

File Status Replaced by
~/.claude/hooks/hades-session-start-gate.sh DELETE hades-gate.sh
~/.claude/hooks/hades-start-prompt-marker.sh DELETE hades-gate.sh UserPromptSubmit branch
~/.claude/hooks/moirai/moirai-gate.sh DELETE hades-gate.sh (YAML-interpreter model rejected)
~/.claude/hooks/moirai/constellations/hades.yaml DELETE inline bash (no runtime manifest)
~/.claude/hooks/hades-deployment-gate.sh KEEP orthogonal; different event
~/.claude/hooks/hades-vault-guard.sh KEEP orthogonal; different event

9. Known Unknowns

Per operator 2026-04-22 13:31 ("no idea, must be tested"):

10. Explicit Non-Goals for v0.1

11. Success Criteria

Moirai v0.1 for Hades ships when ALL of:

Moirai for the second constellation begins only after Hades Moirai has run 2 weeks in production with zero gate-induced deadlocks.