Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The helper is called `sumctl` to avoid shadowing the Unix `sum` command. Normall

## State and communication

Private state lives in `.sum/` and is ignored by Git. `.sum/context.json` records the coordinator owner and `.sum/sessions/` the registered panes and roles. Optional `.sum/preferences.md` and `.sum/projects.md` hold local preferences and project notes; `.sum/projects.json` is the registry of enrolled projects (host/owner/repo, verified remote, canonical path, enrollment metadata), while their clones live outside the state under the Git-ignored `projects/` directory. `.sum/coordinator/` holds the coordinator's contract revisions and refresh receipts. `.sum/machine.json` maps each host's stable identity to the hostnames it was seen using, so records written before that identity existed keep resolving; it is not part of a backup. Each task stores its brief, base SHA, branch/worktree, pane bindings, questions, answers, report, an append-only `evidence` list (reports, structured handoffs, reviewer findings, coordinator verification, exact PR observations), the bound reviewer endpoint, the last reconciled PR identity, a versions sidecar with brief revisions, an optional environment sidecar with the task-local environment record, and an optional usage sidecar (`usage.json`, counts and coverage from the Claude Code transcripts of the task's bound panes, written only by `usage collect`, `report`, and `cleanup` when `settings.json` enables usage accounting). File updates are locked and atomically replaced on one local machine.
Private state lives in `.sum/` and is ignored by Git. `.sum/context.json` records the coordinator owner and `.sum/sessions/` the registered panes and roles. Optional `.sum/preferences.md` and `.sum/projects.md` hold local preferences and project notes; `.sum/projects.json` is the registry of enrolled projects (host/owner/repo, verified remote, canonical path, enrollment metadata), while their clones live outside the state under the Git-ignored `projects/` directory. `.sum/coordinator/` holds the coordinator's contract revisions and refresh receipts. `.sum/findings/` holds optional findings under stable IDs derived from source task and key, including append-only disposition and linked-work history. `.sum/machine.json` maps each host's stable identity to the hostnames it was seen using, so records written before that identity existed keep resolving; it is not part of a backup. Each task stores its brief, base SHA, branch/worktree, pane bindings, questions, answers, report, an append-only `evidence` list (reports, structured handoffs, reviewer findings, coordinator verification, exact PR observations), the bound reviewer endpoint, the last reconciled PR identity, a versions sidecar with brief revisions, an optional environment sidecar with the task-local environment record, and an optional usage sidecar (`usage.json`, counts and coverage from the Claude Code transcripts of the task's bound panes, written only by `usage collect`, `report`, and `cleanup` when `settings.json` enables usage accounting). File updates are locked and atomically replaced on one local machine.

Workers use the exact commands in their generated brief. The core interaction is:

Expand All @@ -68,10 +68,12 @@ Workers use the exact commands in their generated brief. The core interaction is
./bin/sumctl context TASK_ID --section brief --revision r1 # a recorded brief revision, hash-verified, never rewritten
./bin/sumctl context TASK_ID --since CURSOR # what changed since the `cursor` of an earlier read
./bin/sumctl notes TASK_ID --text 'finding' # the one optional task-local notes.md (a claim; secrets refused)
./bin/sumctl finding record TASK_ID --key KEY --title TITLE --explanation TEXT --next-step TEXT
./bin/sumctl finding list TASK_ID
./bin/sumctl help [TOPIC] # command discovery without the full manual
```

Sections: `outline`, `brief`, `decisions`, `handoff`, `evidence`, `execution`, `environment`, `update`, `returns`, `notes`.
Sections: `outline`, `brief`, `decisions`, `handoff`, `evidence`, `execution`, `environment`, `update`, `returns`, `notes`, `findings`.


Prose fields are bounded (`--max-chars`, 0 for all) and credential-shaped text is redacted in the view, never in the record. Outstanding decisions are listed in full on every read regardless of paging. Worker prose, handoffs, and notes are labelled claims; only `verify` and `pr reconcile` records are verification evidence. Skills reach agents as explicit file references (path, size, hash) to read when needed, not as an assumed skill standard. Nothing here calls a model or reads a worker's checkout.
Expand Down
1 change: 1 addition & 0 deletions docs/features/coordination.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Journeys the coordinator, workers, and developers take through `sumctl` and the

| ID | Scenario | Driver | Evidence |
| --- | --- | --- | --- |
| `finding.dispositions` | A registered worker or coordinator records an optional finding without creating follow-up work; a repeated task/key capture returns the same record and changed content is refused. The coordinator can defer, dismiss, reopen, resolve, attach to existing work, promote to an existing approved follow-up task or an authorized in-scope repair, and settle linked work; history survives archival of the source, and backup, task context, and show preserve the ledger. No automated coverage exists. | manual | No automated coverage exists; inspect the persisted ledger and CLI projections |
| `roles.claim` | The first pane claims coordinator atomically; later panes become developers or workers | automated: `go/internal/cli/cutover_test.go`, `go/internal/cli/demo_test.go` | offline suite |
| `roles.machine-identity` | Renaming the host keeps the coordinator role and its return routes without `--reclaim`, because every recorded endpoint's `machine` is a stable identity hashed from the OS machine ID (`/etc/machine-id`, or the macOS platform UUID), never the raw ID or the hostname. A different host stays other-machine even when it shares the hostname: its coordinator claim is refused and reclaim fails as other-machine, and so are a VM clone that regenerated its machine ID with `.sum/` copied, and the tasks of a records backup restored there | automated: `go/internal/cli/machine_identity_test.go`, `go/internal/machine/machine_test.go` | offline suite. The tests pin the machine ID and hostname in process, and each scenario fails when the identity is the raw hostname. Implementation: `go/internal/machine/machine.go`, `go/internal/store/context.go`, `go/internal/store/store.go`, `go/internal/roleinit/designated.go`, `go/internal/app/app.go`, `go/internal/bindcmd/bind.go`. |
| `roles.legacy-hostname-records` | Records written by the hostname-keyed release keep resolving with no manual step. A hostname value names this host when it is the current hostname or was recorded under this host's identity in `.sum/machine.json`, which each registration updates. That covers a mix of old names once the host has carried each one. The coordinator's record and session files keyed by an old hostname are re-keyed on the next `init`, and a delivery recorded under the old key still counts, so it is not sent again. A name recorded under another host's identity never resolves here, and neither does one this host has not been seen carrying | automated: `go/internal/cli/machine_identity_test.go`, `go/internal/store/registration_test.go`, `go/internal/machine/machine_test.go` | offline suite. A pre-upgrade hostname record in a backup restored on a different host that shares that hostname still resolves there, as it did before. A name the host carried only under the older release resolves after one `init` while the host carries it again (the recovery step in `docs/recovery.md`). Implementation: `go/internal/machine/machine.go`, `go/internal/store/store.go`, `go/internal/roleinit/designated.go`, `go/internal/returns/returns.go`, `go/internal/returns/pump.go`. |
Expand Down
Loading