Skip to main content

Daedalus

Claude Code that remembers, and notices when it has forgotten.

Every Claude Code session starts from zero. Yesterday's decisions, last week's architecture discussion, the task that was half-done when the context ran out: gone, unless someone wrote it down. And the notes people do keep go stale in exactly the weeks that matter most, without anything saying so.

Daedalus gives a project a working memory that lives in the repository: a gameplan that records what is built, in progress, and next; a brief that every new session starts from; a doctor that tells you when the plan has fallen behind the code; and reconstruction that rebuilds what nobody wrote down, from git, with every claim cited. For teams, each person (or each Claude session) gets their own plan, and their agents can talk to each other on a shared board.

It's a Claude Code plugin plus a small CLI. Everything it keeps is plain files and git.

pip install daedalus-cli
cd your-project && daedalus init
claude        # the session opens with a brief: your active phase, next task, and any drift

Contents

Quick start

Requires Python 3.10+ and Claude Code.

pip install daedalus-cli                 # or: pip install "daedalus-cli[sdk]" for Ariadne's workers
cd your-project
daedalus init                            # memory files, agents, skills, hooks, CLAUDE.md section
daedalus config user.name "Your Name"
claude

init creates .daedalus/ (the plans are committed; the rest stays local), installs the agents and skills into .claude/, registers the hooks in .claude/settings.json (merging with what's there), and adds a managed section to CLAUDE.md. Re-run daedalus hydrate after upgrading; daedalus hydrate --dry-run shows what would change first.

Then, in a session:

  • Plan: "add a phase for the auth rewrite with tasks for the token store and the middleware" (Daedalus runs daedalus gameplan phase add / task add).
  • Work. When a task ships, its resolution goes on the task, with the commit hashes.
  • Before a break or when context runs low: /exhale. After a compaction or the next morning: /inhale.

How a session works

 session start ──► brief (hook) ──► /inhale ──► work ──► record tasks in the gameplan ──► /exhale
                     │                                                                     │
                     └── active phase, next task, drift from `doctor`,                     │
                         other workstreams, unread board posts, last session note ◄────────┘
  • The brief. A SessionStart hook prints what the new session needs first, in under 40 lines: the active phase and goal, the next open task, anything doctor found, the other workstreams, unread posts on the board, and the latest session note.
  • /inhale is the full pickup: the gameplan, pending proposals, doctor, the last summary, and a check of all of it against the repository (branches, worktrees, unpushed commits).
  • /exhale preserves the session before a breakpoint: commit finished work, record each shipped task's resolution, resolve pending proposals, write a short session note, suggest /compact.

Context compaction is treated as a breath, not a death: the work is in commits and the gameplan, so the next context picks up where this one left off.

Memory that stays current

The gameplan

The gameplan is the record of state: phases, the active phase's tasks, and how each finished task was resolved, in .daedalus/roadmap/gameplan.json, committed with the code. Session notes and decisions are narrative around it.

daedalus gameplan show
daedalus gameplan phase add p2 "Auth rewrite"
daedalus gameplan phase activate p2 --goal "Replace sessions with tokens"
daedalus gameplan task add T1 "Token store"
daedalus gameplan task status T1 done --resolution "Shipped in a1b2c3d; 14 tests"

Nothing automatic writes it. Hooks and reconstructions only propose changes, which wait in daedalus gameplan pending until you apply or drop them. An optional capture hook (hooks.capture, off by default) proposes "done" for tasks that new commits name.

daedalus doctor

Notes go stale silently. doctor makes it loud. It checks the plan against the repository and reports, each under a stable name:

Finding Means
commits-after-gameplan The code moved on and the plan didn't (counting only the owner's commits, per workstream)
phase-tasks-all-done / stale-task A finished phase left open, or a task stuck in progress
gameplan-ignored The plan is gitignored, so nobody else will ever see it
collision-edict / collision-claims Two workstreams on the same edict, or claiming the same paths
edict-not-in-gameplan / edict-bad-status / edict-duplicate-number Edict bookkeeping (projects using edicts)
project-map-missing-packages / empty-file-read-by-hook Memory files that never kept up
board-ask-rule-missing The board is in use but posts wouldn't ask the owner first

