aboutsummaryrefslogtreecommitdiff
path: root/todo.org
diff options
context:
space:
mode:
Diffstat (limited to 'todo.org')
-rw-r--r--todo.org273
1 files changed, 273 insertions, 0 deletions
diff --git a/todo.org b/todo.org
index 6750eed..3213a6f 100644
--- a/todo.org
+++ b/todo.org
@@ -179,6 +179,242 @@ The gate already exists and is nearly right. =scripts/lint.sh='s =check_md_links
Found by the adversarial reviewer on the =references/= fix, 2026-07-28, as the sibling class the original report missed.
+*** 2026-08-04 Tue @ 09:51:13 -0500 Independently confirmed by work's link sweep
+Work swept all 533 tracked org files in their project (sentry cycle, 2026-08-03)
+and landed on the same defect from the opposite direction — a consuming project
+finding the dead targets rather than rulesets predicting them. Their table
+matches this task site for site: task-review ×3 plus one to =docs/design/=,
+task-audit ×1, open-tasks ×1, suspend ×1.
+
+Two things the confirmation adds. They checked =inbox.org=:97's
+=[[file:working/<slug>/proposed.diff]]= and correctly excluded it — that one is
+a template placeholder inside an example block, so the fix must not sweep it up.
+And they independently proposed the same fix direction I'd filed, plus an
+absolute =~/code/rulesets/...= target as an alternative to prose. I'd still
+prefer prose: an absolute path resolves in both trees but bakes a machine layout
+into a file that ships everywhere.
+
+Nothing to change in the plan; this raises confidence that the seven sites are
+the whole set.
+
+** TODO [#B] Teardown has no live-sibling gate :bug:
+:PROPERTIES:
+:LAST_REVIEWED: 2026-08-04
+:END:
+Wrap-up's teardown mode kills the =aiv-<project>= tmux session without checking
+whether another agent is living in it. Archsetup hit this on 2026-08-04: two
+primaries in one project, two windows in one tmux session, and teardown would
+have taken both. They caught it by reading the pane layout before dropping the
+sentinel and aborted the wrap by hand.
+
+Shutdown mode already has exactly this guard — it gates on
+=cj/ai-term-live-count= and =wrap-it-up.org= calls that gate "the load-bearing
+safety of the whole feature." Teardown, twenty lines away, has nothing. Verified
+in the canonical: Step 6's teardown branch drops =/tmp/ai-wrap-teardown-<project>=
+unconditionally.
+
+Grading: Critical severity (kills another agent's live session and its
+in-progress work — the anchor survives, but anything unwritten does not) ×
+rare edge case (needs two primaries in one project) = P2 = =[#B]=.
+
+Fix direction, and archsetup's own suggestion is the better one: gate on the
+pane count of *this* project's session (=tmux list-panes -t aiv-<project>=)
+rather than reusing the machine-wide =cj/ai-term-live-count=. Live-count is
+global, so reusing it would abort a legitimate teardown whenever any unrelated
+project had a session up. The narrow check also keeps the fix inside rulesets —
+no =.emacs.d= handoff needed, unlike anything routed through =ai-term.el=.
+
+Add the check in both places, because the window between them is real: at
+sentinel-drop (where the decision is made and can be reported in the
+valediction) and again in the hook before it consumes the sentinel (a sibling
+can arrive in between). The hook already re-verifies the clean-tree certificate,
+so it has the shape for a second gate.
+
+Not =:solo:= — the verification that matters is a live two-session drill in
+Craig's terminal, and a fix that passes bats while still killing a real sibling
+is exactly the failure mode here.
+
+Source: inbox/2026-08-04-0023-from-archsetup-addendum-to-today-s-agent-anchor.org
+
+** TODO [#B] Agent-scoped session anchor as the default :spec:
+:PROPERTIES:
+:LAST_REVIEWED: 2026-08-04
+:END:
+Archsetup proposes that =.ai/session-context.d/<id>.org= become the path
+always, rather than the =AI_AGENT_ID=-set special case. Their argument is that
+the unset case is also the common case: every agent wants an anchor that is
+its own, and the single-agent situation is just the one with no contention yet.
+Defaulting to the directory removes the race by construction.
+
+The collision that prompted it was real. Two archsetup sessions both resolved
+to =.ai/session-context.org= and interleaved their logs; nothing was lost, but
+only because the second one noticed and appended rather than writing. At wrap
+they had to hand-split the file to avoid archiving the sibling's in-progress
+record along with their own.
+
+The obstacle is protocols.org's invariant: =session-context-path= is called
+many times per session and must return the same path every time, so it must
+never mint an id itself. Archsetup lists three ways out — derive from something
+already stable, let the resolver mint once and persist, or make every launcher
+set =AI_AGENT_ID= — and leans on the third. I don't think the third can work:
+a bare =claude= is always available, protocols.org already concedes it runs
+full primary startup regardless, and their own collision was two bare
+invocations.
+
+There's a fourth option they didn't list, and I think it beats all three:
+=$TMUX_PANE= is exported into the agent's Bash environment and is stable across
+calls (measured =%19= on two separate invocations, 2026-08-04). A resolver that
+falls back to the pane id when =AI_AGENT_ID= is unset stays a *pure function of
+the environment* — no minting, no state file, no clearing rule — which is
+exactly the invariant the three listed options each have to bargain with.
+
+What to check before committing to it: pane ids are unique per tmux server but
+reset when the server restarts, so the collision moves rather than vanishing
+(narrower, since an old anchor is archived at wrap). And an agent outside tmux
+has no =$TMUX_PANE= at all, so the fallback needs its own fallback — possibly
+the controlling terminal, possibly the current unscoped path.
+
+Also decide in the same pass: the absence of =.ai/session-context.org= is
+currently the signal that the last session wrapped cleanly, and both startup and
+wrap-up key on it. Moving to a directory turns that into "is the directory
+empty," and both call sites have to change together or a crashed session stops
+being detectable.
+
+Their second proposal — a startup roster check so a bare invocation learns a
+sibling is live — is already scoped in the helper-agent task ("Startup
+detection-first: the roster check runs before Phase A.0's pulls"), so it belongs
+there rather than here. Worth sequencing: the roster check surfaces the
+collision, this removes it.
+
+Source: inbox/2026-08-03-1443-from-archsetup-proposal-from-a-concrete-collision-in.org
+
+** TODO [#C] Installing into a repo Craig doesn't own has no mode :bug:
+:PROPERTIES:
+:LAST_REVIEWED: 2026-08-05
+:END:
+=todo.org= is in neither installer's exclude set, so it lands untracked-but-unignored
+in a collaborator's repo and shows up in their =git status=. Home hit this
+installing into ratowsky. Verified: =install-ai.sh='s gitignore block and
+=sweep-gitignore-tooling.sh='s =IGNORE_SET= both carry =.ai/=, =.claude/=,
+=CLAUDE.md= and =AGENTS.md=, and nothing else. The workflows expect =todo.org= at
+the project root, so any project running them grows one.
+
+Adding =todo.org= to both sets fixes the symptom. The gap underneath is bigger,
+and it's the part worth designing: *a repo Craig doesn't own is a third mode the
+installer doesn't model.* Both current modes assume the repo is his. Track mode
+commits the tooling; gitignore mode appends the set to =.gitignore=, which in
+someone else's repo commits his personal policy into their tracked file. That is
+the same defect one layer up from the one reported, and it ships today for every
+collaborator install that picks gitignore mode.
+
+The right mechanism there is =.git/info/exclude=, which is local, untracked, and
+invisible to the repo's owner. Ratowsky already worked around it exactly that
+way, for both =todo.org= and the rest of the personal layer, which is good
+evidence the third mode is what the situation actually wants rather than a
+generalization from one case.
+
+So the fix has two halves: add =todo.org= to the exclude set, and give
+=install-ai.sh= a collaborator mode that writes the whole set to
+=.git/info/exclude= instead of =.gitignore=. Worth checking on the way whether
+=inbox/=, =working/= and =temp/= want the same treatment there — the installer
+creates =inbox/= unconditionally in both modes.
+
+Grading: Minor severity (a personal task file surfaces in a colleague's
+=git status=, and an accidental =git add= commits it; nothing breaks and nothing
+is lost) × some users sometimes (collaborator-repo installs only) = P3 = =[#C]=.
+
+Not =:solo:= — the third mode needs a call on how the installer detects or is
+told that a repo isn't Craig's, and that's a design decision rather than a
+mechanical fix.
+
+Source: inbox/2026-08-05-1418-from-home-installer-gap-found-installing-ai-into.org
+
+** TODO [#C] install-lang ignores tooling a track-mode project tracks :bug:solo:
+:PROPERTIES:
+:LAST_REVIEWED: 2026-08-04
+:END:
+Every language bundle's =gitignore-add.txt= opens with the same unconditional
+block — =.claude/=, =CLAUDE.md=, =githooks/= — which =install-lang.sh= appends
+to the target's =.gitignore=. In a track-mode project those three lines assert
+the opposite of the project's actual policy. Work hit it installing the python
+bundle into a project that tracks both =CLAUDE.md= and =githooks/pre-commit=.
+
+Verified across the whole set: bash, elisp, go, python and typescript all carry
+the identical header block, so this is not python-specific. The build-artifact
+entries below it (=*.pyc=, =htmlcov/=, =node_modules/=, =*.elc= …) are correct
+unconditionally — only the tooling header is mode-dependent.
+
+Nothing breaks today, which is why it went unnoticed: git keeps honoring a path
+that is already tracked. The failure is latent and quiet — a *new* file added
+under =githooks/= goes untracked with no warning, so a hook that should travel
+to the other daily driver silently doesn't. And the =.gitignore= now
+misrepresents the project's own policy to whoever reads it next.
+
+Grading: Major severity (a new hook or rules file silently untracked, and
+nothing signals it — the change just fails to reach the other machine) × some
+users sometimes (a track-mode project installing a language bundle) = P3 =
+=[#C]=.
+
+Fix, specified so it needs no design call: split =gitignore-add.txt= into the
+tooling header and the build-artifact body, and append the header only in
+gitignore mode. The mode detection already exists — =scripts/sweep-gitignore-tooling.sh=
+recognizes both the anchored (=/.ai/=) and unanchored (=.ai/=) ignore styles for
+exactly this purpose; reuse its predicate rather than writing a second one that
+can disagree with it. Track mode gets the build-artifact body alone, plus a
+comment saying why the tooling entries were omitted, so a later install isn't
+read as having forgotten them.
+
+Done when: all five bundles split, the predicate shared with the sweep script
+rather than duplicated, bats covering both modes against both ignore styles, and
+=make test= green.
+
+Smaller thing from the same report, worth doing in the same pass: =install-lang=
+seeds =coverage-makefile.txt= at the project root unconditionally, so a project
+with no suite for those targets gets a stray fragment. Either gate the seed or
+say in the file what it's for.
+
+Source: inbox/2026-08-02-2210-from-work-install-lang-mis-ignores-a-track-mode.org
+
+** TODO [#C] Stop hook blocks on a step its workflow may not carry :bug:quick:solo:
+:PROPERTIES:
+:LAST_REVIEWED: 2026-08-04
+:END:
+The wrap teardown hook blocked a wrap in website because that project's synced
+=wrap-it-up.org= predated the =git-worktree-gate certify= step the hook enforces.
+The block message told them to rerun the final wrap verification, which doesn't
+point at the fix, so diagnosing it meant reading the hook's source.
+
+The underlying asymmetry is real: the hook reaches a project as a =~/.claude=
+symlink from =make install=, which startup runs unconditionally in Phase A.0,
+while the workflow that drives it arrives by the *guarded* rsync in Phase A. The
+two halves of one feature can move independently, and nothing signals the skew
+until the hook fires.
+
+Partly overtaken by events, and the report says so honestly without knowing it:
+the per-path sync narrowing (=f69dc22=) landed four minutes before that handoff
+was written. The specific cause named — one dirty =sentry.org= withholding all
+three rsyncs — can't happen now. What survives is the general case: a workflow
+withheld for its *own* dirt, or a project branch behind upstream (that guard is
+still all-or-nothing), still runs old against a new hook.
+
+Grading: Minor severity (a blocked wrap with a misdirecting message; the
+sentinel survives, running the gate by hand clears it, nothing is lost) × some
+users sometimes = P3 = =[#C]=.
+
+Fix, and take only the first half: make the hook's block message name the
+command (=git-worktree-gate certify=) rather than describing a workflow step.
+That is correct whatever version of the workflow the project holds, which is
+precisely the property the skew breaks — a message that names the *step* is
+another thing that can drift, while a message that names the *command* can't.
+
+The report's second suggestion — startup warns when a rulesets-owned hook is
+newer than the project's synced copy of the workflow that drives it — is a
+version-skew detector, and a real idea, but it needs a hook-to-workflow mapping
+that nothing maintains today. Leaving it here as a note rather than filing it:
+if the message fix doesn't stop the class, that's the escalation.
+
+Source: inbox/2026-07-31-2247-from-website-drift-report-from-website-s-wrap-up.org
+
** TODO [#C] start-work Phase 7 still summarizes the old publish flow :chore:solo:
:PROPERTIES:
:LAST_REVIEWED: 2026-07-28
@@ -484,6 +720,27 @@ Both found 2026-07-23 reading =claude-templates/bin/agent-text= and =scripts/sig
Grading: Minor severity for both (one is a latent hang in a tool with a documented fallback, the other a warning on an account nothing currently depends on) x most users, frequently (the stale warning is a standing condition on this host; the hang needs a stall) = P3 = [#C].
** TODO Manual testing and validation
+*** Telegram scan — no spurious 404 after the loadChats callback fix
+What we're verifying: passing =#'ignore= to =telega--loadChats= stops the two
+=Telega error 404: Not Found= lines each Telegram scan printed into the echo area
+and =*Messages*=, without changing what the scan reads. The fix is code-verified
+against telega 20260706.2147 but has never been run — it needs a live telega, so
+it can't be checked from an agent session.
+- Clear the decks so the count is unambiguous.
+#+begin_src emacs-lisp
+(with-current-buffer "*Messages*" (let ((inhibit-read-only t)) (erase-buffer)))
+#+end_src
+- Run a Telegram triage scan (the =triage-intake= telegram source).
+- Check what the chat table holds and whether the noise reappeared.
+#+begin_src emacs-lisp
+(list :chats (hash-table-count telega--chats)
+ :errors (with-current-buffer "*Messages*"
+ (how-many "Telega error 404" (point-min) (point-max))))
+#+end_src
+Expected: =:chats= is populated as before (non-zero, matching what a scan used to
+report) and =:errors= is 0. Before the fix this reliably printed two per scan, so
+a non-zero count means the callback isn't being consumed and the fix is wrong.
+
*** Sentry — entry gates fire with Craig present
What we're verifying: the interactive entry gates stop for the right states and start the loop only on a clean, green baseline.
- On rulesets (ratio), with a clean tree and green suite, say "start sentry hourly".
@@ -599,6 +856,22 @@ From the roam inbox (2026-07-11): work in progress in one project shouldn't stop
:END:
The 2026-07-01 kb-hygiene report listed 42 agent KB nodes with no inbound id: links (of 53 agent nodes; 0 conflicts, no duplicate titles). Orphan-ness alone isn't a defect — agent nodes are found by rg, not only by links — but a periodic pass is worth doing: prune nodes that aged out, merge near-duplicates, add id: links where clusters exist. Regenerate the list with the kb-hygiene script rather than trusting the snapshot. Propose deletions/merges to Craig before applying (auto-cleanup allowed only for :agent:-tagged nodes after approval, per knowledge-base.md).
+*** 2026-08-04 Tue @ 09:51:13 -0500 Fresh hygiene report — orphans 42 → 113
+The 2026-08-01 report: 124 agent nodes, 625 total KB org files, 0 conflicts, no
+duplicate titles, and 113 orphans. So orphans grew 2.7× in a month while agent
+nodes roughly doubled — nearly every node written since 2026-07-01 landed
+unlinked.
+
+That reframes the task. At 42 this was a cleanup backlog; at 113, with the ratio
+holding at about nine in ten, the backlog is a symptom and the write path is the
+cause. Nodes are being written without =[[id:]]= links to their neighbours, so
+pruning the list would leave the same list regrowing. Worth folding into the
+pass: does =knowledge-base.md='s write block ask for the links firmly enough,
+and would a node-write prompt to name one related node close it at the source?
+
+Grading unchanged at =[#C]= — orphan-ness still isn't a defect on its own, and
+=rg= still finds these nodes. The number is a signal, not a failure.
+
** TODO [#B] Helper-agent instance support — concurrent same-project Claude :feature:spec:
:PROPERTIES:
:CREATED: [2026-06-11 Thu]