commanders: definition versus state, and phase 2 sharing
The directory holds two kinds of thing and they must not mix. The definition — CLAUDE.md, parameters, procedures, scripts — is what travels. The instance state — what it has handled, what it spawned, its loop's pid — must never, or a recipient's commander starts up believing it already handled somebody else's recordings and silently does nothing. Structural from the first commit rather than sorted out later, for the same reason plugin capabilities are read in place: a directory boundary beats a convention, because a convention is what a tired person violates. Parameters separate from procedure, too. With a path baked into a script, a fork is a debugging session; declared in one place, a fork is a conversation — the new owner is asked where their memos land and the commander rewrites its own file. Phase 2, recorded and NOT being built: a commander turns itself into a git repository when asked, in conversation. No button — it git inits, ignores state/ and commits, which is the same shape as everything else here. What it needs to know goes in the commander SKILL rather than an affordance, because an affordance's body is charged to every turn of every commander forever and this earns that approximately never. Two rules that belong in the design now because both are awkward later. A credential is definition-shaped — it looks like configuration — so gitignoring state/ does not protect it; commanders name what must be configured and the platform holds the value. And a shared commander declares what it requires, or it lands on an install without a Whisper server, arms cleanly and fails silently at 3am, which is the worst failure this system has. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
@@ -76,6 +76,61 @@ front gets a worse answer than asking later.
|
||||
watch memos, scans and a mailbox. So this is a list on the row, seeded with one, and the commander writes
|
||||
additions into its own `CLAUDE.md` as they are agreed.
|
||||
|
||||
## What the directory holds: definition versus state
|
||||
|
||||
Two kinds of thing live in there and they must not mix, because one of them travels and the other must
|
||||
never.
|
||||
|
||||
```
|
||||
$DATA_PATH/<email>/commanders/<commander id>/
|
||||
CLAUDE.md DEFINITION — the living document, extended as the job is agreed
|
||||
parameters.* DEFINITION — the things a fork has to change. Paths, cadences, thresholds
|
||||
procedures/ DEFINITION — what a spawned agent reads at fire time
|
||||
scripts/ DEFINITION — the loops
|
||||
state/ INSTANCE — what it has handled, what it spawned, its loop's pid
|
||||
```
|
||||
|
||||
**Separate from the first commit, not sorted out later.** A shareable bundle is "everything except
|
||||
`state/`" only if that boundary is structural; mixed together, extracting one means picking files apart by
|
||||
hand and getting it wrong once. Same reasoning as plugin capabilities being read in place rather than
|
||||
copied — a directory boundary beats a convention, because a convention is what a tired person violates.
|
||||
|
||||
The failure it prevents is specific: a recipient's commander starting up believing it has already handled
|
||||
your recordings, and silently doing nothing.
|
||||
|
||||
**Parameters are separate from procedure, or forking means editing code.** With `~/Documents/VoiceMemos`
|
||||
baked into a script, a fork is a debugging session. Declared in one place, a fork is a conversation — the
|
||||
new owner is asked where their memos land and the commander rewrites its own file. That difference is the
|
||||
whole point of the thing being an agent rather than a template.
|
||||
|
||||
## Phase 2 — a commander becomes a git repository
|
||||
|
||||
**Not now.** Recorded because the phase 1 layout has to leave room for it, and it costs nothing today to
|
||||
leave that room.
|
||||
|
||||
**There is no button.** The owner asks the commander, in conversation, to make itself shareable, and it
|
||||
does — `git init`, a `.gitignore` that excludes `state/`, a first commit. That is the same shape as
|
||||
everything else here: the commander maintains its own directory, and the platform does not reach in.
|
||||
|
||||
**What it needs to know goes in the commander SKILL, not an affordance.** The layout, what is tracked,
|
||||
what is ignored and how credentials are handled is reference material — read on the one day somebody asks
|
||||
for it. An affordance's body is charged to every turn of every commander forever, and this would earn that
|
||||
cost approximately never. `capabilities/skills/commander/SKILL.md` gains a section.
|
||||
|
||||
**Credentials are named, never valued.** This is the rule that matters, because the natural place to put a
|
||||
Whisper URL is the config file that is about to become public. A commander declares what must be
|
||||
configured — "an STT endpoint" — and the platform holds the value. Gitignoring `state/` does not cover
|
||||
this: a credential is definition-shaped, it looks like configuration, and it would be committed and pushed
|
||||
and stay published.
|
||||
|
||||
**And a shared commander declares what it requires.** Yours assumes a transcription plugin, a Whisper
|
||||
server actually configured, and a folder that exists. Landing on an install without them, it arms cleanly
|
||||
and fails silently at 3am — the worst failure this system has. Same problem `osDependencies` solves for a
|
||||
plugin, wanting the same answer: the receiving platform refuses rather than pretends.
|
||||
|
||||
The forking story then reads: clone, open a conversation, answer where your memos land and what you want
|
||||
done with them, and the commander rewrites its own parameters and arms.
|
||||
|
||||
## The consequence for the skill
|
||||
|
||||
`capabilities/skills/commander/SKILL.md` says turn one is orientation — *"read where you actually are
|
||||
|
||||
Reference in New Issue
Block a user