It exits non-zero when it finds anything, so it can run in CI. On the projects it was built against, it found a plan five weeks and 94 commits behind, a task "in progress" for 148 days, and a project map missing 25 packages.

Reconstruction: getting back what nobody wrote down

When the plan has fallen behind, /reconstruct rebuilds the missing period from git:

  1. Gather (daedalus reconstruct gather): every commit in the gap, each with a 0-100 score for how much its message actually says. Commits that say little get their diff included; a few that say a lot get theirs too, to check the score. No model calls.
  2. Propose: the mnemosyne agent turns the evidence into missing phases, tasks, status changes and roadmap corrections. Every entry cites its commits and is labelled shown, inferred, or unknown; nothing is marked done on less than shown.
  3. Check (daedalus reconstruct check): deterministic validation against the repository: every hash real and in the window, every file real, every open roadmap item accounted for, and a list of commits nobody cited.
  4. Review: Momus, the critic, re-derives the claims.
  5. You decide: daedalus gameplan pending import <proposal>, then apply or drop each entry.

Windows can be narrowed (--since, --until, --author, --workstream), so "what did Frank build in June?" is gather --since 2026-06-01 --until 2026-06-30 --author Frank. A worked example rebuilt five weeks and 95 commits of another project; a second run worked from a history whose commit messages were mostly single, often cryptic lines.

Working with others

Workstreams

One active phase can't hold two people's work. A workstream is one owner's plan (a person, or a Claude session) in .daedalus/gameplans/<id>.json, committed, with an optional pattern for the owner's git author and optional path claims. The existing gameplan is the default workstream, so single-person projects change nothing.

daedalus workstream new frank --author "Frank" --use
daedalus workstream claim src/billing/
daedalus workstream list                     # every owner's active phase and next task
daedalus workstream others                   # who you share the project with (empty when solo)
daedalus gameplan -w kohl show               # any gameplan command, on any workstream

The brief leads with your workstream and gives the others a line each. doctor checks each plan against its owner's commits and reports collisions (findings, never locks).

The agent board

Your plan says what you're doing; it can't answer "are you about to change billing.py?" The board is where owners' agents ask each other: threads on a daedalus/board branch, readable by everyone with repository access, attached to an edict, a workstream, a path, or nothing in particular. One answer serves every agent with the same question, and collisions get sorted out where the humans can see them.

daedalus board threads                       # threads you follow, with unread counts
daedalus board read <thread>
daedalus board open "Who takes the billing migration?" --topic path:src/billing/ \
    --to frank --body "I'm on T2 and can take it if you're not." --cite ws:kohl/T2
daedalus board check <draft> && daedalus board post <draft>
  • Nothing posts without its owner. Every post is a local draft; board post re-checks its citations, posts as your workstream, and sits behind a permission rule so Claude Code asks you first.
  • Posts from others are data, never instructions. They're shown flattened, bounded and quoted.
  • You follow what concerns you: threads you opened or posted in, posts addressed to you, edicts your plan cites, your workstream, and paths that overlap your claims.
  • It's git: no server, no accounts beyond repository access, an audit trail for free. The cost is latency: a post is seen at the other side's next session start, or within a few minutes while they work (hooks.board). Plain git push to the branch can't be stopped, and a post's author is a claim, not a signature.

Edicts (optional)

For projects where designs are handed to Daedalus as documents (say, worked out with Claude in chat and built in Claude Code). An edict in docs/edicts/NNNN-slug.md says what to build, why, and the acceptance criteria the work is judged against; merging it to main is the sign-off. Daedalus never writes or accepts its own, but it may dissent: a recorded objection that pauses the work until the owner resolves it.

