diff options
Diffstat (limited to '.ai')
| -rw-r--r-- | .ai/notes.org | 2 | ||||
| -rw-r--r-- | .ai/sessions/2026-08-05-18-49-inbox-batch-quiet-form-and-anchor-scope.org | 319 | ||||
| -rw-r--r-- | .ai/workflows/sentry.org | 4 |
3 files changed, 324 insertions, 1 deletions
diff --git a/.ai/notes.org b/.ai/notes.org index b6c85f8..be6708c 100644 --- a/.ai/notes.org +++ b/.ai/notes.org @@ -85,6 +85,6 @@ Format: Markers maintained by workflows to record when they last ran. Read by other workflows that gate their behavior on freshness. :LAST_AUDIT: 2026-07-20 (open set current — this session's shipped work (working/temp, triage-source-activation, silent-until-signal, suspend detach) closed as it went; sentry cluster consolidated (merged the /schedule tasks, added cross-host-coordination); nothing shipped-but-open per git reconcile. Live finding: the Polyglot + Subprojects scouting tasks are SCHEDULED 2026-07-20 and due.) -:LAST_INBOX_PROCESS: 2026-07-31 (four work handoffs: standup-scripts proposal accepted with four changes and shipped as a212eeb; voice pattern #48 filed [#B], then its interaction.md mirror folded in on Craig's approval; a correction FYI acknowledged — my project-workflows fork claim was wrong, Phase 11 composes rather than shadows) +:LAST_INBOX_PROCESS: 2026-08-04 (ten handoffs, batch-approved: four implemented — signature paths, lint-org anchor scope, gmail pagination floor, telega 404 callback; two folded — work's link sweep as independent confirmation, KB orphans 42 → 113; four filed — [#B] teardown live-sibling gate, [#B] agent-scoped anchor default, [#C] install-lang track-mode ignores, [#C] hook message names a step not a command; all four senders replied to) Format: one =:MARKER: YYYY-MM-DD= line per workflow. Workflows overwrite their own marker on completion. diff --git a/.ai/sessions/2026-08-05-18-49-inbox-batch-quiet-form-and-anchor-scope.org b/.ai/sessions/2026-08-05-18-49-inbox-batch-quiet-form-and-anchor-scope.org new file mode 100644 index 0000000..f0a5399 --- /dev/null +++ b/.ai/sessions/2026-08-05-18-49-inbox-batch-quiet-form-and-anchor-scope.org @@ -0,0 +1,319 @@ +#+TITLE: Session Context — 2026-08-04 +#+AUTHOR: Craig Jennings +#+DATE: 2026-08-04 + +* Summary + +** Active Goal + +Startup found nine handoffs waiting and three more arrived during the session. +The whole session became one long inbox pass: evaluate twelve items across five +senders, verify every checkable claim against the source rather than the report, +and ship or file each one. + +** Decisions + +- *Verify before grading, every time.* Every report that made a factual claim + got checked against the source first. All of them held, which is the argument + for continuing rather than for stopping — the checks were cheap and the one + thing they'd have caught is the expensive one. +- *File wider than reported when the report points at something bigger.* Home + asked for =todo.org= in the installer's exclude set. The real gap is that a + repo Craig doesn't own is a third mode the installer doesn't model, since + gitignore mode commits his personal policy into someone else's tracked file. +- *Five commits, not one bundle*, because the fixes were independent and a + bundled =chore:= would have buried two behavior changes among doc edits. +- *Craig lifted the Agent-tool restriction* where the standing rules call for + dispatch, settling a conflict that had surfaced three times in two sessions. +- *Zero-tolerance on em-dashes applies to new prose even in files carrying 65 of + them*, because the profile calls the rule chosen self-discipline rather than a + reflection of his habit. That makes the existing ones the pre-rule habit the + rule corrects, not a house style to match. +- *Don't hold work that doesn't depend on the answer.* Home's item was filed + identically under every option offered, so it shipped without waiting. + +** Data Collected / Findings + +*The first dispatched review returned Request Changes with four blocking +findings, none of which I'd have caught myself.* The worst was a straight +contradiction: my new quiet-output rule told agents to let exit codes carry a +pass, while =verification.md= says read the whole output before claiming one. +Both load into every session, and the obvious targets ("tests pass", "linter is +clean") are the two commands =verification.md= names. A stale carve-out would +also have told agents to run the sentry walk inline, defeating the change +entirely. + +*The reviewer then caught me describing a fix I hadn't made* — I called finding +7 "compressed to a clause" when it was already a clause. Its judgment that the +gap mattered more than the finding is right, and it's the whole argument for +continuing the same reviewer rather than spawning a fresh one. + +*Verified against source, not taken on trust:* the signature paths really are +dead and the marks moved to =~/pictures/signature/=; =lo--spec-file-p= scopes +five checkers, not the four its docstring claimed; all five language bundles +carry the identical unconditional tooling block; teardown really has no +live-sibling gate where shutdown mode calls that gate load-bearing; every step +of =.emacs.d='s telega chain holds against telega 20260706.2147; =agent-lock= is +name-keyed and mkdir-atomic. + +*=$TMUX_PANE= is stable across an agent's Bash calls* (=%19= twice this +session). That's a fourth option archsetup's anchor proposal didn't list, and it +beats all three of theirs by keeping the resolver a pure function of its +environment. + +*The website report was overtaken by events* — the sync narrowing landed four +minutes before it was written. + +*The lint fix is confirmed working downstream.* Work replied at 18:37 that all +three synced files arrived on their evening template sync, and that their live +session anchor now lints =mechanical=0 judgment=0= against 14 judgment items +that morning, 12 of them the =level-2-dated-header= false positive. That is the +end-to-end verification I couldn't run from here, measured in the project that +reported the bug. + +They also closed the one thing I asked of them: the sentry arming prompt is +typed at =/loop= time rather than stored in a file, so there was nothing to +patch, and the correction went into their local memory instead. They kept the +verification-exemption half of that memory deliberately rather than pruning it, +on the grounds that it's the half most likely to be read past. + +*Orphan KB nodes went 42 → 113 while agent nodes doubled*, so nearly every node +written since 2026-07-01 landed unlinked. That reframes the orphan task from a +cleanup backlog into a write-path problem. + +** Files Modified + +Seven commits, all pushed. + +- =fc1a519= =lint-org.el= + tests — the anchor scope fix, suite 77 → 82. +- =7637a97= =triage-intake.telegram.org= — =#'ignore= on both =loadChats= calls. +- =57dae70= =triage-intake.personal-gmail.org= — the date-slice floor. +- =771c669= =protocols.org= — signature section rewritten to a three-row table. +- =91ac5a1= =todo.org= — four filings from the batch. +- =cf9910d= =todo.org= — the collaborator-repo installer gap. +- =588fbf6= =interaction.md=, =subagents.md=, =sentry.org= — quiet output plus + the Output-Destination Override. + +KB: promoted 2 / consulted yes + +** Next Steps + +1. *Craig's two standing reminders are both still open* and both need his + decisions rather than execution: the context-engineering rightsizing (four + decisions, docs one commit behind) and the sentry spec deep read, now three + weeks old. +2. *The teardown live-sibling gate =[#B]=* is the sharpest thing filed tonight — + it would have killed a running session. Needs a real two-session drill, so + it's not =:solo:=. +3. *The agent-anchor default =[#B]=* now carries the =$TMUX_PANE= option; decide + between it and archsetup's three before building. +4. *The inbox Stop hook fired three times* on an item that was mid-disposition, + where protocols.org says it should step aside on re-entry. Worth checking + whether the soft-nudge is behaving as designed. +5. Twenty-nine tasks remain unreviewed past a week. + +* Session Log + +** 00:30 — Startup + +Ran the startup workflow. Phase A.0: rulesets already current, =make install= +had nothing new to link, project repo clean and up to date. Phase A: templates +synced cleanly, no session-context anchor from a prior session (last wrap was +clean), language bundle silent, spec-sort and host-identity probes silent. + +Findings to carry: 29 top-level tasks unreviewed for >7 days, 3 items in the +roam global inbox, and nine new handoffs in =inbox/= since the 2026-07-31 +process marker — one from website, one KB hygiene report, four from work, two +from archsetup. + +** 00:45 — Inbox pass: evaluation + +Ran the value gate and skeptical review over all nine handoffs, verifying every +checkable claim against the source rather than taking the reports at face value. +All four verifications confirmed the senders: + +- The signature paths in =protocols.org= really are dead; dotfiles moved the + marks to =~/pictures/signature/= and added an initials stamp the section + never mentions. +- =lo--spec-file-p= scopes out the todo-format family for =/docs/specs/= only, + and a session anchor has the same property by instruction (=protocols.org= + line 120 prescribes the dated =** = log heading). Its docstring says four + checkers; the call site excludes five. +- All five language bundles append the same unconditional tooling block + (=.claude/=, =CLAUDE.md=, =githooks/=) in =gitignore-add.txt=, so the + track-mode defect work hit is not python-specific. +- Teardown mode really has no live-sibling gate: shutdown mode gates on + =cj/ai-term-live-count= and calls it "the load-bearing safety of the whole + feature," while teardown drops its sentinel unguarded and the hook then kills + the whole =aiv-<project>= tmux session, windows and all. + +One thing I found that archsetup's anchor proposal missed: =$TMUX_PANE= is +exported into the agent's Bash environment and stable across calls (=%19= on +two separate invocations this session). That is a fourth option they did not +list, and it beats all three of theirs — the resolver stays a pure function of +the environment, with no minting and no state file. + +The website report is partly overtaken by events: the per-path sync narrowing +(=f69dc22=) landed four minutes before that handoff was written, so the specific +root cause it names — one dirty =sentry.org= blocking all three rsyncs — no +longer holds. The asymmetry it describes does. + +A tenth handoff arrived from =.emacs.d= at 00:31, mid-evaluation, proposing a +one-line fix for a repeating telega 404. Craig approved the batch as +recommended. + +** Inbox pass: applied + +(Note on times: =date= read 00:30 at startup and 09:51 an hour of work later, so +the machine's clock moved under this session. Timestamps below are what =date= +returned when the entry was written; the earlier headings keep what it returned +then. Not chased — flagging it so the sequence doesn't read as garbled.) + +Four implemented, two folded, four filed. + +*Implemented.* =protocols.org='s Signature Image section now points at +=~/pictures/signature/= as a three-row table and names the README that carries +the sizing guidance — the old prose named two paths that no longer exist. I +described the stow source as "Craig's dotfiles repo" rather than the specific +path work quoted: the doc had already rotted once by pinning +=~/code/archsetup/dotfiles/=, and the marks now resolve through =~/.dotfiles/=. +The personal-gmail plugin's date-slice recipe is now labelled a floor rather +than a complete read, with home's 250-vs-291 measurement and the rule for which +uses can tolerate it. The telegram plugin passes =#'ignore= to both =loadChats= +calls, with the quick reference updated in the same pass so the two can't drift. + +=lint-org.el='s =lo--spec-file-p= became =lo--todo-format-exempt-p=, widened to +cover the live anchor, per-agent anchors, and the =.ai/sessions/= archives. +Work flagged honestly that they'd measured only =level-2-dated-header= and were +inferring the rest; the composite test I wrote red answered it — the other four +do fire on an anchor. The archives were mine to add: same file, same shape, +later in its life, and sentry lints them. Suite went 77 → 82. + +*Folded.* Work's link sweep into the existing =../../= links bug as independent +confirmation from the consuming side — same seven sites, and they correctly +excluded the =inbox.org= template placeholder, which the fix must not sweep up. +The KB hygiene report into the orphan-review task, where the number reframes it: +orphans went 42 → 113 while agent nodes doubled, so nearly every node written +since 2026-07-01 landed unlinked. That makes the backlog a symptom of the write +path rather than a cleanup queue. + +*Filed.* =[#B]= teardown's missing live-sibling gate (the most serious — it +would have killed a running session), =[#B]= the agent-scoped anchor default, +=[#C]= install-lang's unconditional tooling ignores, =[#C]= the hook message +that names a step instead of a command. + +** Shipped as five commits, pushed + +=fc1a519= the lint-org scope fix, =7637a97= the telega callback, =57dae70= the +gmail pagination floor, =771c669= the signature paths, =91ac5a1= the four task +filings. Green suite before and after, zero new lint issues, mirror in sync, +=0 0= against upstream after the push. + +Split into five rather than one because they're independent fixes, and a +bundled =chore:= would have buried the two behavior changes among the doc edits. + +*The review gate ran inline, not isolated.* The =publish= skill requires a +dispatched reviewer on every commit and =subagents.md= names it as the standing +isolation-override case, but this session's instructions bar the Agent tool +unless Craig asks. The skill's own fallback covers it, and I said so plainly at +the gate rather than letting an inline review pass as an isolated one. It did +earn its keep: it caught my telega comment claiming the noise multiplied "across +every project holding a synced copy," when there is one daemon and the synced +copies only multiply which project can trigger it. + +That conflict has now fired twice in two sessions, and work's new handoff makes +it three — its second rule is "dispatch repeated passes to a subagent." One +decision from Craig settles all three. + +** Two more handoffs mid-commit + +=home= reports the installer never excludes =todo.org=, so it lands tracked in a +collaborator's repo. Verified: both =install-ai.sh='s gitignore block and +=sweep-gitignore-tooling.sh='s =IGNORE_SET= carry =.ai/=, =.claude/=, +=CLAUDE.md=, =AGENTS.md= and nothing else. The deeper finding is that the +collaborator case is a *third* mode the installer has no notion of — in a repo +Craig doesn't own, the whole set belongs in =.git/info/exclude= rather than +=.gitignore=, since appending to =.gitignore= pushes his personal policy into +someone else's tracked file. Ratowsky already worked around it exactly that way. + +=work= relays a direct Craig directive: quiet form always, and dispatch repeated +scheduled passes. Both rules are right and I've been violating the first all +session. + +Home's item got filed as =[#C]= and committed (=cf9910d=) without waiting for +Craig, because it was filed identically under every option I'd offered him — so +it wasn't a fork, and holding it would have been ceremony. + +** Craig lifted the Agent-tool restriction, and the first dispatched review paid for itself + +He chose option 1: implement quiet form into =interaction.md= and +=subagents.md=, with the Agent tool allowed where the standing rules call for +dispatch. So the pre-commit review for the rules change went to an isolated +reviewer, the first this session. + +It returned *Request Changes* with four blocking findings, and every one is +something I would not have caught reviewing my own diff: + +1. *The quiet rule contradicted =verification.md= outright.* I wrote "a check + that returns the expected result prints nothing" and prescribed + =cmd >/dev/null 2>&1=, while =verification.md= says read the whole output + before claiming a pass. Both files load into every session, so an agent + would have had to resolve that itself, every time — and the obvious targets + ("tests pass", "linter is clean") are exactly the two commands + =verification.md= names. My rule was instructing agents toward the false + pass that file exists to prevent. +2. *My idiom threw away the diagnostic it then demanded.* =2>&1= to + =/dev/null= means the failure branch prints only the placeholder string I + typed, eight lines above my own sentence saying deviations print in full. +3. *"Run these two checks" now sat over three subsections*, and the new one + inverted the section's direction: the other two prevent a spawn, mine + justifies one. +4. *Two of three parallel override enumerations went stale*, and one collided + with the motivating case — "Don't Subagent At All" refuses dispatch for a + known target under ~10 tool calls, which is precisely the shape of the + sentry walk. An agent landing there would have correctly concluded "run it + inline," defeating the whole change. + +Fixed all seven (the three Minor ones too: background is the load-bearing word, +the thread boundary for lock and commits was left to inference, the anecdote was +told three times). Verified the lock claim rather than asserting it — +=agent-lock= is name-keyed and mkdir-atomic, and its header says it exists +because every agent Bash call is its own shell, so a refresh from the subagent +holds the lock the main thread acquired. + +Sent back to the *same* reviewer per the publish flow, so it can check its own +findings against the new text rather than a fresh reviewer re-litigating. + +Round two: *Approve*. It rated findings 1 and 4 closed more thoroughly than it +asked, verified the =agent-lock= claim against the helper's source rather than +taking my word, and raised one new Minor I'd introduced — my preamble said both +overrides lift both pre-dispatch checks, but Availability is a hard capability +constraint, not an efficiency rule, and no override can conjure a spawn +mechanism that isn't there. Fixed rather than deferred. + +*It also caught me describing a fix that didn't happen.* I reported finding 7 +(the anecdote told three times) as "compressed to a clause"; the diff shows it +was already a clause and I changed three words. Its judgment — that the gap is +worth more than the finding was — is right, and it's the exact failure mode the +re-review loop exists to catch: had it trusted my summary instead of re-reading +the text, I'd have gotten away with it. Worth remembering that the loop's value +is the reviewer checking claims against the diff, not against my account of the +diff. + +** Craig ran /voice bare, mid-flow + +Read it as the in-progress draft: the new rule prose, prose mode (these are +documents he reads in an editor, so personal mode's artifact patterns would +misfire). It found 12 em-dashes in what I'd written, plus a semicolon, +uncontracted forms, and stress italics. + +The judgment call worth recording: =interaction.md= and =subagents.md= already +carry 65 em-dashes between them, so new prose following zero-tolerance is +locally inconsistent with its surroundings. I applied the rule anyway, because +the profile says zero-tolerance is chosen self-discipline rather than a +reflection of his habit — which makes the existing 65 the pre-rule habit the +rule exists to correct, not a house style to match. Flagged it to him rather +than deciding silently. + +Work's handoff is replied to and retired, and the inbox is empty. Shipped as +=588fbf6=, pushed, tree clean and even with upstream. diff --git a/.ai/workflows/sentry.org b/.ai/workflows/sentry.org index b25fc14..0e8f819 100644 --- a/.ai/workflows/sentry.org +++ b/.ai/workflows/sentry.org @@ -91,6 +91,10 @@ Every reclaim of a stale lock surfaces in the digest — the helper prints the r Each cycle, after acquiring the single-runner lock and verifying branch state (below), walks the pass list in order. Every pass follows the same four-step contract: +*Run the walk in a BACKGROUND subagent, not the main thread.* The pass list is roughly ten tool calls and it repeats every cycle, while the main thread's tool output lands in the Emacs buffer Craig is working in. Eleven cycles inline on 2026-08-05 filled his workspace with output that almost entirely confirmed nothing had changed. Backgrounding is the load-bearing part: a background agent's output goes to a file, while a foreground dispatch puts it straight back in his terminal. The main thread then reports only what the quiet-output rule allows: deviations, plus the one-line heartbeat at cycle-end. See the Output-Destination Override in =subagents.md= and the quiet-output rule in =interaction.md=. A recurring prompt that tells the agent to walk the list inline is overriding this. Fix the prompt rather than the workflow. + +*Where the thread boundary falls.* The dispatched agent owns the whole walk, which means the per-pass work, the =session-context.org= entries, the per-pass commits, and the between-pass lock refreshes all happen inside it. The main thread keeps what brackets the walk: the entry gates, acquiring and releasing the single-runner lock, branch-state verification, and the cycle-end digest. The lock survives the boundary because =agent-lock= is keyed by name rather than by process, so a refresh from the subagent holds the same lock the main thread acquired. + 1. *Probe* — a cheap existence check for the pass's target (named per pass below). Absent → the pass is one skip line in the digest and nothing more. This is what makes the pass list portable: passes self-activate where their target exists and stay silent elsewhere, with zero per-project configuration. 2. *Work* — run the pass under the unattended contract. Quick, solo, already-agreed mechanical actions execute. Anything destructive or requiring judgment does *not* execute — it appends to the morning-approval queue (what, why, the exact command or edit that fires on approval). A pass runs fully or not at all; there is no reduced-form pass. |
