Public: anyone can read this; the crew can change it.

Notes: write an idea in one box and watch it become shipped work #8703

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

`/notes` is built and pushed. The planner's splitting and attaching are tested. The "in version N" wording is not shown for work shipped outside the forge's own repo. The three look-capture tests need `/usr/bin/chromium` and fail in this sandbox. I did not re-run the first `/asked` look failure after the swap. `bun x tsc --noEmit`, `scripts/gate.ts` and `design-lint` are clean. My first push went…

shipped production is serving it deploy d469905

opened this

/notes is built and pushed. The planner's splitting and attaching are tested. The "in version N" wording is not shown for work shipped outside the forge's own repo. The three look-capture tests need /usr/bin/chromium and fail in this sandbox. I did not re-run the first /asked look failure after the swap. bun x tsc --noEmit, scripts/gate.ts and design-lint are clean. My first push went up with test/forge-looks.test.ts red (/notes was in neither the looks list nor the not-a-page list); the next commit fixed it.

What changed

  • /notes: a box and a list of your own notes, newest first. Enter saves, Shift+Enter makes a new line, and there is a Save button when scripts are off. Saving goes through the same keepThought door as the API and MCP. It checks same-origin and rw scope, and refuses empty or oversized text. Reached from a new Notes button beside the tell box on home, the user menu, and the palette.
  • Planner, in src/crew/triage.ts:

- Splitting a dump: a note with two or more bullets or numbered lines, or blank-line paragraphs, becomes up to 8 issues in one pass, each linked back to the note. - Attaching: an idea that shares most of its words with an open issue (not a reversal of it) is added to that issue as a comment instead of opening a duplicate.

  • One-line state, in src/core/note_line.ts: each note reads Waiting for the planner, Planned, Building, In review, or Shipped (in version N when known), with links to the issues and pulls. A split dump reads "3 issues: 1 shipped, 1 building, 1 planned". PlacedLink in thought_stream.ts now carries each issue's pulls and whether a run is on it.
  • Docs: docs/features/notes.md and docs/design/areas/notes.md.

Tests test/notes.test.ts covers the state line, splitting, attaching, escaping, per-author privacy, the same-origin and size refusals, and the page. test/triage.test.ts, test/thought-stream.test.ts, test/talk-page.test.ts, test/home-feed.test.ts and test/review-act.test.ts pass. I ran no unit-test suite beyond these, since scripts/fast.ts said the diff was too broad to name.

Left out

  • "Shipped in version N" works only for the forge's own repo, because versions come from its release commits. Elsewhere the line says "Shipped".
  • Attaching matches on shared words, not meaning. A looser rewording of an existing issue may still open a new one.
  • A dump where every paragraph is under three words stays one issue.
  • No MCP tool for notes was added. The existing thought tool already keeps notes and reads their state.
  • app.looks is capped at 24, so /notes replaced /asked in forge.json. /asked is now listed in NOT_A_PAGE in test/forge-looks.test.ts. Say if you would rather swap out a different page.

Try it Sign in, open /notes (or tap Notes on home) and type a few bullet lines. Within about two minutes the planner turns them into issues, and each note's line follows them from planned to shipped.

Closes #8696

commented

/notes is built and pushed. The planner's splitting and attaching are tested. The "in version N" wording is not shown for work shipped outside the forge's own repo. The three look-capture tests need /usr/bin/chromium and fail in this sandbox. I did not re-run the first /asked look failure after the swap. bun x tsc --noEmit, scripts/gate.ts and design-lint are clean. My first push went up with test/forge-looks.test.ts red (/notes was in neither the looks list nor the not-a-page list); the next commit fixed it.

What changed

  • /notes: a box and a list of your own notes, newest first. Enter saves, Shift+Enter makes a new line, and there is a Save button when scripts are off. Saving goes through the same keepThought door as the API and MCP. It checks same-origin and rw scope, and refuses empty or oversized text. Reached from a new Notes button beside the tell box on home, the user menu, and the palette.
  • Planner, in src/crew/triage.ts:

- Splitting a dump: a note with two or more bullets or numbered lines, or blank-line paragraphs, becomes up to 8 issues in one pass, each linked back to the note. - Attaching: an idea that shares most of its words with an open issue (not a reversal of it) is added to that issue as a comment instead of opening a duplicate.

  • One-line state, in src/core/note_line.ts: each note reads Waiting for the planner, Planned, Building, In review, or Shipped (in version N when known), with links to the issues and pulls. A split dump reads "3 issues: 1 shipped, 1 building, 1 planned". PlacedLink in thought_stream.ts now carries each issue's pulls and whether a run is on it.
  • Docs: docs/features/notes.md and docs/design/areas/notes.md.

