Ephesus runs AI coding agents behind your gates. Today it turns the terminal coding CLIs you already pay for into a self-coordinating company of agents, each with memory, a mailbox and a desk on a 2D floor, while you act as the architect. Phase 9, planned and not yet built, makes it a full agentic harness: its own engine for local and API models, a bench that scores the harness, and the floor as an optional view.
Electron · React · TypeScript · Pixi.js · xterm.js · node-pty
Pre-alpha. There are no releases and no installer — signed builds are a planned milestone (M7b.5) and have not shipped. If you are here to use Ephesus, the honest answer is: not yet. If you are here to build it, everything runs from source today and contributions are welcome.
What works right now: the Electron shell, real agent CLIs under management with
memory and mailboxes, the 2D floor, the Agora, the Odeon, the Stoa and the Gymnasium
self-improvement loop. Every package through M8c is built. The current milestone is
M9 — the harness is the product, planned and not yet started: the Architect has
approved its plan and not yet its build (docs/M9-PLAN.md).
The pitch above describes where Phase 9 (M9b to M9h,
docs/PHASE-9-PLAN.md) takes Ephesus; like M9, Phase 9 is
approved for planning only, and none of it is built.
Package-by-package state with evidence is in docs/PROGRESS.md,
which opens on where the build resumes; the narrative is under
Where the build stands.
You need Node 20.19+ or 22.12+, a toolchain that can compile native modules
(node-pty and better-sqlite3 are built on install), and at least one agent
CLI on your PATH.
.nvmrc says 20, which is the major line — but fifteen packages
in the lockfile, @electron/rebuild among them, require ^20.19.0 || >=22.12.0.
On an older 20.x you will get a wall of EBADENGINE warnings from npm install
and a native rebuild that may not work. Nothing refuses the install, so check
node -v yourself.
git clone https://github.com/Cassandra-Collective/Ephesus.git
cd Ephesus
npm install # patches node-pty, syncs the pixel fonts, rebuilds natives
npm run dev # the app, with hot reloadThen confirm the checkout is healthy:
npm run typecheck && npm run lint && npm testAll three must be green on a fresh clone. If they are not, that is a bug and we want
the issue. The full story — which engine to install, the files created in
~/.ephesus/, and what the shipped gate policy allows — is under
Setting it up.
Ephesus is documentation-first, and its rules are unusual on purpose: the docs are the
source of truth, accepted ADRs are append-only, every pull request carries evidence,
and a wiring seam with no test is a defect rather than a gap.
CONTRIBUTING.md explains all of it, including exactly what you
get from a first clone and what is deliberately missing from it.
The single most useful contribution today: clone it, run it on a machine that is not Windows, and open an issue about the first thing that goes wrong.
Ephesus was a working city: a harbor that moved goods in and out, an agora where business was coordinated, the Library of Celsus that held its knowledge, an odeon where the council met and heard reports, and the Temple of Artemis watching over all of it. Every subsystem in this harness is named for the part of the city that does the same job:
| Subsystem | City metaphor | What it does |
|---|---|---|
| Artemis | Patron deity | The orchestrator agent — your chief of staff. The one agent you talk to. Routes work, adjudicates, escalates only what needs you. |
| Hermes | The messenger | The messaging/routing layer — mailboxes, delivery, speech-act messages, escalation, anti-livelock rules. |
| The Agora | The marketplace | The shared on-disk coordination space — roster, blackboard, task ledger, append-only event log. A git repo with a single committer. |
| The Library (Celsus) | Library of Celsus | The memory layer — per-agent markdown memory plus semantic recall and the company archive, backed by MemPalace (ADR-0016), with reflection/condensation so it never grows unbounded. |
| The Odeon | Council theatre | The briefing subsystem — voice standups, auto-generated slide reviews, decision memos (mini-ADRs), and live meeting mode. |
| The Harbor | The port | Everything in and out — GitHub, Slack/chat bridges, webhooks, mobile/remote command, shareable hires. |
| The Herald | Town crier | The voice interface — a Jarvis-style spoken assistant. Provider-agnostic seam; ElevenLabs first, OpenAI Realtime fallback, local engines optional. |
| The Terraces | Terrace houses | The 2D office floor — every agent is an avatar at a desk; stations, walking, flying envelopes. Watchability as observability. |
| The Watch | City walls | Safety — human gates, budgets, the circuit breaker (steer → constrain → stop), the secret broker, telemetry. |
| The Gymnasium | Training grounds | The self-improvement loop — the company's primary standing mission: observe → propose → gate → land → measure, every step Architect-gated and recorded in a permanent ledger. |
| The Stoa | Colonnade of the scholars | The research department — studies Architect-registered external repositories (the tagged watchlist) and files provenance-cited briefs that feed the Gymnasium (ADR-0017); company modes decide when it runs autonomously, behind a proof gate (ADR-0018). |
Ephesus is a desktop app (Electron) that wraps a real terminal-agent CLI as fully-capable agents with long-term memory, mailboxes, and desks on a 2D floor, coordinated by Artemis, the one agent you talk to. It works with the subscription you already pay for, on its limits.
The MVP ships one engine — claude
(ADR-0024). Engines reach the
harness through an adapter seam: a fixed conformance surface every integration has
to pass (ADR-0009). That seam is real
rather than aspirational — two further adapters, codex and gemini, live in the
tree and are held to the same table on every run, because a conformance suite with
one implementation only proves that implementation compiles. Neither is registered,
and a hire declaring either is refused at activation, by name, with the reason:
neither can yet carry a granted autonomy level to its process or report a single
hook event, and a company that silently runs at one turn per wake is worse than one
that will not start. Adding an engine is an adapter and a registration, and the bar
is that suite passing for it on autonomy, notification and trust — not that it
spawns.
What makes it different from its inspiration:
- The architect relationship. Agents don't just do work — they account for it.
Every non-trivial decision becomes a decision memo you can approve or reject; every
milestone produces a short slide review; Artemis delivers spoken standup briefings; and
you can convene a live meeting with any subset of agents. See
docs/sdd/SDD.md §7(the Odeon). - Mission profiles. Three first-class, pre-wired company configurations:
- Skeleton Crew — a standing crew per app you own: health watching, CI babysitting, dependency updates, incident response with escalation to you.
- Front Office — the outward face of a project: issue/PR triage, drafted replies, docs and changelog upkeep, release preparation.
- Recursive Improvement — the self-improvement mission as a switchable crew (ADR-0019): you present repositories by URL, the Stoa studies them, approved proposals come back as pull requests from the company's own GitHub identity (ADR-0020) — and you merge.
- A voice-first chief of staff. The Herald gives Artemis a refined, Jarvis-style spoken presence: wake word, barge-in, briefings on demand, approvals by voice.
- A real org. Departments, roles, hiring templates, agent performance reviews, and retros — the "little company" made explicit rather than emergent.
- It improves itself — under governance. The company's primary standing mission is its own improvement (ADR-0015): improvement proposals rise from the company's own operating records, pass through the same memo/gate machinery as any other change, land with a declared success metric, and are measured — with every outcome, including rejections and rollbacks, kept in the Gymnasium ledger. The loop starts now, during the build phase, and carries into the running system unchanged in shape.
you ──── voice (Herald) / text ────► ┌─────────────┐
│ ARTEMIS │ orchestrator
◄── briefings · reviews · memos ──── │ (chief of │ roster · routing
(Odeon) │ staff) │ adjudication
└──────┬──────┘
│ assigns · routes · escalates
┌───────────────────────┬───────────────┴────────┐
▼ ▼ ▼
┌───────────┐ Hermes ┌───────────┐ Hermes ┌───────────┐
│ agent A │ ────────► │ agent B │ ─────────► │ agent C │
│ CLI + mem │ message │ CLI + mem │ message │ CLI + mem │
└───────────┘ └───────────┘ └───────────┘
└────── the Agora: blackboard · tasks · log · registry ──────┘
└────── the Library: memory.md × N + semantic index ─────────┘
- You describe intent to Artemis — by voice or text. Artemis decomposes it, checks the roster, and assigns work as self-contained task specs.
- Agents collaborate through Hermes over the Agora — plain files in a local git
repo. Agents write only to their own
outbox/; the harness router delivers into recipients'inbox/. Only the main process ever commits (noindex.lockwars). - Agents keep themselves running — a
Stop-hook autonomy loop drains each agent's inbox when it finishes a turn, so mail never waits for a human. - The company reports back — decision memos queue for your sign-off, milestone slide reviews archive in the Odeon, and Artemis briefs you aloud on schedule or on demand.
- Everything is watchable — avatars on the Terraces floor, live terminals, the activity log, budgets and the tool waterfall.
Ephesus runs a company of real terminal-agent CLIs on your machine. It needs three things from you and creates the rest itself.
1. The toolchain. Node 20.19+ or 22.12+ — the major line alone is not
enough, and nothing refuses the install, so check node -v yourself. .nvmrc
says 20, but fifteen packages in the lockfile (@electron/rebuild among them)
require ^20.19.0 || >=22.12.0; see Quick start for what an
older 20.x actually does. Then:
npm install # postinstall patches node-pty and rebuilds native modules
npm run dev # the app, with hot reload2. An engine you are logged into. The MVP ships Claude only
(ADR-0024): install the
claude CLI and sign in.
claude auth status # what Ephesus asks before it hires anybody
claude auth login # if that says you are not logged inEphesus asks this itself at every spawn. An agent whose engine has no session is shown as needs-login with the command to run, rather than started and left sitting at a login prompt while its card claims it is working.
3. Nothing else is required — though the first boot will tell you about one
optional extra. Semantic recall uses MemPalace
(ADR-0016), and without it the Library reports two degradations naming
pip install mempalace and falls back to a full-text rung. That is the harness
working as designed — a missing optional is disclosed, never silently absent —
and you can ignore it or install it.
On first launch the harness creates ~/.ephesus/ and
writes the files it needs, then tells you it did:
| File | What it decides | If you delete it |
|---|---|---|
config.json |
Window bounds, company mode | Recreated with defaults |
gate-policy.json |
The company-wide autonomy ceiling and which classes are held for a human | Everything is held and every profile is clamped to manual, reported as a degradation |
authority.json |
What Artemis may decide without you (FR-5.5) | She decides nothing and every routine call queues for you |
github-app.json |
The company's GitHub identity (optional, ADR-0022) | No company identity; the activation screen says which grants the broker cannot supply |
~/.ephesus/ is yours. Ephesus writes a file there only when it is absent
and never edits one you already have, so anything you change stays changed.
To run against a different home, set EPH_HOME to any directory:
EPH_HOME=/tmp/eph-scratch npm run dev$env:EPH_HOME = "$env:TEMP\eph-scratch"; npm run devThat is how you get a genuinely clean company without touching the one you already have — useful for trying something out, and required by the M8 exit script.
And whatever goes wrong, read DIAGNOSIS.md in that home first. The
harness rewrites it every minute and once more on the way out: what is working,
what is not and why, and — the part that matters — what has simply never been
exercised, which is not the same as fine.
4. Say go. Nothing is hired until you do. On first launch the app shows a banner above everything else saying the company is not working yet, and naming exactly what starting it would do: which agent gets hired on which engine, that its turns spend tokens against your subscription, what the company-wide daily ceiling is — or that there is none — and which schedules start and how often. Press START THE COMPANY and it begins in that same window; no restart, and you are never asked again.
Leave it closed and everything else stays readable: the panels, the book of record, the settings. Nothing runs, and the status strip says so rather than looking like a company that has finished its work.
Stopping it. Stop Electron by process, not by the npm run dev wrapper.
Killing the wrapper can leave Electron running and still using the same
~/.ephesus/ home. If you start npm run dev again, the second harness may
open its window, but it will not hire agents or arm schedules: the
one-harness-per-home guard reports agora/home-occupied, naming the process that owns the
home. Stop the leftover Electron process before restarting; the guard prevents
a second company from working against the same book of record
(ADR-0034).
Get-Process electron | Where-Object { $_.Path -like "*ephesus*" } | Stop-Process -Forcepkill -f 'electron.*ephesus'The ceiling ships at autonomous so a profile's own declaration governs, with
every irreversible class held at supervised — attempted with you able to see
and stop it, never silently:
destructive · prod-facing · scope-change · outbound · spend supervised
needs-human manual
everything else the profile decides
Autonomy composes stricter-wins: a profile can only ever be more cautious
than this file, never less. Edit gate-policy.json to tighten the whole
company at once.
The app is running and nobody is doing anything. That is correct — Ephesus ships with no crew, because which agents exist and what they are allowed to do is a decision, not a default. You get from here to a company watching your repository in four steps.
1. Check the orchestrator came up. The agent dock along the bottom should
show artemis. She is the only agent hired at boot; she routes work and
scribes the board, and she does nothing on her own until there is something to
route. If she is not there, the status strip will say why — most often
claude auth status reporting no session.
2. Open PROFILES. A profile is a mission bundle: the agents it hires, what each may do, and what wakes them (ADR-0012). Two ship with the app:
| Profile | What it is for |
|---|---|
| Skeleton Crew | watches a repository's CI, turns failures into incidents, triages them and reports back |
| Front Office | drafts outbound messages and holds them at a gate until you approve |
Start with Skeleton Crew. It is the one M8's exit review is written around.
3. Point it at a checkout. Choose the profile, then give it the path to a local clone of the repository you want watched — a real one, with CI that runs on push. The activation screen then shows you the whole plan before anything happens: which agents get hired, what each may do without asking, which triggers get armed, which declared secrets the broker cannot supply, and which repository it would watch. Read it. It is the last point at which nothing has started.
You need gh installed and authenticated (gh auth status) for the repository
half to work at all — that is how Ephesus reads CI runs, issues and pull
requests. Without it the crew hires fine and ingests nothing, which the app
reports as a degradation rather than as silence.
4. Activate. The crew is hired, each agent in its own git worktree so nothing runs in your own checkout, and each on its own engine install so no agent inherits your CLI's memory, plugins or hooks. From here on, a CI failure on the watched repository becomes an incident, the incident is routed to whoever is on call for it, and what they report comes back to the INCIDENTS section at the bottom of the PROFILES tab (it lives there rather than on a tab of its own because an incident belongs to a profile instance) — including every refusal, shown as a refusal.
To take it all down: deactivate the instance from PROFILES. To watch a second repository, activate the same profile again against a different checkout.
Every step above is also a command, because "the Architect activates" is about
authority, not about a mouse
(ADR-0033). With the app
running, in another terminal with the same EPH_HOME:
node scripts/ephctl.cjs helpconsent:status prints what starting the company would do; consent:grant says
go; budget:set --daily 5000000 bounds what it may spend — per hire, which
is the figure the consent screen and the run script both name; profile:activate --profile skeleton-crew --target repo:myapp --path /path/to/checkout hires the
crew and tells you which repositories it will watch; profile:instances,
agents:list, status and log:tail read.
budget:set may only ever lower the ceiling. Raising one is refused by
name, with the reason — a ceiling caps what the company may spend, so tightening
it is something a script may do and loosening it is not.
Four things it will not do, and it says so by name rather than pretending
they do not exist: approve a gate, decide a memo, set a secret, or change the
company mode. A script may run the company; only a human may authorise what the
company is not otherwise allowed to do. Every act performed this way is written
to the book of record tagged remote, so the log always distinguishes what the
window did from what a script did.
It is owner-only and local-only — a socket in the harness home, a local named
pipe on Windows, no port and no token. That means anything running as you can
operate the company; docs/THREAT-MODEL.md §6.8 says
plainly what that is and is not.
A mission profile is activated against a target repository from the Profiles tab. The activation screen shows what would happen before anything does: which agents get hired, what they may do, which triggers get armed, which declared secrets the broker cannot actually supply, and which repository it would watch.
You do not have to tell it which repository that is — Ephesus reads the target checkout's git remote and says what it found and where it found it. Two cases where it will not guess, and says so on the screen instead:
| What it finds | What it does |
|---|---|
| one GitHub remote | watches that repository |
a fork (origin and upstream at different repositories) |
refuses, names both, asks you to pick |
| no remote, or no GitHub remote | says the instance will watch nothing, and why |
In either of those, type the owner/repo into the repositories box before
reading the plan. Whatever the bundle's own harbor.json declares wins over the
checkout; what you type wins over both.
An instance that comes up watching nothing still hires its crew and arms its schedules — but it can ingest no CI run, issue or pull request, so it will raise no incident, and that shows up as a degradation rather than as silence.
This repository is a complete, self-contained documentation suite. Read in this order:
| Document | What it answers |
|---|---|
docs/srs/SRS.md |
Software Requirements Specification — actors, use cases, functional requirements (FR-1…FR-11), non-functional requirements, acceptance criteria. What must the system do? |
docs/adr/ |
Architecture Decision Records — 15 ADRs covering every load-bearing decision, each with context, options considered, and consequences. Why is it built this way? |
docs/sdd/SDD.md |
Software Design Description — component architecture, data models, on-disk formats, message schema, IPC contracts, sequence flows. How is it built? |
docs/design/UI-DESIGN.md |
Visual & interaction design — design tokens, the floor, panels, typography, motion rules. |
docs/design/VOICE-DESIGN.md |
Voice & conversation design — the Herald's persona, wake word, barge-in, briefing scripts, error behavior. |
docs/ENGINEERING-STANDARDS.md |
Coding standards, repo conventions, review rules, security rules, definition of done. |
docs/TEST-STRATEGY.md |
Test pyramid, what gets unit/integration/E2E coverage, agent-behavior evals, CI gates. |
docs/IMPLEMENTATION.md |
Phased implementation plan (M0 through M9h, with M7b the v1 boundary) with exit criteria, risk register, and build order. |
docs/PROGRESS.md |
The build register — where the build resumes, what waits on the Architect, and every open milestone, package by package with evidence. Closed milestones are archived, one file each, in docs/progress/. |
BUILD-PROMPT.md |
Ready-to-paste prompt that directs a coding agent to implement this design milestone by milestone, doc-grounded and verification-gated. |
docs/AUTOMATION.md |
The Claude Code automation installed in this repo (hooks, skills, subagents, CI) — what exists, why, and what's deferred. |
docs/gymnasium/LEDGER.md |
The self-improvement ledger — every Gymnasium proposal from evidence to measured outcome. |
docs/stoa/WATCHLIST.md |
The research watchlist — the external sources the Architect has registered for study, and the briefs they produce. |
docs/M9-PLAN.md |
The next milestone, planned and not yet started — the harness as the product: Ephesus's own agent engine running local models behind the existing adapter seam, and a bench that measures the harness's own uplift. Approved for planning on 2026-10-02. |
docs/PHASE-9-PLAN.md |
What follows M9, planned and not yet started — seven milestones (M9b–M9h) that give Ephesus the capabilities of an agentic harness in its own way: a workspace with the floor as a view mode, a local model service, contained execution and armed gates, web research, a messaging gateway with remote authorisation, schedules, mail and calendar, and a companion of its own on the phone. Planned on 2026-10-03. |
What comes next is decided and not started. On 2026-10-02 the Architect planned M9 — The harness is the product: Ephesus's own agent engine (
eph-agent, ADR-0036) running any OpenAI-compatible local model first and Claude natively second, behind the same adapter seam every wrapped CLI passes; a bench built before the engine so the milestone exits on a measured harness uplift rather than a feature list; and a headless-first core with the window as one client. The plan, its evidence and the seven decisions it rests on are indocs/M9-PLAN.md. Nothing below this note has changed; M9 has no landed package.What follows M9 is planned as well, and equally unstarted. On 2026-10-03 the Architect set the target: what a real agentic harness offers — conversations with local and API models, a model service that fits a model to the machine, deep research, blind comparison, documents, skills, a messaging gateway, schedules, mail and calendar, sandboxed execution, the phone — built Ephesus's way, with every capability granted by name, gated by the Watch and measured by the bench. The city and its names stay; the floor becomes a view mode and the window opens on a workspace (ADR-0040). Seven milestones, M9b to M9h, in
docs/PHASE-9-PLAN.md: five before the v1 boundary (M7b) and two — mail and calendar, and the companion — after it. Until M9b lands, everything this README shows and says about the floor is still what the app does.
M8's thirteen packages have all landed — and M8 has not closed. M6 and M7
landed the spoken company and the two outward missions; M8 is the hardening
milestone that runs before shipping, because the suite was green while Closing
Time had never once run in the shipped app, the standup read the oldest 500 log
entries, and the dock showed an overnight run's first 300 events. Its exit is
not a checklist: it is SRS §6.1's one-hour company test on
a real repository, run by a developer who is not the author, from a clean
clone, following only this README, and surviving a deliberate restart
mid-run. That run has not happened, so the row is open — as M7's own exit has
been since 2026-09-01, for the same reason. The script for it is
docs/EXIT-M8.md.
Landed so far: a coverage baseline and the seam rule that enforces it (a wiring seam with no test is a defect, not a gap); a quit path that actually runs, with one door to the renderer and one ordered, isolated shutdown sequence; a degradation channel where every give-up is visible, durable and countable; the log-derived surfaces reading the whole book instead of its oldest 500 entries; the setup cliff — the config files the harness needs are now created, documented and reported, and an engine with no session says so instead of pretending to work; and a mission activated against a repository now actually watches it, because the checkout is asked which repository it is rather than a bundle that ships an empty list being the only source of the answer.
Since then: every hire works in its own git worktree, so a crew no longer runs git operations and file edits concurrently in your checkout — a spawn that cannot be isolated is refused rather than quietly falling back into it — and a breaker stop at the top rung now outlives the process it stopped, so an exhausted budget stops instead of cycling. Every hire also runs its own engine install, with its own config directory: a hired agent does not inherit your CLI's memory, plugins, hooks or MCP servers, and the harness is the only author of the hooks that install runs. What a target repository legitimately offers — its skills and subagents — the harness re-supplies by name, because a hire template declares what it may read. And a restart no longer silently un-hires the company: active missions, open gates with their settled verdicts, the trigger clock and the drafts an outbound gate is holding all come back, with anything that could not be restored reported rather than absent. The agents themselves are not respawned automatically — engine session recovery is the follow-on — so you reactivate, and the company tells you that is what happened.
And most recently, the work the company does is something you can see. An incident the crew was handed now has a surface: what was raised, who is on call, what they reported in their own words, whether anybody checked the diagnosis — and, above all, every refusal, shown as a refusal rather than as an absence. That last part is why the panel was worth building: on the first repository this was pointed at, twelve of twenty-one triage attempts were refused and every root-cause verdict the company ever received was thrown away for being too long, and all of it was written down where nobody would ever look. Those two refusals now say what rule they are enforcing and what to do about it, instead of answering an agent's plain English with a JSON parse error. The status strip also learned to tell a hung harness from an idle one: it asks the main process whether it is still there, on a deadline rather than a promise, because a harness whose event loop is stuck never answers and never fails either.
And now the company survives being left running. The book of record rotates:
log.jsonl is sealed into numbered archive segments once it grows past a few
megabytes, which is a rename and nothing else — the segments and the live file
concatenated are byte for byte the file that used to be there. No surface sees
less. That was the whole design constraint, because the incident board drops an
incident whose opening row it cannot find, so a rotation that quietly moved
history out of view would have emptied the panel rather than aged it; every
reader still folds the entire history, and the ones that only ever wanted the
newest few rows stopped paying for all of it — on a 28 MB log, the Activity
feed's read went from 200 ms to 26 ms, on the same loop that carries your agents'
keystrokes. Alongside it: a spawn no longer re-reads a week of transcripts on
every tick to work out what it has spent, one agent with an oversized memory no
longer stops reflection for everyone whose name sorts after it, the roster
finally records which mission profile hired each agent, and mail addressed to
an agent that is no longer running is now visible as such — it is neither
bounced nor dropped, because an agent can come back, but it is no longer a
silence.
And most recently, the front door says what actually ships. Ephesus registered
three engines and advertised five, two of which have never had an adapter at all.
That gap was not a missing feature but a set of silent wrong answers: on either
partial adapter the autonomy ceiling you granted was dropped on the floor; with no
Stop hook there was no continuation loop, so the agent stopped after one turn; and
with no hook stream at all its avatar asserted a confident idle for it for ever.
None of it failed — it just quietly happened, and the activation screen printed
"on codex" without a word. A hire on any engine but claude is now refused at
activation, naming the engine, the reason and the one edit that fixes it. The two
partial adapters stay in the tree, unregistered, because they are what keeps the
adapter seam honest. And the hook grade pty-heuristic, which named a mechanism
nobody ever built, is now called none, which is what it is.
And finally, the company asks before it starts. Booting Ephesus used to hire
an agent: artemis.start ran unconditionally at the end of boot, the scheduler's
first tick fired sixty seconds later, and nothing anywhere asked anybody first —
on a machine where spending is unbudgeted by default and the tokens are yours.
Now a first launch shows what starting the company would do, in the specifics of
your configuration, and does nothing until you say go; the answer is
remembered, and a withheld company is reported as a state rather than looking
like one that has finished its work. Consent covers the schedules too, not only
the hire — the two are different products, and a gate on the hire alone leaves
the standup, the retro and the metric check firing on the first tick anyway.
Alongside it, the README finally covers the gap between "the app booted" and "a
crew is watching my repo", the book of record's readers no longer lose a row to
a duplicate sequence number left behind by two harness instances sharing one
home, and docs/EXIT-M8.md is a script somebody who has
never seen this repository can follow, with the place each acceptance clause's
evidence lands named by hand.
And, added after the first attempt at that exit run: the company writes down
what is wrong with it. Every harness home now carries a DIAGNOSIS.md,
rewritten at boot, every minute, and once more on the way out. It says what is
working, what is broken and why, what is waiting on you — and, the part that
earns it, what has simply never been exercised, which is not the same as
fine. Nothing is stored to produce it: it is a reading of the degradation
channel and the book of record, both of which already existed, and it keeps
writing even while the company itself is stopped, because a diagnostic that
stops when its subject stops is not a diagnostic. The point is that when you
come back to a machine you left running — or hand it to somebody else — the
first file they open already answers the question, instead of them guessing from
a quiet screen.
That same exit attempt found this README sending people to two panels that do not exist, and a Node version the lockfile does not accept. Both are fixed here, which is what the exercise is for.
And, the package that unblocked the exit run itself: the controls are not
buried in the window. The first attempt stalled at the last step of setup —
consent and profile activation existed only in the renderer, so a runner who was
not a person at the keyboard could not reach them, and an hour's test died at
minute two. Two workarounds were offered and both refused in favour of naming
the real defect. Ephesus now carries a local control surface: consent, mission
activation and deactivation, convening a briefing, and the reads, all available
to a script through the same handlers the window calls — not a parallel
implementation, which is why the two cannot drift. It operates the company and
it does not authorise anything the company is not otherwise allowed to do:
gate approvals, memo verdicts, secrets and mode changes are refused by name,
with the reason, because a CLI that could approve a destructive gate would
delete the meaning of the very clause the exit run is measuring. Every act it
performs is tagged remote in the book of record, so an audit can always tell a
script from a person at the keyboard.
Then the first real attempt at that run happened, and it is where the rest of this milestone came from: the crew detected everything and could act on nothing. A mission bundle was read from the repository rather than from the harness home, so an activated instance had no runbooks to cite and no authority to act from — the single highest-value fix in the record, and the direct cause of both failing action clauses. Even with the file in place the agent could not open it: the playbooks directory sits outside the working directory a hire is spawned in, so it now carries a grant minted at spawn — read-only, deliberately, because an agent that could rewrite its runbook could quietly lower the bar it is judged against. Alongside it: a meeting with one attendee can end itself, and the floor prompt names the act of declining instead of instructing a turn that silently resets the round; an archived brief resolves from the home a reader actually has; a shipped prompt no longer instructs an act its endpoint refuses; and the ledger's first refusal teaches the rule instead of billing you for the same mistake eight times over.
And most recently, the company is bounded, and honest about itself. The first
unattended hour cost 40,453,419 tokens — $11.22 — because two defects compounded:
no ceiling could be set without a mouse, and the first ingest replayed two weeks
of settled history as news, raising eight incidents before the runner had broken
anything. Both are closed, and consent now asks for the ceiling rather than
assuming one — the verb may only ever lower it, because tightening a cap is a
script's to do and loosening one is a person's. The rest is the harness learning
to describe itself in the reader's vocabulary instead of its own. WORKING must
cite a row proving an area finished, not one proving it was asked: the
diagnosis called the incidents area working while the ledger had refused eight of
them. armed says which triggers have a clock — a runner following this
repository's own exit script would have read the old output as "stop, the run is
invalid" and been wrong. A seeded config names the file it actually seeded,
recall fails fast instead of hanging for ever, and a hire declares in advance what
it may do without asking, because an engine's own permission prompt during an
unattended hour is a stop nobody is there to answer. A crew comes back after a
restart with no manual filesystem step. And the exit script no longer tells the
crew the break is deliberate — it had been dictating the commit message for the
very failure the company is measured on finding.
The unattended hour itself has still never been run to completion. Every package above exists because an attempt died on it. The run is unblocked for the first time, and until it happens M8b's exit, M8c's exit and M7b all wait on it.
M7's own exit (SRS §6.1 on a real repository) remains open and is independent of M8. The same run is owed to both.
The previous milestone's story:
M5b complete — the learning company, on a licensed floor. The Stoa is in
the product: repositories the Architect registers by URL on the reading
desk (tagged, licensed, pinned), a researcher plan that is read-only and
secret-free by construction, briefs whose every finding must cite a path at
the pinned commit or die before a human sees them, and proposals that must
cite the brief they descend from. Company modes gate autonomy: improving
cannot be switched on until the §6.9 proof gate reads its evidence off the
ledger, the mode is visible everywhere, and a rung-3 breaker stop on
improvement work reverts it. The floor now paints from the purchased LimeZu
packs — see it — with the sheets kept out
of the repo per licence and the credit on the status strip.
EVIDENCE registered: src-munder-difflin pin=b91a49f license=MIT
EVIDENCE plan: commit=b91a49f readOnly=true envGrants=[]
EVIDENCE brief archived: RB-001 "Closing time and the hook-return…"
EVIDENCE ledger: GYM-001 … status=proposed cites=RB-001
The M5b demo view is in docs/demo/: the reading desk and a
brief on screen (m5b-stoa-desk · m5b-stoa-brief), the three cycle captures
(m5b-cycle-1/2/3), the LimeZu floor, and — from the close-out audit — the
research cycle re-run against a real, remotely-verifiable pin
(m5b-cycle-real-source.txt): the
audit caught the original demo citing a commit that existed in no repository,
the record was amended, and the chain re-proven end to end. Four in-milestone
defects were found by running the demo; the audit added five more fixes, every
one with a named regression test. Evidence trail in
docs/progress/M5b.md; full record in
the M5b record.
Next: M6 — the floor's face + the Herald (citizens at the MD-grade §5.1 spec, stations that are facts, act-colored envelope flights — then the spoken company). The art spec landed as UI-DESIGN v2 at the M5b close.
The previous milestone's story:
M5 complete — the accountable company. A review:deck task is
mechanically unclosable until its deck is archived; a new dependency is held
at the choke point until a memo exists and is verdict-ed — Artemis decides
within her delegated classes and countersigns, everything else queues for
the Architect, and a rejection reverses the action. Briefings are compiled
facts first, narrative second: a sentence without a resolvable ref refuses the
whole brief. Meetings enforce turn order (an early answer is held, not lost)
and file their minutes; the org layer computes every metric from log.jsonl
alone and writes a weekly retro that decides nothing. And the Gymnasium runs
governed: proposals without a falsifiable metric never reach a human,
verdicts are Architect-only, authority-widening is refused before any
approver could say yes.
DEMO 1 close before the deck: todo ← refused; the task did not move
DEMO 1 close after the deck: done
DEMO 2 action held by: new-dependency
DEMO 2 rejection reverses the action: denied
DEMO 3 every sentence carries refs: true
DEMO 4 held (said early): [ agent.scribe ]
The demo view is in docs/demo/: the six panel screenshots
(m5-briefs-tab · m5-decks-tab · m5-memos-tab · m5-odeon-meeting ·
m5-org-metrics · m5-gymnasium), a real archived deck
(m5-deck-artifact.html), and
the retro report generated from this
company's own records. Alongside M5, the Stoa ran its first full cycle:
a research brief over the upstream inspiration (RB-001)
became two Architect-approved, landed improvements (hook-boundary steer,
closing time) — the ledger's first proof-gate evidence. M5 was closed by the
two-agent audit (execution + design conformance); it re-proved every exit
criterion and caught one real ledger-column defect, fixed with regression
tests. Evidence trail in docs/progress/M5.md; full
record in the M5 record.
Ephesus is an original work inspired by the MIT-licensed Munder Difflin. Architectural patterns are reused with attribution (see each ADR's "Prior art" section); no upstream code or assets are vendored. The Jarvis-style voice is a style (a composed, understated British assistant persona), not a clone of any actor's voice or any studio's character.
Note
Inspired by Munder Difflin — the "office of your clones" agent harness. Ephesus reuses its strongest architectural ideas (two data planes, a file-based hive with a single git committer, the Stop-hook autonomy loop) and re-imagines the product around a different thesis: you are the architect of a small company, and the company reports to you — by voice, in briefings, in design reviews, and in decision memos.