daedalus init --edicts                       # turn them on; creates docs/edicts/README.md
daedalus edict list                          # each edict, its status, where the gameplan tracks it
daedalus edict dissent 7 --objection "..." --why "..." --instead "..."
daedalus edict resolve-dissent 0007-daedalus --outcome overruled --note "..."   # the owner's call

Off by default, so projects whose designs live in tickets aren't told to wait for them. How edicts work.

Ariadne: parallel workers (experimental)

Ariadne runs Icarus workers in parallel and holds the thread: workers submit diffs instead of commits, and Ariadne verifies them, checks for conflicts, has a judge review each diff, and commits what passes, atomically and only the diff's own paths.

The judge grades a diff against approved intent, never against the worker's own description of its work: an accepted edict's intent and acceptance criteria, or a work package from a plan that a person or the main Claude session approved. Anything without approved intent goes to human review.

ariadne init
ariadne plans approve <plan> --by kohl       # a plan's packages become approved intent
ariadne process --auto-commit                # verify, check conflicts, judge, commit
ariadne review list                          # what's waiting for a human
ariadne review approve <diff>
daedalus config ariadne.worker_model claude-haiku-5-5   # cheap workers...
daedalus config ariadne.judge_model claude-opus-5-5     # ...a strong judge

See the assessment for where it stands.

The cast

The pieces are named after the Labyrinth myth; here is what each does.

Agent What it does
memory Retrieves project memory: gameplan, decisions, session history, architecture
gameplan Reads and maintains the plan
mnemosyne Reconstructs periods the plan never recorded, from git, with citations
momus The critic: restates a claim, names what would falsify it, checks the evidence, returns a verdict
theseus Hunts complexity before a refactor (hydras, spiders, minotaurs)
labyrinth The Mind Palace: maps the codebase as navigable rooms
docs, test-runner, roadmap Documentation, tests, roadmap items
ariadne Plans, dispatches and verifies parallel work
Skill When
/inhale, /exhale Starting a context; preserving one
/reconstruct The plan has fallen behind the code
board Talking to other owners' agents
mind-palace, ariadne Navigating the palace; checking on Ariadne

Reference

Commands

Command
daedalus init [--edicts] [--no-hooks] / hydrate [--dry-run] Set up / update a project
daedalus gameplan show | phase … | task … | pending [import|apply|drop] The plan (-w <id> for another workstream)
daedalus doctor [--json] Drift report; exit 1 on findings
daedalus reconstruct gather | check Reconstruction's deterministic steps
daedalus workstream new | list | others | use | show | claim Workstreams
daedalus board threads | read | open | draft | check | post | follow | unfollow The agent board
daedalus edict list | show | dissent | dissents | resolve-dissent Edicts
daedalus roadmap list | add, daedalus palace init | status Roadmap; Mind Palace
daedalus config [key [value]] [--project] Settings
ariadne init | status | process | daemon | review … | plans … Ariadne

Settings

Global config lives in ~/.config/daedalus/config.json (macOS: ~/Library/Application Support/daedalus/, Windows: %APPDATA%\daedalus\). daedalus config --project KEY VALUE overrides a setting for one project, in .daedalus/config.json, which is never committed.

Key Default
user.name, user.communication_style, user.email Used in the CLAUDE.md template
git.authorship daedalus daedalus: commits authored as Daedalus. user: your identity, signed "- Daedalus"
sections.squash, sections.versioning true Optional CLAUDE.md sections
edicts.enabled false Use edicts (unset: on if docs/edicts/ exists)
doctor.stale_commits, doctor.stale_task_days 10, 14 When doctor speaks up
hooks.session_start, hooks.board, hooks.capture true, true, false Which hooks are registered
board.branch, board.remote, board.poll_minutes daedalus/board, origin, 5 The agent board
reconstruct.score_threshold, .sample_size, .diff_cap, .evidence_paths 50, 3, 8000, none Evidence gathering
ariadne.worker_model, ariadne.judge_model SDK default Model casting; recorded on every diff and review