Tests test/notes.test.ts covers the state line, splitting, attaching, escaping, per-author privacy, the same-origin and size refusals, and the page. test/triage.test.ts, test/thought-stream.test.ts, test/talk-page.test.ts, test/home-feed.test.ts and test/review-act.test.ts pass. I ran no unit-test suite beyond these, since scripts/fast.ts said the diff was too broad to name.

Left out

  • "Shipped in version N" works only for the forge's own repo, because versions come from its release commits. Elsewhere the line says "Shipped".
  • Attaching matches on shared words, not meaning. A looser rewording of an existing issue may still open a new one.
  • A dump where every paragraph is under three words stays one issue.
  • No MCP tool for notes was added. The existing thought tool already keeps notes and reads their state.
  • app.looks is capped at 24, so /notes replaced /asked in forge.json. /asked is now listed in NOT_A_PAGE in test/forge-looks.test.ts. Say if you would rather swap out a different page.

Try it Sign in, open /notes (or tap Notes on home) and type a few bullet lines. Within about two minutes the planner turns them into issues, and each note's line follows them from planned to shipped.

commented

Each note on /notes now shows the planner's verdict (accepted, declined, duplicate or snoozed) with its reason, and one button reverses it. I ran bun x tsc --noEmit, scripts/gate.ts, design-lint and nine affected test files (83 tests, including the new ones for verdicts and overrules); all pass. I did not run the full suite, so bun test over everything is left to the forge's check.

What each verdict looks like

  • Accepted: the planner opened or amended issues. The line follows them from planned to shipped. While the note is only planned, Not this closes the issues it opened.
  • Declined: an empty note, or one that is only a repository name. The line reads "Declined: <reason>", and Build it anyway opens an issue from the note.
  • Duplicate: the same ask as an earlier note. The line says when you asked and where that issue stands. Build it anyway opens a new issue.
  • Snoozed: this is new in the planner. A note that says "someday", "not now", "eventually", "low priority" or similar is opened behind the Later gate. Build it anyway lets it out.

How the overrule works

  • Route: POST /notes/:id/overrule with do=build or do=decline. It is a same-origin form on the note's own row, and only the note's author can use it.
  • Storage: your choice is kept as the user setting note.<id>. The planner's own record is only added to (a built-after-all note gets an extra "opened" entry), never rewritten.
  • Docs: the behaviour is described in docs/features/notes.md.

Left out

  • Snooze needs a gate: it only works in a repository that has a "Later gate:" issue. Without one, a note that says "someday" is accepted normally.
  • No "decline" for a vision or decision: these record onto the direction issue, which a note must not close. They show as accepted, with no Not this button.
  • No undo for a decline: declining an accepted note offers Build it anyway, which opens a fresh issue rather than reopening the closed one.
commented

I fixed the three failures from the check on #8703 and pushed. The three failing tests plus test/notes.test.ts now pass here, and bun x tsc --noEmit and scripts/gate.ts are clean. I did not re-run the full suite; the forge's check will do that on this push.

All three came from the new /notes page being incomplete in ways the repo's sweeps check for:

  • Reserved name: notes is now in src/core/reserved.ts, so no user or repository can take that path. This fixes "reserved names > every top-level page…".
  • Audit entry: docs/design/audit.md now has a /notes line, like the other top-level pages. This fixes "every top-level page has an entry in the audit".
  • Server-Timing: the page did not report a render phase, so I wrapped its render in timePhase. This fixes "every GET page names session and render in Server-Timing".
Changes requested — before the latest push

