forked from jason/echo
Phase 5: group-voice docs, onboarding runbook, CHORUS icon — v2.0.0-rc.1
The final phase of CHORUS-PLAN.md. Code- and doc-complete for group use; rc pends live deployment at chorusapi.mpm.to. - Repo README rewritten for CHORUS: group model (schema 5), concurrency posture, configuration, baked-build onboarding, layout, testing, 2.0 version history (ECHO history referenced at the fork tag). - Operator→member voice sweep across SKILL.md (incl. the trigger description, now group-aware), all references, 8 command docs, plugin README; member preferences / semantic layer / triage guidance describe the group model. - docs/ONBOARDING.md: member runbook — vault stand-up, per-member config, bake, deliver, self-onboarding first load, norms, offboarding. - docs/USAGE.md rewritten as the member usage guide. - New icon: chorus-icon.svg + 1024/512/64 PNGs (three voices, one center). - Removed ECHO-era assets (icons, spec PDF, perf briefs); ECHO planning docs retired to docs/history/. All preserved at echo-fork-point. - eval/README documents test_multimember.py. Manifest -> 2.0.0-rc.1; rebuilt chorus-memory.plugin. Verified: routing-sync, 25/25 unit, scaffold, 5 mock e2e suites, run_eval metrics green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,5 +16,5 @@ bootstrapped (+ `schema_version`), and the **config source** for owner/endpoint/
|
||||
(per-field: env override `CHORUS_OWNER`/`CHORUS_BASE`/`CHORUS_KEY`, then the machine-local
|
||||
`~/.claude/chorus-memory/config.json` — or `baked-in (plugin)` on a per-user baked build,
|
||||
which is authoritative and reported as such). Exits non-zero if anything is red — if the config is
|
||||
missing (or still the placeholder template), ask the operator for their chorus-memory config file and install it with `chorus.py config import <path>` (or `config set --owner … --endpoint … --key …`). For the full vault-invariant lint, run
|
||||
missing (or still the placeholder template), ask the member for their chorus-memory config file and install it with `chorus.py config import <path>` (or `config set --owner … --endpoint … --key …`). For the full vault-invariant lint, run
|
||||
`/chorus-health`.
|
||||
|
||||
@@ -14,4 +14,4 @@ CHORUS_TODAY=<currentDate> python3 "$SDIR/vault_lint.py"
|
||||
|
||||
Exit codes: `0` clean · `1` violations (printed, grouped by check) · `2` vault unreachable · `3` vault not bootstrapped (run `bootstrap.py`).
|
||||
|
||||
Summarize the violations grouped by category and propose fixes, but **do not auto-fix** without the operator's go-ahead. If this is the first substantive session of a calendar month, offer to write the findings to `_agent/health/YYYY-MM-vault-health.md` (per the skill's **Vault Health** section).
|
||||
Summarize the violations grouped by category and propose fixes, but **do not auto-fix** without the member's go-ahead. If this is the first substantive session of a calendar month, offer to write the findings to `_agent/health/YYYY-MM-vault-health.md` (per the skill's **Vault Health** section).
|
||||
|
||||
@@ -14,6 +14,6 @@ python3 "$CHORUS" load
|
||||
|
||||
`load` prints all eight sections (and self-onboards your member namespace on a first visit) (404s on today's note / inbox are shown as absent, not errors) and flags an un-bootstrapped vault. Follow up with `chorus.py scope show` if you need the sessions-since-switch count, and a project search if a specific project is in play.
|
||||
|
||||
**If `load` prints `NOT CONFIGURED` (exit 78)**, this machine has no usable key file yet. Don't proceed with memory — follow **First run** in `SKILL.md`: tell the operator CHORUS isn't configured, ask for their chorus-memory config file (group/member/endpoint/key), install it with `chorus.py config import <path>` (or `config set`), then re-run `load`.
|
||||
**If `load` prints `NOT CONFIGURED` (exit 78)**, this machine has no usable key file yet. Don't proceed with memory — follow **First run** in `SKILL.md`: tell the member CHORUS isn't configured, ask for their chorus-memory config file (group/member/endpoint/key), install it with `chorus.py config import <path>` (or `config set`), then re-run `load`.
|
||||
|
||||
Do not narrate the reads. End with a one-line orientation: who/what/where the active scope is, and any reconcile prompt.
|
||||
|
||||
@@ -7,7 +7,7 @@ Use the **chorus-memory** skill to run **session reflection** (H5). Scan this co
|
||||
things worth remembering across sessions, then propose them — don't write blindly.
|
||||
|
||||
1. **Extract** durable items from the conversation: new facts, preferences, decisions,
|
||||
commitments, people/companies/projects introduced, and anything the operator said to remember.
|
||||
commitments, people/companies/projects introduced, and anything the member said to remember.
|
||||
Skip the ephemeral. Anchor relative dates on the conversation's `currentDate`.
|
||||
2. **Emit a JSON array** of proposals (one per item), each:
|
||||
`{"title","kind","body","aliases","tags","sources","confidence"}` — `kind` ∈
|
||||
@@ -15,7 +15,7 @@ things worth remembering across sessions, then propose them — don't write blin
|
||||
working, skill, decision`; set `"inbox": true` when the home is genuinely unknown;
|
||||
`confidence` 0–1 (items below 0.6 are dropped — send those to the inbox instead).
|
||||
Write the array to a file with the Write tool (cross-platform; no heredoc).
|
||||
3. **Preview, then apply.** Dry-run first (writes nothing) and show the operator the plan; only
|
||||
3. **Preview, then apply.** Dry-run first (writes nothing) and show the member the plan; only
|
||||
apply after they confirm.
|
||||
|
||||
```bash
|
||||
|
||||
@@ -16,7 +16,7 @@ python3 "$CHORUS" capture "<title>" <bodyfile> --kind <kind> [--aliases a,b] [--
|
||||
python3 "$CHORUS" capture "<title>" --inbox # unknown home -> idempotent inbox line
|
||||
```
|
||||
|
||||
**If capture exits `76` (duplicate gate):** the title strongly resembles an existing entity — do NOT retry blindly. Show the operator the printed candidates and either update the existing note (`capture ... --merge-into <slug>`) or, only after they confirm it's genuinely distinct, re-run with `--force`.
|
||||
**If capture exits `76` (duplicate gate):** the title strongly resembles an existing entity — do NOT retry blindly. Show the member the printed candidates and either update the existing note (`capture ... --merge-into <slug>`) or, only after they confirm it's genuinely distinct, re-run with `--force`.
|
||||
|
||||
Drop to the low-level verbs only for shapes `capture` doesn't model (a project `## Status` replace, an ADR mirror, a daily-note edit):
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ description: Bring the CHORUS vault up to the current feature spec (entity index
|
||||
allowed-tools: Bash(python3 *sweep.py*), Bash(python *sweep.py*), Bash(ls /sessions/*), Bash(dirname *)
|
||||
---
|
||||
|
||||
Use the **chorus-memory** skill to bring the vault up to the current spec. Run the sweep **dry-run first**, show the operator the plan, and only `--apply` on their go-ahead:
|
||||
Use the **chorus-memory** skill to bring the vault up to the current spec. Run the sweep **dry-run first**, show the member the plan, and only `--apply` on their go-ahead:
|
||||
|
||||
```bash
|
||||
SDIR="${CLAUDE_PLUGIN_ROOT}/skills/chorus-memory/scripts"
|
||||
|
||||
@@ -11,13 +11,13 @@ python3 "$CHORUS" triage --list --json
|
||||
# Windows: use `python` or `py -3` if `python3` is not on PATH.
|
||||
```
|
||||
|
||||
1. **List** — the JSON gives each capture as `{line, date, text, age_days}`. Surface the aging ones (≥ ~7 days) to the operator and ask which to route.
|
||||
2. **Propose** — for accepted items, write a proposals JSON with the Write tool (reflect schema: `{"title","kind","body",...}` **plus `"line"`: the original inbox line**, echoed into the audit log). Route per the map: preference/pattern → `semantic` (or a direct PATCH to `operator-preferences.md::Observations`); project idea → `project` with `--status incubating`; durable fact → `semantic`; person fact → `person`.
|
||||
3. **Preview, then apply** with the operator's go-ahead:
|
||||
1. **List** — the JSON gives each capture as `{line, date, text, age_days}`. Surface the aging ones (≥ ~7 days) to the member and ask which to route.
|
||||
2. **Propose** — for accepted items, write a proposals JSON with the Write tool (reflect schema: `{"title","kind","body",...}` **plus `"line"`: the original inbox line**, echoed into the audit log). Route per the map: preference/pattern → `semantic` (a preference about the capturing member goes to their own `_agent/members/<member>/preferences.md::Observations` via direct PATCH); project idea → `project` with `--status incubating`; durable fact → `semantic`; person fact → `person`.
|
||||
3. **Preview, then apply** with the member's go-ahead:
|
||||
|
||||
```bash
|
||||
python3 "$CHORUS" triage proposals.json # dry-run: classify + preview, writes nothing
|
||||
python3 "$CHORUS" triage proposals.json --apply # route via capture + log each move
|
||||
```
|
||||
|
||||
`--apply` records every move in `inbox/processing-log/YYYY-MM-DD.md` (`- <original> → <destination>`) automatically. Do **not** delete the original captures unless the operator explicitly asks — the processing log is the audit trail. A proposal that stops at the duplicate gate (exit note in the summary) should be re-proposed with the existing entity's title.
|
||||
`--apply` records every move in `inbox/processing-log/YYYY-MM-DD.md` (`- <original> → <destination>`) automatically. Do **not** delete the original captures unless the member explicitly asks — the processing log is the audit trail. A proposal that stops at the duplicate gate (exit note in the summary) should be re-proposed with the existing entity's title.
|
||||
|
||||
Reference in New Issue
Block a user