| 💾 Saved. d722711 k33g 3h ago | 1 | # History |
| 2 | |
| 3 | One entry per session, appended, never rewritten. |
| 4 | |
| 5 | ## 2026-09-15 — Diátaxis documentation bootstrap (agent "riker") |
| 6 | |
| 7 | - **Asked:** `/diataxis-doc` — start documenting the project, excluding `./kits` and `./tmp`. Ran in parallel with another agent adding `/new`. |
| 8 | - **Changed:** created `docs/` (language selector) with full four-quadrant trees in `docs/en/` and `docs/fr/`, identical file names: 1 tutorial, 4 how-to guides, 6 reference pages, 3 explanations per language, plus both indexes. Linked the `/new` how-to page and `docs/diagrams/packages.drawio` written by the other agent. No Go code touched. |
| 9 | - **Decisions:** language "Both" taken from the methodical-dev convention (user unavailable, skill's mandatory question skipped and recorded here). Shipped skill layout defect documented in how-to/reference rather than fixed. |
| 10 | - **Verified:** `go build` OK; banner output for both YAML files captured verbatim; `go test ./...` fails on `mm/internal/skills` (test points at `../../../demo/skills`). All relative links in `docs/` resolve. |
| 11 | - **Docs:** everything under `docs/`. Created `.memory/` skeleton. |
| 12 | |
| 13 | ## 2026-09-15 — `/new` slash command (terminal + ACP), quality gate set-up, first `.memory/` |
| 14 | |
| 15 | - **Goal**: add `/new` to the `mm` agent to clear the history and start a fresh session, in the terminal REPL and over ACP; exclude `./kits` and `./tmp` from the quality measurement. Run by agent "bob" via `methodical-dev`, autonomously (the user was not available for the skill's approval gates), while agent "riker" wrote the rest of `docs/` in parallel. |
| 16 | - **Changes**: new package `internal/session` (`NewCommand`, `NewCommandName`, `IsNewCommand`, `Fresh`, `Forgotten`) + tests; `detector.Reset()` + first tests for `internal/detector`; `internal/agent/agent.go` (`/new` handling, `startNewSession`, banner, `if/else` → `switch` for staticcheck QF1003, both front ends now start from `session.Fresh`); `internal/acp/acp.go` (`availableCommands`, `available_commands_update` in `NewSession`, `/new` interception in `Prompt`, `startNewSession`, `resetSession`) + tests; `main.go` package list comment; `.qlty/qlty.toml` (created); `.quality/` (2 runs); docs (below); `.memory/` created. |
| 17 | - **Decisions**: `/new` resets history + engine token count + loop detector (REPL); ACP keeps session id / cwd / allow-always; only `/new` advertised over ACP; notification sent inside `NewSession` before the response; the `session` import is aliased `history` inside `internal/acp` because that package already has a `session` type. Rejected: reusing `compactHistory`'s "keep the detector" rule for `/new` (different situation: the task changes); creating a git worktree (all files untracked); fixing the pre-existing `demo/skills` test path (layout decision for the user). |
| 18 | - **Tests**: `go test ./...` — all packages pass except the pre-existing `internal/skills` failure (`TestShippedSkillsHaveDescriptions`, path `../../../demo/skills`). `/new` smoke-tested end to end: piped REPL prints `🆕 new session: 0 message(s) forgotten`; scripted JSON-RPC client sees `available_commands_update` then the `session/new` response, and `/new` answered by an `agent_message_chunk` + `end_turn`. |
| 19 | - **Quality**: gate FAIL, 2 iterations: warnings 69 → 67, smells 18 → 18, complexity 620 → 618. Fixed: `ineffassign` in the new test, staticcheck QF1003 in `agent.go`. Remaining findings are all pre-existing (osv on `go.mod`, errcheck, complexity of `agent.Run` etc.) and out of this change's scope. Nothing was excluded beyond `kits/**` and `tmp/**`; no threshold changed. |
| 20 | - **Docs**: `docs/{en,fr}/how-to/start-a-new-session.md` (new); `/new` rows and ACP paragraphs in `docs/{en,fr}/reference/slash-commands.md` and `acp.md` (riker's pages, edited in place); links in both `README.md` indexes; `docs/diagrams/packages.drawio` (new, from `go list`) referenced from both `explanation/architecture.md`. |
| 21 | |
| 22 | ## 2026-09-15 — Zed config fix in the editor how-to (orchestrator) |
| 23 | |
| 24 | - **Asked**: the user reported that the Zed `agent_servers` snippet in the docs is insufficient — Zed requires `"type": "custom"` in the entry. |
| 25 | - **Changes**: added `"type": "custom"` to the JSON block in `docs/en/how-to/use-from-an-editor.md` and `docs/fr/how-to/use-from-an-editor.md`; recorded the requirement under "Decisions in force" in `summary.md`. |
| 26 | - **Tests / quality**: docs-only change, none run. |
| 27 | |
| 28 | ## 2026-09-15 — ACP: `/new` was invisible in Zed's slash menu (orchestrator) |
| 29 | |
| 30 | - **Asked**: the user reported that Zed lists commands for other ACP agents (docker agent) but shows "Available commands for mini-me: none" and rejects `/new` as unknown. |
| 31 | - **Cause**: `available_commands_update` was sent inside `NewSession`, i.e. before the SDK wrote the `session/new` response. Zed keys sessions on the id in that response and drops updates for an unknown session id. |
| 32 | - **Changes**: `internal/acp/acp.go` — `Run` now builds the front via `newFront(e, system, tools, w, r)`; the SDK writes to a `responseWriter` that runs a per-session hook once the response line carrying that session id has been written; `NewSession` registers the hook (`context.WithoutCancel(ctx)`, the request context dies with the method) instead of calling `SessionUpdate` directly. `acp_test.go` — `TestResponseSessionIDMatchesOnlySessionResponses`, `TestAvailableCommandsAreSentAfterTheSessionNewResponse` (drives the real SDK over pipes, reads the raw lines back). Docs: `available_commands_update` row in `docs/{en,fr}/reference/acp.md`; `summary.md` decision updated, the "Zed slash menu" unknown removed. |
| 33 | - **Rejected**: a goroutine with a `time.Sleep` after `NewSession` returns (a race, just an unlikely one); sending the list on the first `session/prompt` (too late for the menu before the first message). |
| 34 | - **Tests**: `go test -race ./internal/acp -count=5` ok; `go build` ok; real binary over stdin shows the response line before the notification line. |
| 35 | - **Not verified**: the menu in a real Zed (no Zed in the sandbox) — the user should retry. |
| 36 | |
| 37 | ## 2026-09-15 — ACP: `/compact` and `/abort` alongside `/new` (orchestrator) |
| 38 | |
| 39 | - **Asked**: the user confirmed `/new` now shows in Zed and asked for the same for `/compact` and `/abort`. |
| 40 | - **Changes**: `internal/acp/acp.go` — `compactCommand`/`abortCommand` constants, `isCommand`, three advertised commands, `/abort` intercepted in `Prompt` before `turnMu` (`abortTurn` → shared `cancelTurn`, also used by `Cancel`), `/compact` after `turnMu` (`compactSession` → `compactHistory(ctx, s, cfg, summarize, explain) (line, compressed)`, engine-free and testable). `internal/compact/compact.go` — `Result.Report()` plus `kilo`/`seconds` moved here from `internal/agent/agent.go`, which now prints `res.Report()`. Tests: `TestAvailableCommandsMatchWhatPromptIntercepts`, `TestIsCommandTrimsAndRequiresExactMatch`, `TestCompactHistoryOutcomes` (3 sub-tests), `TestCancelTurnFiresOnlyWhenATurnIsInFlight`; the wire-order test now compares against `availableCommands()`. Docs EN+FR: `reference/slash-commands.md` (ACP section became a table), `reference/acp.md` (`session/new` row, three `session/prompt` rows, commands table), `how-to/use-from-an-editor.md` (cancel + compress/restart bullets), `how-to/manage-the-context-window.md`. |
| 41 | - **Decisions**: `/quit` stays terminal-only; `/compact` over ACP is always forced (no automatic compaction exists in the ACP front end, unchanged); `/abort` answers `⚠️ No generation in progress.` when idle rather than erroring. Rejected: handling `/abort` under `turnMu` (it could never reach a running turn). |
| 42 | - **Tests**: `go test -race` on acp/compact ok; full `go test ./...` still fails only on the pre-existing `internal/skills` path test. Real binary driven by a small JSON-RPC client: commands list `new, compact, abort`; `/abort` idle → `⚠️ No generation in progress.`; ` /compact\n` on an empty history → `🗜️ nothing to compact: 1 message(s), no turn older than the last 3`; both `end_turn`. |
| 43 | - **Not verified**: `/abort` against a real running generation (no model server in the sandbox) and the two new entries in Zed's menu. |
| 44 | |
| 45 | ## 2026-09-15 — `mm` killed on the user's Mac (orchestrator, diagnosis only) |
| 46 | |
| 47 | - **Asked**: running `mm` on the Mac prints `[1] 55918 killed mm`. |
| 48 | - **Findings**: the repo's `./mm` is a Mach-O (magic `CF FA ED FE`), so the user rebuilt natively after the sandbox builds (the sandbox produced linux/arm64 ELF binaries at the same path in between — `mm` is gitignored, fine). SIGKILL of a freshly built Go binary on macOS is the invalid-signature kill; most likely cause is `install.sh` overwriting `/usr/local/bin/mm` IN PLACE with `cp` (the kernel keeps the old inode's signature cached → `Killed: 9`), possibly compounded by the repo living in a kDrive-synced folder. Not verifiable from the sandbox. |
| 49 | - **Proposed, not applied**: `sudo rm /usr/local/bin/mm && ./install.sh`; make `install.sh` remove the target (or use `install`) before copying; `codesign -vv /usr/local/bin/mm` to confirm. |
| 50 | |
| 51 | ## 2026-09-15 — "the agent does not see the skills" (orchestrator, diagnosis only) |
| 52 | |
| 53 | - **Cause confirmed in code**: `skills.List` globs `<skillsDir>/*.md` and `skills.Read` opens `<skillsDir>/<name>.md`, while the shipped skills live in `skills/<name>/SKILL.md` — so `skills: 0` and `read_skill` is never declared. Two aggravating factors: in terminal mode a relative `skillsDir` resolves against the current directory, and `agent.yaml` has been renamed `agent.dmr.yaml` by the user (no `./agent.yaml` → built-in defaults; a Zed `AGENT_CONFIG` still pointing to `agent.yaml` names a missing file, which `config.Load` treats as an error). |
| 54 | - **Proposed, not applied**: make `List`/`Read` accept both layouts (`*.md` and `*/SKILL.md`, name = directory), fix the test path `../../../demo/skills` → `../../skills`. |
| 55 | |
| 56 | ## 2026-09-15 — Skills layout fix, skillsDir resolution, `/abort` removed from ACP (orchestrator) |
| 57 | |
| 58 | - **Asked**: fix the skills loader; make an installed `mm` (`/usr/local/bin`) load the skills of the directory it is started from; drop `/abort` from ACP because Escape already cancels in Zed. |
| 59 | - **Changes**: `internal/skills/skills.go` — `List` globs both `<dir>/*.md` and `<dir>/*/SKILL.md`, `defaultName` uses the directory name for a `SKILL.md`, `Read` tries `<name>.md` then `<name>/SKILL.md` (flat wins); tests `TestListAcceptsFlatAndNestedLayouts`, `TestReadAcceptsFlatAndNestedLayouts`, shipped-skills test path → `../../skills`. `main.go` — `resolveSkillsDir(dir, configPath, acpMode)` makes a relative `skillsDir` absolute from the current directory (terminal, or ACP without config) or next to the config file (ACP with one); a `[warning: no skills found in <abs path> (expected <name>.md or <name>/SKILL.md there)]` line when the count is 0. `internal/acp/acp.go` — `/abort` handling, `abortTurn`, `cancelTurn` removed; `Cancel` back to its inline form; `availableCommands()` = `new`, `compact`; tests adjusted. Docs EN+FR: `how-to/add-a-skill.md`, `reference/skill-format.md`, `reference/tools.md`, `reference/configuration.md`, `reference/cli.md`, `how-to/use-from-an-editor.md`, `reference/slash-commands.md`, `reference/acp.md`. `summary.md`: known defects closed, skills decision added, ACP commands decision updated. |
| 60 | - **Decisions**: both layouts accepted rather than moving the shipped files (the `<name>/SKILL.md` form is the Agent Skills convention); flat file wins when both exist; the warning is printed whenever 0 skills are found, with the resolved absolute path, because "skills: 0" alone was the user's whole problem. |
| 61 | - **Tests**: `go test -race ./...` all green (first time `internal/skills` passes). Linux build to `/tmp/mm-linux` (NOT `./mm`, which is the user's Mach-O): from the repo root the banner lists `read_skill`; from `/tmp` it warns `no skills found in /tmp/skills`. |
| 62 | - **Not verified**: the Mac binary — the user must rebuild natively (`sudo rm /usr/local/bin/mm && ./install.sh`). |
| 63 | |
| 64 | ## 2026-09-15 — `@path` notation in questions (orchestrator) |
| 65 | |
| 66 | - **Asked**: mini-me must understand `@path/file` in a question, without a picker. |
| 67 | - **Changes**: new `internal/mention` (`Expand(input, cwd) (string, []Attachment)`, `Attachment.Line()`): mentions start the input or follow a space/bracket/quote, end at a space, lose trailing punctuation; resolved against cwd, absolute, or `~/`; only existing paths attach, once each, as `[attached file: …]` / `[attached directory: …]` lines appended to the text (same shape as ACP `resource_link`). Wired in `internal/agent/agent.go` (cwd captured once in `Run`; `📎 <abs>` dim line per attachment) and `internal/acp/acp.go` (after `flatten`, against `s.cwd`; `[acp] session <id>: attached <path>` on stderr). Tests: 4 in `mention_test.go`. Docs EN+FR: new `how-to/attach-a-file.md`, README indexes, `reference/slash-commands.md` (new `@path` section), `reference/acp.md` (prompt content row), `how-to/use-from-an-editor.md`, `explanation/architecture.md` package table, `docs/diagrams/packages.drawio` (node + edges from agent and acp). |
| 68 | - **Decisions**: keep the sentence as typed and append the marker lines rather than rewriting the `@` token (mirrors what Zed sends: text + resource_link); no inlining of content (bash-first agent reads it); paths with spaces unsupported (documented); non-existing paths silently left alone rather than warned (a `@handle` in a sentence is normal text). |
| 69 | - **Tests**: `go test -race ./...` all green. Linux build in `/tmp`: typing `explain @main.go and @internal, not @nothing.go` prints two `📎` lines and none for the missing path. |