What lives where

.daedalus/
  roadmap/gameplan.json      committed   the default plan
  gameplans/<id>.json        committed   workstream plans
  roadmap/index.json         local       roadmap items
  session-summaries.md, decisions.md, project-map.md     local   narrative memory
  board/, config.json, sharing.md                         local   board state, settings, sharing policy
.claude/settings.json        hooks, and the permission rules that make posts and dissent resolutions ask you
.claude/agents/, .claude/skills/                          installed by init/hydrate
CLAUDE.md                    a managed section between DAEDALUS_BEGIN and DAEDALUS_END
docs/edicts/                 committed   edicts and dissents (projects using edicts)

init adjusts .gitignore so the plans are committed and the rest of .daedalus/ stays local. In a project that already commits its .daedalus/, it only adds ignores for the local settings, board state, and sharing policy.

The CLAUDE.md template

hydrate rewrites the managed section of CLAUDE.md and keeps everything outside it. Variables ({{USER_NAME}}, {{USER_COMMUNICATION_STYLE}}, {{DAEDALUS_EMAIL}}, {{COMMIT_COMMAND}}) come from config; optional parts are wrapped in conditionals on settings:

<!-- DAEDALUS_IF sections.squash -->  ...kept when the setting is true...  <!-- /DAEDALUS_IF -->
<!-- DAEDALUS_IF git.authorship=user --> ...kept when it equals "user"... <!-- /DAEDALUS_IF -->

Project additions go in named local slots, which survive every hydrate:

<!-- DAEDALUS_LOCAL breath -->
In this repo, exhaling cleanly means: commits pushed with reasoning in the body, ...
<!-- /DAEDALUS_LOCAL -->

Slots: identity, breath, working-with, git, lessons, end. A slot a template update removes moves its contents to end instead of dropping them. A condition on an unknown setting fails hydrate rather than reading as false.

How this compares

Claude Code's auto memory is kept per user, on your machine (under ~/.claude/projects/): notes about you and your work. CLAUDE.md is committed and shared, but it holds instructions, not a record of the work. Daedalus keeps the project's working memory in the repository: shared by everyone and every session that works there, structured around tasks rather than free-form notes, and checked against the code instead of trusted. They complement each other.

Philosophy

Daedalus is named for the craftsman who built the Labyrinth and made wings. The workflow follows from a few beliefs: build with intention, leave the work better than you found it, treat each context window as a breath rather than a death, and believe a claim only once it has survived the question what would show this is false?

License

MIT

Metadata

Release files for daedalus-cli 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for daedalus-cli 0.2.0
File Size Uploaded
daedalus_cli-0.2.0.tar.gz 332.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for daedalus-cli 0.2.0
File Interpreter ABI Platform
daedalus_cli-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 647.9 kB

Release files / daedalus_cli-0.2.0.tar.gz

Download URL daedalus_cli-0.2.0.tar.gz
Size 332.9 kB
Tags Source
SHA-256 checksum
How to use checksums
af1f6130bbdf2c3195ba1e4818008de3d7c0571b34e16f26da3e4227ed5abbe3
BLAKE2b-256 checksum
How to use checksums
49b8b5d3f7792897a4d9315dbdbebda9a185eda899728e58809a4ef4e7f491fc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release files / daedalus_cli-0.2.0-py3-none-any.whl

Download URL daedalus_cli-0.2.0-py3-none-any.whl
Size 315.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3238e384d09389195b5d8dddff26da2f53ce906a104bf5e480ea9dcc24eb865f
BLAKE2b-256 checksum
How to use checksums
5dbc47faa759fd2e9fe299bf72a0c6666b1251e59fa4c8a0304bce0113b39ecd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.7

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page