Repository navigation
Needs attention: keep a list of what needs a person and notify on the Mac - #67
Merged
Merged
Conversation
The notify default, notify: false and a non-boolean notify are not handled yet, so three config tests fail. Issue: #58
notify turns the macOS notification of attention items on or off, on by default. Issue: #58
attention.ts does not exist yet, so the whole file fails to load. Issue: #58
Items are kept in attention.json, a new one posts one osascript notification with its text in argv, and the third erroring pass in a row raises pass-errors. Issue: #58
The fake world has an attention seam the pass does not use yet, so the six new tests fail. Issue: #58
…across a restart index.ts does not provide Attention or put it on the world yet, so these tests and the tests that run a pass fail. Issue: #58
Attention lines, stuck and needs-info runs raise items; a claim, a repo leaving the config and a finished run clear them. The live world is wired in the next commit. Issue: #58
The runtime provides Attention, raises a config item when the machine config does not load, clears it when it does, applies notify, and reports how each pass ended. Issue: #58
…notifying Fails: a claim whose launch ends stuck leaves the issue's earlier stuck item open beside the new one; a timed-out osascript is logged per item instead of once and every later item runs it again; the osascript run carries no termGraceMs. Issue: #58
…otifying A claim whose launch ends stuck now clears the issue's earlier items as a started claim does. A timed-out osascript turns notifying off until restart and is killed after a 1 s grace. A failed write or fsync of attention.json no longer leaves its temp file behind. Issue: #58
rawphp
marked this pull request as ready for review
October 16, 2026 06:57
Author
|
Factory gate: passed (attempt 1, run by the factory in a fresh checkout of the pull request's head
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #58
Contract
Attentionservice (apps/server/src/factory/attention.ts) keeps the open items (id, kind, repo, issue or none, run or none, message, first-seen) in<base>/factory/attention.json. Raised by: everyattentionevent the pass writes, a run that goesstuckorneeds-info, a machine config that fails to load, a pass that errors three times in a row. Cleared by: the issue being claimed again (a started claim, or one whose launch failed), a run-boundattentionitem whose run is no longer unfinished, the config loading, a pass that succeeds, the repo leaving the config. A new item posts one macOS notification throughprocess.ts(osascript -e <fixed script> <title> <message>,on run argv), never again while it stays open, also across a restart.notify: falsein the machine config keeps the list and posts nothing. A missing (exit 127) or hung (timed out)osascriptlogs once and stops trying.Attention.list()is a service method;FactoryLayernow providesAttentionnext toFactoryLoop.Attention.clear(matches)is the method those issues call. Click-to-open: not done. AppleScript'sdisplay notificationcarries no click action, so clicking the notification opens nothing for every item; the title namesrepo#issue(orfactory) and the item holds the issue number for Factory page in the T3 web app #28's page. A click-to-open needs a different notifier (e.g.terminal-notifier -open), which the issue'sosascriptcriterion rules out.vp test run apps/server/src/factory→ pass (34 files, 1156 tests, in the gate run)Settled by this run (not in the issue text)
error:lines or it died or timed out; it "succeeds" when its report has 0 errors. Thepass-errorsitem's message carries the last error line.stuckandneeds-infoitems stay until the issue is claimed again; they are about finished runs, so the end-of-pass "run no longer unfinished" clear applies only toattention-kind items.Acceptance criteria
Attentionservice with id, kind, repo, issue, run, message, first-seen —attention.test.ts"raise stores the item and list returns it";attention.tsattentionevent —pass.test.ts"an ATTENTION line raises an attention item whose message is the line"stuck/needs-info—pass.test.ts"a run that goes stuck raises a stuck item", "a run that goes needs-info raises a needs-info item"index.test.ts"an invalid machine config raises a config item and notifies once"attention.test.tspassEnded tests;index.test.ts"three failing passes raise pass-errors"stuck/needs-info(claimed again) —pass.test.ts"claiming an issue again clears every item of that issue and no other", "a claim whose launch fails clears the issue's earlier items and keeps the new one"attention.test.ts"clear by run removes the run's items and the file reflects it" (service method; wiring lands with the stop/abandon issues);pass.test.ts"a run-bound attention item whose run is no longer unfinished is cleared at the pass end"index.test.ts"a valid machine config clears the config item"attention.test.ts"a success clears pass-errors and resets the count"pass.test.ts"an item of a repo that is not in the machine config is cleared at the pass start; a machine item stays"factory—attention.test.tsargv test (a/b#7,factory)attention.json—attention.test.ts"a second service over the same dir lists the item and raising it again posts nothing";index.test.tsrestart testosascript display notification; seeoutprocess.ts, text as argv (on run argv), never in the source; quotes, backslashes and" & do shell script "—attention.test.ts"the text goes to osascript as argv and never into the script"notify: falseturns the notification off and keeps the list —config.test.tsnotify tests;attention.test.ts"setNotify(false) posts nothing";index.test.tsnotify-false testosascriptlogs once, does not fail the pass —attention.test.tsexit-127 test; timed-out testAttention.list()is a service method —attention.ts;index.tsfactoryRuntimemerges the layerGate
factory/scripts/check.sh→ exit 0 (.factory/gate-1.log: seam check, 34 test files / 1156 tests,t3typecheck,@t3tools/webtypecheck)Models
Review
85a781742: 12 mutants, 12 killedassert.include(..., "a")inattention.test.ts; a no-matchclearassertion that cannot distinguish an early return; theindex.test.tspass-errors loop leans on a 30 s boundNotes for the factory
e4bcce9f6, behindorigin/main; it was fast-forwarded toff23fa2fdat Isolate before any read (ancestor, clean tree).factory:*labels already existed on the repo.factory/SEAMSuntouched. The boundary test passes (attention.tsimports only factory-internal paths andeffect).5ecaffef9adds fail againstb7c59a509's product code and pass at the tip. The makers reported red for the other three pairs.Lessons
A lookup that
cds elsewhere moves the session's shell. Symptom: the next command's relative paths fail with "No such file" and the harness reports the working directory is no longer a worktree. Cause: a one-offcd /tmp && gh api ...in a shell whose working directory persists between calls. Default: nevercdout of the worktree, even for a read of another repo; prefix every command withcd <worktree> &&and give other tools absolute paths.A red check in a pnpm monorepo runs in a detached worktree with symlinked
node_modules. Symptom: a detached worktree at atest:commit cannot run vitest (no modules), andvp ithere costs minutes. Default:git worktree add --detach .factory/red <test sha>,git checkout <parent> -- <product files>, symlink the root, app andpackages/*/node_modulesfrom the main worktree, run the filtered test files, thengit worktree remove --forceandprune. Extends lesson 16 to JS.In a fork,
gh pr createwithout--repoopens the PR on the parent repository. Symptom: the draft lands on the upstream project (herepingdotgg/t3code) and has to be closed with an apology. Cause:ghresolves the default repo to a fork's parent whenoriginis a fork. Default: always pass--repo <owner/repo>(the issue's repo) and--head <branch>togh pr create, and check the printed URL's owner before reportingFACTORY-DONE.Commits
10955d104test: the machine config has a notify key— Make slice 1 (red)8b3ea13f9feat: the machine config has a notify key— Make slice 13dbdaffcatest: the Attention service keeps open items and notifies once— Make slice 2 (red)6c39b22e3feat: an Attention service keeps open items and notifies once— Make slice 2a6f544d1btest: the pass raises and clears attention items— Make slice 3 (red)3fcce22fffeat: the pass raises and clears attention items— Make slice 307100e7b7test: the runtime raises config and pass-errors items and keeps them across a restart— Make slice 4 (red)b7c59a509feat: the factory runtime raises config and pass-errors items— Make slice 45ecaffef9test: a failed launch clears earlier items and a hung notifier stops notifying— Check cycle 1 (red)85a781742fix: a failed launch clears earlier items and a hung notifier stops notifying— Check cycle 1Files
attention.json, osascript notifier, pass-error countPassWorld.attentionFakeworld's attention recorder and the raise/clear testsAttentionlayer merged intofactoryRuntime; config item raise/clear;setNotify;passEndedon every pass exitnotify(optional boolean, default true)notifyparse tests