---
{
  "n": 7,
  "title": "Suggestions - the agent proposes a change, the user accepts, adjusts or declines",
  "abstract": "Combined design report from three research agents: what a suggestion is, its lifecycle, how the agent learns to file one and hears the decision, and how it is built on the questions pattern",
  "refs": [],
  "seen": [
    "agent",
    "user"
  ],
  "data": {},
  "created": 1789341717.0,
  "updated": 1789750266.975414,
  "deleted": 0.0,
  "completed": 0.0,
  "outcome": "",
  "type": "doc"
}
---
Combined from three research reports (2026-09-14): what a suggestion is and its lifecycle; the agent side; how it fits the code. What they agree on is written as the design. Where they disagree, a question has been filed for the user.

## What a suggestion is
A suggestion is the agent's own proposal of a change nobody asked for, waiting on the user's decision. Nothing is blocked while it waits.

| resource | started by | waits on | is |
|---|---|---|---|
| to-do | the user asked (or said later) | nothing | a commitment |
| question | the agent | an answer it needs to go on | a gap |
| message | the user | the agent processing it | a request coming in |
| pin / rule | ruled or found | nothing | a fact |
| suggestion | the agent, unasked | the user's decision | a proposal |

The test, in order: did the user ask for it (a to-do); does the work need an answer first (a question); would the project be better if the user said yes, with nothing blocked if they never answer (a suggestion); is it simply true (a pin, or nothing).

## Lifecycle
- **open**: filed by the agent. Title is the change in one line; the brief says what was seen, what it costs now and later.
- **accepted**: the user accepts. A to-do is filed at once from the title and brief, linked both ways (`became: todo:N` on the suggestion, `suggestion` on the to-do). Accepting is not permission to start: auto mode decides that, as for any to-do.
- **adjusted**: the user changes it. The original text is kept, the user's change is stored, and the to-do is filed from the adjusted version.
- **declined**: with an optional reason. A decline is a ruling: the agent does not file it again in other words.
- **withdrawn**: by the agent, with a reason, when it stopped being worth it or was fixed another way.

Nothing is deleted. The status is derived from the fields, as `Question.status` is.

## Scope, links, noise
- Per environment, like questions and messages. Links reuse the questions ref parser (`todo 12`, `doc 4.1`, `pin 3`, `rule 2`), and `suggestion N` becomes a ref questions, comments and messages can cite.
- At most 5 undecided suggestions per environment (`suggestion_max_open`); a sixth is refused with the list.
- `add` compares the title and links against declined suggestions; a close match is refused, showing the decline and its reason, unless `--despite=<n> --because="<what changed>"` is given.
- Age never retires one. A suggestion whose linked to-do closed or linked file is gone shows up in `journal cleanup`.

## The agent side
- A SKILL.md section "Suggestions: propose, and let the user decide" (drafted in the agent-side report): file it, don't say it; a suggestion never changes the work in hand; a decline is a ruling. The line "it might be nice to refactor this is a message with a tag" changes to point at suggestions.
- The session start shows one line: `suggestions: N waiting on the user`, so every session knows the channel exists.
- A new stop subject `suggestions` at priority 46, after questions (45) and before work (50): "the user decided suggestion 3 — accepted, to-do 12 filed / declined: <why>". Uses `untold`/`mark_told` like questions.
- Guardrails: filing a suggestion does not satisfy the deferral gate (only a to-do does); `accept`, `adjust` and `decline` are the user's verbs (viewer or terminal), refused when the agent runs them; subagents cannot file suggestions.

## Build (the questions pattern)
- `suggestions.py` (entries.Store, per environment), `Suggestion` model and `Suggestions` repository, `payloads/suggestions.py`, `controllers/suggestions.py` with actions index, show, store, update, link, unlink, accept, adjust, decline, destroy (withdraw). Routes come free from the generic router once the controller is registered.
- CLI: `suggestions add "<change>" --brief [--about=<ref>]...`, `suggestions`, `show`, `link`, `unlink`, `withdraw`, and the user's `accept`, `adjust`, `decline`.
- Viewer: a Suggestions page like Questions, with groups open, accepted, adjusted, declined, withdrawn; a sidebar entry with the open count; Accept, Adjust and Decline in the panel; comments (to-do 66) in the panel once they exist.
- Tests: a new `test_suggestions.py` modeled on `test_questions.py`, plus route coverage in `test_serve.py` and repository coverage in `test_resources.py`.
- Size: close to questions end to end, roughly 900–1100 lines. Split into three to-dos: the resource and its decision flow, the viewer, and teaching the agent.

## Open for the user
1. Do suggestions replace the `ideas` list, or does `ideas` stay as the user's own scratch list? The reports split on this.
2. Should a hook hint when the agent's reply proposes a change ("we could…", "it would be better to…") and nothing was filed? One report says yes, as a hint once per reply that goes quiet after three ignored; the other says no, because the deferral detector already reads replies and a second one teaches the agent to skim.

## Needs from comments (to-do 66)
Comments must accept `suggestion N` as what they are about, and the agent must be able to reply to a comment. A comment is not a decision: "sounds good" does not accept a suggestion.
