chore: interview before fixes and keep HANDOFF.md tiny
Queue Release Build / prepare (push) Successful in 1m3s
Deploy Web Apps / deploy (push) Successful in 12m28s
Queue Release Build / build-windows (push) Successful in 32m9s
Queue Release Build / build-linux (push) Successful in 54m12s
Queue Release Build / build-android (push) Successful in 21m27s
Queue Release Build / finalize (push) Successful in 5m11s

Require a short user interview before implementing bugs/features, and overwrite or clear HANDOFF.md so it never accumulates session history.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-22 21:49:06 +02:00
co-authored by Cursor
parent 34c32ba64a
commit d658ab0827
8 changed files with 104 additions and 39 deletions
+18 -5
View File
@@ -5,7 +5,13 @@ alwaysApply: true
# Handoff (token control) # Handoff (token control)
Agents **cannot** create a new Cursor chat. When a handoff is needed, write `agents-docs/HANDOFF.md` and tell the user to start a **new chat** with `@agents-docs/HANDOFF.md`. Agents **cannot** create a new Cursor chat. When a handoff is needed, **overwrite** `agents-docs/HANDOFF.md` and tell the user to start a **new chat** with `@agents-docs/HANDOFF.md`.
## File size rule (mandatory)
- **Never append** to `HANDOFF.md`. Always replace the entire file.
- One active handoff only — no history stack in this file.
- Keep sections short (bullets, paths, not log dumps).
## When to hand off ## When to hand off
@@ -13,12 +19,19 @@ Agents **cannot** create a new Cursor chat. When a handoff is needed, write `age
- Thread is long (many tool rounds, large pastes, repeated failed approaches) and more major work remains - Thread is long (many tool rounds, large pastes, repeated failed approaches) and more major work remains
- Switching to a clearly separate objective - Switching to a clearly separate objective
## What to do ## What to do (new handoff)
1. Overwrite `agents-docs/HANDOFF.md` — set `Status: active`; fill Goal, Completed, Changed files, Decisions, Failed approaches, Current issue, Next steps, Commands. 1. **Overwrite** `agents-docs/HANDOFF.md` completely — `Status: active`; fill Goal, Completed, Changed files, Decisions, Failed approaches, Current issue, Next steps, Commands (brief).
2. Stop major new work in this chat after writing the handoff (unless the user says continue here). 2. Stop major new work in this chat after writing the handoff (unless the user says continue here).
3. Tell the user the one-liner to paste in the new chat. 3. Tell the user the one-liner for the new chat.
## When the task is finished
After the user-approved work is done (or they abandon the handoff objective):
1. **Clear** `agents-docs/HANDOFF.md`: set `Status: none` and empty all section bodies (restore the short template — do not leave old Completed/Next steps lying around).
2. Do this in the same turn you claim done, so the next chat does not reload stale handoff context.
## New-chat bootstrap ## New-chat bootstrap
If `agents-docs/HANDOFF.md` has `Status: active`, read it first and continue Next steps. Do not reload the whole monorepo or redo Completed work. If `Status: active`, read the handoff first and continue Next steps. Do not reload the whole monorepo or redo Completed work. When that work is finished → **clear** the file as above.
+20
View File
@@ -0,0 +1,20 @@
---
description: Interview the user before implementing fixes; no guessing
alwaysApply: true
---
# Interview before implement
Before writing or changing product code for a bug/feature ask:
1. Read the ask (and the one Obsidian bug note if named). Do **not** start a large codebase rewrite yet.
2. Reply with a **short interview** (bullets only):
- What you think the bug/goal is (12 sentences)
- Whats missing / unclear
- Choices (A/B/C) with a **recommended** default
- Proposed scope (files/areas you will touch; what you will not)
- How you will prove done
3. **Stop and wait** for the users answers. Do not implement until they approve or choose.
4. Then implement exactly what they chose — no silent extra scope.
Skip the interview only when the user says e.g. “just fix it”, “no interview”, or the handoff already records approved Next steps/decisions and they said continue.
+19 -4
View File
@@ -6,14 +6,27 @@ Keep this file small. Detail lives in linked docs — load those **only when the
Agents **cannot** open a new Cursor chat. To reset context: Agents **cannot** open a new Cursor chat. To reset context:
1. Write/update `agents-docs/HANDOFF.md` (`Status: active`) — see `.cursor/rules/handoff.mdc`. 1. **Overwrite** `agents-docs/HANDOFF.md` entirely (`Status: active`) — never append. See `.cursor/rules/handoff.mdc`.
2. Ask the user to start a **new chat** and attach `@agents-docs/HANDOFF.md`. 2. Ask the user to start a **new chat** and attach `@agents-docs/HANDOFF.md`.
**At session start:** if `agents-docs/HANDOFF.md` has `Status: active`, read it first and continue Next steps. Do not redo Completed work. **At session start:** if `Status: active`, read it first and continue Next steps. Do not redo Completed work.
**When the task is finished:** clear the handoff — set `Status: none` and empty all sections (same short template). Never leave a growing archive in `HANDOFF.md`.
## Named Obsidian bugs ## Named Obsidian bugs
When the user says `fix bug "…"`, follow `agents-docs/BUG_TRACKER.md` § Named fix: open **that one** vault note under `Log/Bugs/`, use it as acceptance criteria, fix in default scope, then set `status: Resolved`. Do not scan the whole bug inbox. When the user says `fix bug "…"`, follow `agents-docs/BUG_TRACKER.md` § Named fix: open **that one** vault note, **interview before implementing**, then fix in default scope and set `status: Resolved`. Do not scan the whole bug inbox.
## Interview before implement (user in control)
Before changing product code for a bug or feature:
1. Read the ask / named bug note (cheap orientation only — not a monorepo dig).
2. Post a **short interview**: your understanding, gaps, A/B/C choices with a recommended default, proposed scope, how youll prove done.
3. **Wait** for the users choices. Do not guess past ambiguity.
4. Implement only what they approved.
Skip only if they say “just fix it” / “no interview”, or an active handoff already has approved decisions and they said continue. See `.cursor/rules/interview-before-fix.mdc`.
## Default work scope (token fence) ## Default work scope (token fence)
@@ -93,11 +106,13 @@ IPC/preload/WS contract changes → `agents-docs/features/<slug>.md` when that c
## Completion checklist ## Completion checklist
- [ ] Interview completed (or user opted out); implemented only approved choices
- [ ] Asked behavior proven (not only unit tests green) - [ ] Asked behavior proven (not only unit tests green)
- [ ] Stayed in scope (`toju-app` + targeted `electron` + CI) unless user expanded it - [ ] Stayed in scope (`toju-app` + targeted `electron` + CI) unless user expanded it
- [ ] Appropriate targeted tests for logic changes - [ ] Appropriate targeted tests for logic changes
- [ ] Lint via `npm run lint:fix` (not hand-fixed style); build only touched packages - [ ] Lint via `npm run lint:fix` (not hand-fixed style); build only touched packages
- [ ] Docs only if contracts changed - [ ] Docs only if contracts changed
- [ ] Lesson + index entry if corrected this session - [ ] Lesson + index entry if corrected this session
- [ ] If the thread is long and work remains: write `HANDOFF.md` and ask user for a new chat - [ ] If the thread is long and work remains: overwrite `HANDOFF.md` and ask user for a new chat
- [ ] If work from an active handoff is finished: clear `HANDOFF.md` to `Status: none` (empty sections)
- [ ] PR when requesting merge (`Fixes #<n>` / `Relates to #<n>`) - [ ] PR when requesting merge (`Fixes #<n>` / `Relates to #<n>`)
+25 -17
View File
@@ -17,50 +17,58 @@ Do **not** re-read this whole file every turn after the first skim.
## Workflow Orchestration ## Workflow Orchestration
### 1. Plan only when ambiguity is real ### 1. Interview before implement (default)
- Plan for unclear architecture or when the user asks. - For bugs/features: short interview first (understanding, gaps, choices + recommended default, scope, proof) — then wait. See `/AGENTS.md` and `.cursor/rules/interview-before-fix.mdc`.
- Skip plan mode for focused, in-scope edits with clear acceptance criteria. - Do not guess past ambiguity; the user controls the implementation choices.
- Skip only when the user opts out (“just fix it”) or an approved handoff already decided.
### 2. Subagents sparingly ### 2. Plan mode
- Use plan mode when architecture is unclear or the user asks — the interview often replaces a heavy plan for normal bug fixes.
- Skip long planning essays; prefer bullet choices.
### 3. Subagents sparingly
- Default: one agent. - Default: one agent.
- Subagents only for true parallel search inside allowed paths. - Subagents only for true parallel search inside allowed paths.
- Never spawn extra review agents unless the user asks. - Never spawn extra review agents unless the user asks.
### 3. Handoff / short sessions ### 4. Handoff / short sessions
Triggers: user says handoff / new chat; thread is long with more major work left; switching objectives. Triggers: user says handoff / new chat; thread is long with more major work left; switching objectives.
Action: overwrite `agents-docs/HANDOFF.md` with `Status: active` (Goal, Completed, Changed files, Decisions, Failed approaches, Current issue, Next steps, Commands). Then stop major work and ask the user to open a new chat. Action: **overwrite** (never append) `agents-docs/HANDOFF.md` with `Status: active` and short sections. Then stop major work and ask the user to open a new chat.
New chat: if handoff is active, read it first; continue Next steps; do not redo Completed work. New chat: if handoff is active, read it first; continue Next steps; do not redo Completed work. If Next steps still need choices, re-interview — dont invent them.
### 4. Self-Improvement Loop **When finished:** clear `HANDOFF.md` to `Status: none` with empty sections so the file stays tiny for the next session.
### 5. Self-Improvement Loop
**At session start:** `LESSONS-INDEX.md` only; open matching lesson bodies by tag. **At session start:** `LESSONS-INDEX.md` only; open matching lesson bodies by tag.
Record a lesson + index line when corrected. Prefer fewer sharp rules (~20). Record a lesson + index line when corrected. Prefer fewer sharp rules (~20).
### 5. CONTEXT.md upkeep ### 6. CONTEXT.md upkeep
Default: `toju-app/CONTEXT.md`. Read `electron/CONTEXT.md` only when touching Electron. Other packages only when in scope. Default: `toju-app/CONTEXT.md`. Read `electron/CONTEXT.md` only when touching Electron. Other packages only when in scope.
### 6. ADR upkeep ### 7. ADR upkeep
Only when hard-to-reverse + surprising + real trade-offs. Contract: `agents-docs/AGENTS_ADRS.md`. Only when hard-to-reverse + surprising + real trade-offs. Contract: `agents-docs/AGENTS_ADRS.md`.
### 7. Verification Before Done (behavior first) ### 8. Verification Before Done (behavior first)
Done = asked functionality works. Unit green ≠ done for product asks. Prefer in-scope proof; dont pull e2e/server “just to be sure.” Done = asked functionality works **as the user confirmed in the interview**. Unit green ≠ done for product asks.
### 8. Demand Elegance (Balanced) ### 9. Demand Elegance (Balanced)
One pause for non-trivial design; skip for obvious fixes. One pause for non-trivial design; skip for obvious fixes once the user has chosen a direction.
### 9. Autonomous Bug Fixing ### 10. Bug fixing (after interview)
Fix with evidence in default scope. If root cause is clearly `server/` (or similar), say so and ask to expand scope. Implement the approved plan with evidence in default scope. If root cause is clearly outside scope, say so and ask to expand — dont silently crawl.
--- ---
@@ -72,4 +80,4 @@ Gitea: `git.azaaxin.com/myxelium/Toju`. Branch `<type>/<short-description>`; PR
## Core Principles ## Core Principles
- **Simplicity First** · **No Laziness** · **Minimal Impact** · **Cheap Context** · **Default Scope Fence** · **Handoff Beats Fat Context** - **Simplicity First** · **No Laziness** · **Minimal Impact** · **Cheap Context** · **Default Scope Fence** · **Handoff Beats Fat Context** · **Interview Before Guessing**
+6 -5
View File
@@ -14,11 +14,12 @@ When the user says e.g. `fix bug "Images and files in chat doesn't load"`:
1. **Resolve one note** under `Log/Bugs/` whose title matches (usually `Bug - <title>.md`). Do not list or read the whole inbox. 1. **Resolve one note** under `Log/Bugs/` whose title matches (usually `Bug - <title>.md`). Do not list or read the whole inbox.
2. **Read that note** (Description, Steps, Expected/Actual, Logs). Read attachments only under that bugs attachment folder if referenced. 2. **Read that note** (Description, Steps, Expected/Actual, Logs). Read attachments only under that bugs attachment folder if referenced.
3. Acceptance criteria = the notes Expected Result (plus any clarifying line from the user). 3. **Interview before implement** (see `/AGENTS.md` and `.cursor/rules/interview-before-fix.mdc`): restate the bug, list gaps, present choices with a recommended default, propose scope and proof of done — then **wait** for the user. Do not start coding until they answer (unless they said “just fix it”).
4. **Fix in default repo scope** (`toju-app/` + targeted `electron/` + CI) per `AGENTS.md`. Do not crawl `server/` / `e2e/` / other packages unless the note or user clearly requires it — then ask once. 4. Acceptance criteria = the notes Expected Result **plus** the users interview answers.
5. Prove the asked behavior (not only unit-green). Prefer a regression that encodes the notes failure mode. 5. **Fix in default repo scope** (`toju-app/` + targeted `electron/` + CI) per `AGENTS.md`. Do not crawl `server/` / `e2e/` / other packages unless the note or user clearly requires it — then ask once.
6. When done: set that notes frontmatter `status` to `Resolved` (or `Closed` if the user prefers). Do not rewrite Description / Investigation / Resolution unless asked. 6. Prove the asked behavior (not only unit-green). Prefer a regression that encodes the notes failure mode.
7. Long thread + more work left → write `agents-docs/HANDOFF.md` and ask for a new chat. 7. When done: set that notes frontmatter `status` to `Resolved` (or `Closed` if the user prefers). Do not rewrite Description / Investigation / Resolution unless asked.
8. Long thread + more work left → write `agents-docs/HANDOFF.md` and ask for a new chat.
Do **not** re-read `BUG_TRACKER.md` every turn after the first use. Do **not** load the stale “open bugs” snapshot as truth — the vault files are source of truth. Do **not** re-read `BUG_TRACKER.md` every turn after the first use. Do **not** load the stale “open bugs” snapshot as truth — the vault files are source of truth.
+4 -4
View File
@@ -1,13 +1,13 @@
# Session Handoff # Session Handoff
> **New chat:** attach `@agents-docs/HANDOFF.md` (and only the files listed under Changed files). Say: continue from this handoff; do not redo completed work. Stay in default scope unless Next steps expand it. > **New chat:** attach `@agents-docs/HANDOFF.md` (and only files under Changed files). Say: continue from this handoff; do not redo completed work.
> >
> **Agents cannot open a new chat** — write/update this file, then ask the user to start one. > **Agents cannot open a new chat** — overwrite this file, then ask the user to start one.
>
> **Keep this file tiny:** always **overwrite** the whole file (never append). When the task is finished, **clear** back to `Status: none` and empty sections (see below).
**Status:** none **Status:** none
<!-- When Status is `active`, fill every section below. When done with a handoff cycle, set Status back to `none` or overwrite on the next handoff. -->
## Goal ## Goal
## Completed ## Completed
+2 -1
View File
@@ -53,7 +53,8 @@ Tags help grepping: `rg '\\[attachments\\]' agents-docs/LESSONS-INDEX.md`
- Use blob URLs for inline attachment previews — `[attachments] [electron]` - Use blob URLs for inline attachment previews — `[attachments] [electron]`
- Resolve Electron drag-and-drop file paths with webUtils — `[attachments] [electron]` - Resolve Electron drag-and-drop file paths with webUtils — `[attachments] [electron]`
- Preserve uploader local attachment paths across sync — `[attachments] [persistence]` - Preserve uploader local attachment paths across sync — `[attachments] [persistence]`
- Interview before coding; dont guess the fix — `[workflow] [bugs] [tokens]`
- Prove the asked behavior; unit-green is not done — `[verification] [testing] [workflow]` - Prove the asked behavior; unit-green is not done — `[verification] [testing] [workflow]`
- Default to `toju-app/` + targeted `electron/` + CI; do not crawl the monorepo — `[workflow] [tokens] [scope]` - Default to `toju-app/` + targeted `electron/` + CI; do not crawl the monorepo — `[workflow] [tokens] [scope]`
- Write HANDOFF.md and ask the user for a new chat — agents cannot open chats — `[workflow] [tokens] [handoff]` - Write/overwrite HANDOFF.md for new chats; clear it when the task finishes — `[workflow] [tokens] [handoff]`
+10 -3
View File
@@ -25,6 +25,13 @@ Durable rules for AI agents working on this project.
## Lessons ## Lessons
### Interview before coding; dont guess the fix [workflow] [bugs] [tokens]
- **Trigger:** about to edit product code for a bug/feature after reading the ask or Obsidian note, while acceptance, approach, or scope is still ambiguous or has real alternatives.
- **Rule:** send a short interview (understanding, gaps, A/B/C + recommended default, proposed scope, proof of done), wait for the users choices, then implement only that — skip only if they said “just fix it” / “no interview.”
- **Why:** unprompted guesses cause wrong fixes and expensive back-and-forth; one clarifying turn costs less than a wrong implementation thread.
- **Example:** `fix bug "Images and files in chat doesn't load"` → read the note → ask whether the failure is channel-switch blank vs cold reload vs both before touching attachment services.
### Default to `toju-app/` + targeted `electron/` + CI; do not crawl the monorepo [workflow] [tokens] [scope] ### Default to `toju-app/` + targeted `electron/` + CI; do not crawl the monorepo [workflow] [tokens] [scope]
- **Trigger:** about to browse all of `electron/`, or to `grep`/`Read` under `server/`, `e2e/`, `website/`, or `docs-site/` on a normal product bug without the user naming those packages. - **Trigger:** about to browse all of `electron/`, or to `grep`/`Read` under `server/`, `e2e/`, `website/`, or `docs-site/` on a normal product bug without the user naming those packages.
@@ -35,9 +42,9 @@ Durable rules for AI agents working on this project.
### Write HANDOFF.md and ask the user for a new chat — agents cannot open chats [workflow] [tokens] [handoff] ### Write HANDOFF.md and ask the user for a new chat — agents cannot open chats [workflow] [tokens] [handoff]
- **Trigger:** the thread is long, the user says "handoff"/"new chat", or a new major objective starts while more work remains. - **Trigger:** the thread is long, the user says "handoff"/"new chat", or a new major objective starts while more work remains.
- **Rule:** overwrite `agents-docs/HANDOFF.md` with `Status: active` and the eight sections, then ask the user to start a new chat attaching that file; never pretend you opened a fresh chat. - **Rule:** **overwrite** (never append) `agents-docs/HANDOFF.md` with `Status: active` and short sections, ask the user to start a new chat with that file; when the handoff task is finished, **clear** the file to `Status: none` with empty sections.
- **Why:** fat chat history dominates token burn on problem-solving models; a 510k handoff replaces 100k+ of mixed failure/tool output. - **Why:** fat chat history dominates token burn; an appending handoff file becomes a second fat archive that every new chat reloads.
- **Example:** user: "handoff" → write HANDOFF → reply: "Start a new chat and attach `@agents-docs/HANDOFF.md`; say continue from handoff." - **Example:** user: "handoff" → replace HANDOFF → reply: "Start a new chat and attach `@agents-docs/HANDOFF.md`." Later when done → reset HANDOFF to empty `Status: none`.
### Prove the asked behavior; unit-green is not done [verification] [testing] [workflow] ### Prove the asked behavior; unit-green is not done [verification] [testing] [workflow]