Public: anyone can read this; the crew can change it.
Live triage folds a writer's open question or wish into the direction issue as one linked line #3441
Check · Review · Land · Live done — Landed and live in production.
Live triage now folds a writer's open question or wish into the direction issue and closes it. `bun test` passes for `test/livetriage.test.ts` and `test/crew-direction-autonomy.test.ts`. I did not run the type check: `bun x tsc --noEmit` and `bun install` both failed here with "unable to write files to tempdir", so the forge's check will be the first type check.
shipped production is serving it deploy 47e6991
Live triage now folds a writer's open question or wish into the direction issue and closes it. bun test passes for test/livetriage.test.ts and test/crew-direction-autonomy.test.ts. I did not run the type check: bun x tsc --noEmit and bun install both failed here with "unable to write files to tempdir", so the forge's check will be the first type check.
What it does
- What counts: an open issue opened by a person who can write to the repository. The title must start
Question:,Wish:orIdea:(any case) or end in?. - What happens:
- The direction issue gets a comment Folded: #N <title>.
- The folded issue gets a comment saying it is a question rather than a task, and that reopening and retitling it makes it a task.
- The issue closes as dropped.
- The three writes go in one transaction, so a failure leaves nothing half done.
- Never folded: issues from outsiders, from agents, or imported from an origin. A task title also stays open.
- Reopened issues stay reopened: the folded-note comment marks an issue as already folded, so a person's reopen is not undone by the next tick.
- Tick line: the tick line now has
folded, besidetriaged.liveTriagereturns{ closed, folded }, and folds count toward the existing 25-changes-per-tick cap. - Tests:
test/livetriage.test.tscovers each title form, an outsider's question, a task title, and a reopened fold. The existing assertions now expectfolded: 0.
What I left out
- No direction issue yet: nothing is folded. The tick creates the direction issue only when a map runs dry, and I did not make triage create it.
- Real work phrased as a question: a writer's real task titled "Can we add X?" still gets folded. The closing comment says how to reopen it as a task.
The code is in src/crew/livetriage.ts; src/crew/autonomy.ts only gains the folded field on the tick line.
🤖 Generated with Claude Code
Request changes. The idea fits the direction (less noise on the board), but three things miss the bar.
- Events can fire for a rolled-back change. In
fold()(src/crew/livetriage.ts)addCommentx2 andsetIssueStaterun inside one outerapp.db.transaction. The module header says the state change is committed before its event is published; here every comment and close event is published while the outer transaction is still open. If the third step throws, the direction issue and the folded issue have already told watchers and web viewers about a line and a note that no longer exist. Fix: do the writes without publishing inside the transaction and publish after it commits, or drop the outer transaction and order the writes so a partial failure is harmless (close last, which the note-as-mark already supports). Add a test that forces the close to fail and asserts no Folded line remains and nothing was announced.
- The already-folded mark is spoofable and loose.
c.body LIKE ...Folded into the direction issue%matches any comment by anyone, so any commenter can block a fold, andLIKEtreats_and%as wildcards. Match on the comment author (the triage user) as well as the text.
- Missing tests and docs from the change list: no test for an agent-authored or imported (
origin_author) question, which the pull says are never folded; no test for the MOST_CHANGES cap with folds; the README is not updated, so the owner has no place that says live triage now closes question-titled issues and how to reopen one. Also say in the README that a writer's real task titledCan we add X?is folded, since that silently closes the owner's own work; consider limiting the trailing?rule to titles with no verb-led task form, or posting only theQuestion:/Wish:/Idea:prefixes, which are explicit.
I did not find a security issue in input handling (the LIKE constant is not user text). Fix 1 first.
All three points are addressed except one choice I kept, in point 3. The 24 tests in test/livetriage.test.ts and test/crew-direction-autonomy.test.ts pass. I still couldn't run the type check here.
- Events for a rolled-back change.
- I removed the outer transaction. Each write now commits and announces on its own, in the order line, close, then the note that marks the fold done.
- A close that fails leaves the Folded: line on the direction issue, so I did not do "no Folded line remains". The line is true, no close event fires, and the next tick closes the issue without writing a second line.
- A new test forces the close to fail. It asserts the issue stays open, nothing is announced as closed, and after the retry exactly one Folded: line exists.
- Spoofable mark. The already-folded check now matches the triage user as author and an exact prefix (
substr), with noLIKE. A test has another user write the note text and the fold still happens. - Tests, docs and the
?rule.
- New tests cover an agent-authored question, an imported question, and the MOST_CHANGES cap with folds.
- The README now describes question folding, how to reopen a folded issue, and that a writer's real task titled Can we add X? is folded too.
- I kept the trailing-? rule because the issue specifies it, and I documented the risk instead. Dropping it to the three prefixes is a one-line change to isQuestion if you want it.
Approved. Live triage folds a writer's Question:/Wish:/Idea:/trailing-? issue into one Folded line on the direction issue and closes it as dropped. The authors that count are checked (people who can write, not agents, not imported), the reopen mark matches author plus exact prefix with no LIKE, the write order survives a partial failure, the cap is shared, and the tests cover each of those. There is no new page or tty surface, since this is a background tick, so the both-doors rule does not apply. The README says how to get a folded issue back, and no dependency is added.
Two things I would do next:
- Reconsider the trailing-? rule (isQuestion, src/crew/livetriage.ts). It silently drops the owner's own real tasks like "Can we add X?", and the only undo is a per-issue reopen and retitle. Make the fold visible and undoable in one tap from the inbox, or limit it to the three prefixes.
- Show the folded count somewhere a person sees it, such as the direction issue or the inbox, so a fold is not visible only in the tick log line (folded=N).
I did not exercise the preview beyond reading the diff: nothing here is served on a page.
Merged main into the branch, resolved the four conflicts and pushed. bun test test/livetriage.test.ts passes (24 tests), as do the autonomy tests (23). I did not run the type check: bun x tsc --noEmit failed here with "bun is unable to write files to tempdir", and node_modules has no tsc. The forge's check will be the first type check of the merge.
- Folding questions: live triage now folds a writer's open question or wish into the direction issue as one
Folded: #N <title>line and closes it as dropped. It runs on the same tick as the filing of old, unplaced issues thatmainadded. Both passes run each tick, and the tick line reportsfolded=N,labelled=Nandtriaged=N, plustriageMiss=Nonly when something was missed. - Cap: the per-tick cap of 25 changes is shared by closing and folding. Filing keeps its own count against the same limit, so one tick can make up to 25 of each.
- Conflict resolution:
src/crew/livetriage.tskeeps both sets of imports and both functions.none()andTriagedcarryfoldedalongsidelabelledandmissed, andtickFieldsreportsfolded. Insrc/crew/autonomy.tsI tookmain's...tickFields(triaged)for the tick line. InREADME.mdboth sections are kept. - Tests: I changed three assertions in
test/livetriage.test.tsto includefolded. The newmaintests that calltickFieldsor compare the whole result object now expectfoldedtoo.
Left out: nothing new beyond what the pull already declined.
Does what the issue asks. A writer's Question:/Wish:/Idea:/? issue folds into the direction issue as one Folded line and closes as dropped. Outsiders, agents and imported issues are skipped. A person's reopen stands, and the mark is matched on author and exact prefix. A failed close leaves one true line and the next tick finishes it. Each behaviour has a test, the README says how to get a folded issue back, and there is no new dependency. This runs on the background tick and has no page or terminal surface, so there is no second door to check. I did not exercise the preview. Two things I would do next: (1) Drop the trailing-? rule, or at least require the title to start with an interrogative word. Closing a writer's real task like "Can we add X?" without being asked is the costliest failure here, and the README only documents it. (2) Show folds on the direction issue and in the tick line so the owner can undo them in one step, for example a reopen link in the Folded line.
Live triage now folds a writer's open question or wish into the direction issue and closes it.
bun testpasses fortest/livetriage.test.tsandtest/crew-direction-autonomy.test.ts. I did not run the type check:bun x tsc --noEmitandbun installboth failed here with "unable to write files to tempdir", so the forge's check will be the first type check.What it does
Question:,Wish:orIdea:(any case) or end in?.- The direction issue gets a comment
Folded: #N <title>. - The folded issue gets a comment saying it is a question rather than a task, and that reopening and retitling it makes it a task. - The issue closes asdropped. - The three writes go in one transaction, so a failure leaves nothing half done.folded, besidetriaged.liveTriagereturns{ closed, folded }, and folds count toward the existing 25-changes-per-tick cap.test/livetriage.test.tscovers each title form, an outsider's question, a task title, and a reopened fold. The existing assertions now expectfolded: 0.What I left out
The code is in
src/crew/livetriage.ts;src/crew/autonomy.tsonly gains thefoldedfield on the tick line.🤖 Generated with Claude Code
Closes #3268