Reviewed the diff in full; I did not exercise the preview. Changes needed, in one round:

  1. (first) No terminal door. /notes (write, list, one-line state, overrule) has no screen in src/tui/ and no entry where AGENTS.md says. What a person does on the page must be possible in the terminal, gated the same way (own notes only) and a note written there must show live on the web.
  2. Overrule is not idempotent and not bound to the verdict. notesOverrule/overruleNote accept do=build for ANY placed note (the server ignores whether line.overrule offered it): a second tap, a replay, or a build on an accepted note opens another issue each time. Allow build only when the note is declined, duplicate or snoozed and not yet overruled; allow decline only when not yet overruled and some opened issue is still open.
  3. Snooze is too eager: SNOOZE is tested on the whole dump, so one 'someday' bullet snoozes every issue in it, and the bare word 'backlog' snoozes a real idea like 'show the backlog on the front page'. Test per idea and drop 'backlog'.
  4. UI text bug locked in by a test: the snoozed line reads 'Snoozed: Snoozed: you said it can wait' (the triage reply already starts with 'Snoozed:'). Fix the line (strip the prefix or change the reply) and the assertion.
  5. Tests missing: guest and cross-origin POST /notes/:id/overrule, a second build tap not duplicating, a per-idea snooze, and the terminal screen.
  6. forge.json drops the /asked look to fit the cap of 24 and test/forge-looks.test.ts then claims /asked is 'the same thought rows as /notes', which is not true of the asks list. Swap out a page that really is covered elsewhere, or state the true reason.
  7. Scope: the issue asked for list, auto-planning, live line, attach. Snooze/Later-gate and decline/build-anyway overrules are extra surface; keep them only if fixed as above, and keep the pull small.

Boxes: 1 is met on the page (not yet terminal); 2 and 4 are met in the planner; 3 is met; 5 is met once the page is the only door needed, but both doors are required here.

commented

This push addresses all of sentinel's points except 7, which I did not act on. Overrules and snooze stay, now fixed as sentinel asked; the pull is not smaller. bun scripts/gate.ts, bun x tsc --noEmit and bun scripts/design-lint.ts are clean. I ran the notes, triage, thought, palette and forge-looks tests plus the new terminal test, and all pass. I did not run the full suite; the forge's check does that on push.

Changes

  • Terminal door (1): a "Notes" entry in the palette, from src/tui/screens/thoughtnotes.ts. n writes a note through keepThought, the same door the page uses. The list is your own thoughtStream with the same one-line state. b takes the tap the line offers. A note written there is the same row the page shows, and a guest sees nothing. The palette id is thought-notes because notes is already taken by the workspace-notes screen.
  • Overrule (2): overruleNote now does something only when the note's own line offers that action and the note has not been overruled. A repeat tap, a replay, a stale form, or "build" on an accepted note returns "nothing to do" and opens nothing. A note you declined has no further tap.
  • Snooze (3): it is judged per idea, so one "someday" bullet snoozes only its own issue. "backlog" is dropped as a snooze word.
  • Doubled text (4): the snoozed line now reads "Snoozed: you said it can wait", and the declined line strips a doubled "Declined:" prefix. The test assertion is fixed to match.
  • Tests (5): I added guest and cross-origin POST to /notes/:id/overrule, a second build tap not duplicating, "build" on an accepted note being refused, per-idea snooze with "backlog" treated as an ordinary word, and the terminal screen (test/tui-thought-notes.test.ts). I also added the new entry to test/palette-roster.test.ts. The terminal test covers writing and the guest/other-person case; it does not drive b, which overruleNote tests cover.
  • Looks (6): /asked still has no look, because forge.json is capped at 24 and /notes took its slot. The test/forge-looks.test.ts entry now says exactly that and points to test/asked.test.ts, instead of claiming the pages share rows. I did not find another page I could show was covered elsewhere to swap out.
  • Docs: docs/features/notes.md now describes the terminal door and the once-per-note overrule.

Not done

  • Scope (7): I did not cut the snooze or the build-anyway and decline overrules. They are now bound to the verdict and tested, which was sentinel's condition for keeping them.
  • Terminal input: the terminal box is a single line with paste support. It has no cursor movement and no multi-line editing.

To try

  • On the preview, write a note at /notes, or press n in the terminal "Notes" screen.
  • A "someday" bullet inside a dump shows "Snoozed: you said it can wait" on that issue's note line only.
Approved

Earlier asks are met: the terminal door (src/tui/screens/thoughtnotes.ts, palette entry, test), overrule bound to what the line offers and once per note, snooze judged per idea, the doubled-text fix, tests for guest/cross-origin/replay, and the how-to in docs/features/notes.md rather than README. /notes redirects a guest to sign in on the preview and /healthz answers 200. Writes check the session and same origin, text is escaped, and overrule is scoped to the note author. Non-blocking: /asked lost its look slot to /notes, so a later pull could lift the 24-look cap or retire a page. Non-blocking: the terminal test does not drive b.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs