diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-29 06:38:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-29 06:38:34 -0500 |
| commit | 73e8c01fa49f48766a283e2db933e38951f656ab (patch) | |
| tree | 0c77ef77d0227dad433c3ccfdbac99c655f10cc3 | |
| parent | ecd5d7b47d06c724086a1fa799fc984131493892 (diff) | |
| download | rulesets-73e8c01fa49f48766a283e2db933e38951f656ab.tar.gz rulesets-73e8c01fa49f48766a283e2db933e38951f656ab.zip | |
Three finished tasks moved to Resolved: the sentry cycle rename, the
references/ link removal, and the parked telegram down-is-launch fix.
The lint sweep re-ran and its judgment items were refreshed.
| -rw-r--r-- | .ai/sessions/2026-07-29-06-36-adversarial-review-flow-and-telegram-fixes.org | 514 | ||||
| -rw-r--r-- | inbox/lint-followups.org | 31 | ||||
| -rw-r--r-- | todo.org | 141 |
3 files changed, 599 insertions, 87 deletions
diff --git a/.ai/sessions/2026-07-29-06-36-adversarial-review-flow-and-telegram-fixes.org b/.ai/sessions/2026-07-29-06-36-adversarial-review-flow-and-telegram-fixes.org new file mode 100644 index 0000000..12cbe3d --- /dev/null +++ b/.ai/sessions/2026-07-29-06-36-adversarial-review-flow-and-telegram-fixes.org @@ -0,0 +1,514 @@ +#+TITLE: Session Context — 2026-07-28 +#+AUTHOR: Craig Jennings +#+DATE: 2026-07-28 + +* Summary + +** Active Goal + +Started as inbox triage on a telegram-plugin bug report and became two things: shipping the cross-project fixes that arrived overnight, then designing and dogfooding a mandatory isolated adversarial review before every commit — which immediately found real defects in its own design and in everything filed afterward. + +** Decisions + +- *Merge colliding fixes rather than sequence them.* The parked down-is-launch diff still carried the bad =loadChats= call and cited the segfault gotcha the other fix rewrites. Applying either alone would have shipped a file arguing against itself. +- *"Adversarial", not "hostile"* (Craig). An agent told to attack manufactures findings, so the stance carries a substantiation floor: a finding not substantiated against the diff is dropped. +- *Re-review until the reviewer approves* (Craig's addition, the thing I had missed). Same reviewer continued, not a fresh one — a fresh reviewer can't tell an addressed finding from one that never existed. Bounded at three rounds or first recurrence. +- *Dispatch on every commit*, with the reviewer's own Phase 0 ruling triviality. A floor written as "small" or "mechanical" puts the judgment back with the author, whose judgment is the thing being checked. +- *Pass the requirement source, withhold the rationale.* A ticket is not the author's model; it was written first and by someone else, so it's the only input that can contradict the author's claim. +- *=cycle=, not =pass=, for one sentry loop* (Craig). home proposed =pass=; =sentry.org= already uses it as a numbered noun for the eleven hygiene passes, so =Pass 11= would have collided with =pass 12=. +- *Drop the =references/= link rather than sync the directory.* The four calendar workflows already travel and already carry the recipes. +- *Strip the wrap-org-table task to Verified / Open questions* after its review loop bounded out. The measurements were never what failed. + +** Data Collected / Findings + +- *The telegram bug.* =(telega--loadChats 'main)= sends a bare symbol on the wire; =tdat_plist_value= (=telega-dat.c=) accepts only =(=, =[=, ="=, =-=, digit, =t=, =:=, =n= and calls =assert(false)= on =m=. Verified against telega's source at four points rather than trusting the handoff. Exposure was manual triage only — sentry excludes messengers, so home's eleven overnight cycles never loaded the plugin. +- *=wrap-org-table.el= splits logical rows*, and =lint-org= doesn't merely miss it — it *causes* it. =lint-org.el:424= calls the same broken predicate, so it reports the tool's own correct output as "missing rule between rows — wrap-org-table.el reflows it" when nothing is missing, then reports the corrupted result clean. Idempotence is broken: the tool corrupts its own output on a second run. +- *The isolated reviewer earned its keep on its first four uses*, finding: that withholding the ticket made my claim self-certifying; that my =subagents.md= override reaffirmed the Prompt Contract field that would destroy the isolation; a fourth verdict (=Needs Discussion=) I'd asserted didn't exist; and four successive wrong root-cause analyses on the table bug. +- *rulesets is itself exposed* to the table bug: =todo.org='s four-row attachment-sanitization table. Don't reflow until fixed. +- *Seven =../../= link sites* across four synced workflows resolve only in rulesets. =scripts/lint.sh='s =check_md_links= was built for that class and misses them because it matches markdown syntax only. + +** Files Modified + +Seven commits, all pushed, velox synced after each. =bff0138= merged telegram fixes. =43a4cf7= post-load liveness check. =614e3b1= removed finished working dirs. =ca508a1= filed three handoff findings. =f3f5bfd= the =fire= → =cycle= rename (72 sites plus three that had leaked outside =sentry.org=). =3a933a2= the =references/= analysis. =5999f88= dropped the dead link and deleted the stale file behind it. =ecd5d7b= filed the wrap-org-table bug. + +Rules changed: =publish/SKILL.md= Step 1 rewritten (dispatch contract, four defined verdicts, the loop, bounds), =review-code/SKILL.md= (two levels of dispatch, adversarial contract, re-review mode), =claude-rules/subagents.md= (Isolation Override; Prompt Contract field 2 inverts), and the three unattended callers taught to park. + +** Next Steps + +- *Three of the four items Craig queued are untouched*: the winvm =[#C]= lint defects, the context-engineering rightsizing (needs his four decisions), and the sentry spec deep read (two weeks old). +- *Rule gap found by using the rule*: =Needs Discussion= exits to the user, but nothing says what happens after the user answers — whether the round counter resets. I treated it as a fresh review; that judgment isn't written down. +- *Item 2 is now qualified*: its fix says "run =wrap-org-table.el=", and that tool has a live corruption bug. The specific table is safe, but verify the output rather than trust it. +- Four =[#B]= bugs filed tonight and unstarted: the table splitter, the =../../= links, plus the two carried in. + +KB: promoted 1 / consulted no + +* Session Log + +** 11:55 — Startup + +Ran startup. Rulesets already current, project repo clean and current, =make +install= had nothing new to link, =.ai/= synced from templates. No crash anchor +— previous session (context-engineering rightsizing, 2026-07-27 17:02) wrapped +cleanly. + +Findings: 6 tasks unreviewed >7 days; roam inbox holds 4 items; KB at 108 +=:agent:= nodes with nothing matching this project. Spec-sort and host-identity +probes silent. Language-bundle check silent. + +** 12:05 — Inbox: the telegram segfault root cause + +Four new inbox files from =.emacs.d=, two pairs: a 06:15 intro note + plugin +file, then a 07:21 correction + superseding plugin file. The correction retracts +one secondary claim from the 06:15 write-up (that the "19 of ~50 chats" reading +was truncation caused by the bug — it wasn't; 19 is the real account size, +measured by work at the wire level). Root cause and fix unchanged. + +The proposal: =triage-intake.telegram.org= Step 1 calls =(telega--loadChats +'main)=, and that bare symbol kills =telega-server= outright. + +I verified the whole chain against telega's own source rather than taking the +handoff's word for it (=elpa/telega-20260706.2147/=): + +- =telega--loadChats= (telega-tdlib.el:2190) drops its argument straight into + the request as =:chat_list= with no conversion. Confirmed. +- The C parser =tdat_plist_value= (server/telega-dat.c:466) accepts only =(=, + =[=, ="=, =-=, a digit, =t=, =:=, or =n= to start a value; anything else + prints "Unexpected char '%c' in plist value" and calls =assert(false)=. + =main= starts with =m=. Confirmed, and the accepted-char list in the handoff + is exactly right. +- telega's own callers all pass the object: telega.el:290, telega.el:295, + telega-tdlib-events.el:516. Confirmed. +- The symbol shorthand lives in a different layer — telega-filter.el:472 and + telega-folders.el:99 convert =(eq cl-fspec 'main)= to ='(:@type + "chatListMain")=. Confirmed. + +Every claim holds. Grepped all workflows for other bare-symbol arguments to +=telega--*= wrappers: only the two sites this diff already fixes. + +*The complication I found.* There is already a parked =[#B]= VERIFY (todo.org:136, +from =.emacs.d= 2026-07-24) proposing a different fix to this same file — the +down-is-launch fix, with a prepared diff in +=working/triage-telegram-down-launch/=. Its proposed file still carries the bad +=loadChats= call at its lines 52 and 122, and its third hunk adds prose citing +"tdlib segfaults in native mode (SEGFAULT gotcha below)" — pointing at the very +section this new handoff rewrites to say the crashes were our bug, not tdlib's. +Applying either one alone leaves the file half-right. They need merging, not +sequencing. + +Also: home and work both declare =telegram= in =:TRIAGE_SOURCES:=, so both have +been killing telega-server on every sweep. Work already patched locally and +verified at the wire level. Home has not been told. + +** 11:58 — Staged the batch, closed the loops + +The Stop hook counted the four files still sitting in =inbox/=. The triage was +done; what remained was Craig's merge decision, not mine. So I staged all four +into =working/triage-telegram-segfault-rootcause/= (the 07:21 pair as +=.proposed= + correction note, the 06:15 pair kept as superseded context — its +blast-radius and follow-up sections aren't repeated in the correction). Inbox +back to clean, =inbox-status= rc=0. + +Left =working/triage-telegram-down-launch/= untouched: the parked VERIFY's body +links its =proposed.diff= by path, and moving it would break the link before +Craig has decided anything. If he takes the merge, that consolidates then. + +Replied to =.emacs.d= — confirmed the verification, and told them the one thing +they couldn't see: their own 2026-07-24 parked diff collides with this, both in +the stale =loadChats= call it still carries and in the native-mode prose it adds +citing the gotcha this rewrites. Also declined their suggested bare-symbol lint: +one consumer file, two call sites both fixed, so the stated rule is cheaper than +a checker with a single input. + +Notified home directly with the mechanism and the two-site fix, told it to patch +locally rather than wait on the canonical, and carried the correction forward +explicitly so it doesn't inherit the retracted truncation story. + +Nothing applied to the canonical. That still waits on Craig. + +** 12:10 — Craig picked the merge. Applied and committed. + +Merged both fixes into one version rather than sequencing them. Base was the +segfault-corrected file, then the three parked hunks on top: the down-is-launch +directive, the SCAN-FAILED-only-after-launch-attempted rewording, and =(setq +telega-use-docker t)= restored to the Step 1 code block. + +The reconcile that made merging worth doing. The parked hunk's new comment said +"tdlib segfaults in native mode (SEGFAULT gotcha below)", pointing at the +section the other fix rewrites to say those deaths were our own bad argument. +Left alone the file would have argued against itself. I changed the Step 1 +comment to state plainly that the two are separate concerns (the deaths happened +*in* docker mode, so docker mode is neither a defense against the loadChats bug +nor evidence for itself), and reworded the Quick Reference line from "tdlib +segfaults outside docker mode" to "crashed in native mode (2026-06-09)" with the +same disambiguation. + +That reword also removed a host-identity violation I hadn't gone looking for. +The original asserted "Craig's daemon currently has telega-use-docker nil" — a +mutable machine fact stated as fixed in a synced doc. I checked the actual +default (=telega-customize.el:514=, =defcustom telega-use-docker nil=) and wrote +the durable claim instead. + +Verified: both live call sites use the TL object, the two remaining ='main= +occurrences are inside the gotcha prose describing the bug, lint-org clean on the +changed file, mirror synced, =make test= green before (exit 0) and after (exit +0). + +todo.org: closed the parked =**= VERIFY as =DONE= + =CLOSED:= per todo-format.md +with the merge rationale in the body. Promoted its =***= engine child (SCAN +FAILED must not advance the sentinel) to top-level =**= VERIFY so it doesn't get +buried under a DONE parent. Kept its =:LAST_REVIEWED: 2026-07-24= rather than +stamping today — I moved it and judged it separate, but nobody re-derived its +content, so the older date keeps it honest. + +Review: Approve, no Critical or Important. Two Minor, both surfaced rather than +fixed. The gotcha now advises a post-load =(process-live-p ...)= check that the +Step 1 recipe doesn't actually do, and adding it would extend the recipe past the +two fixes Craig approved. + +Committed =bff0138=. Not pushed — that's a separate confirmation. + +** 12:20 — home replied, and corrected my urgency read + +home accepted, patched both call sites locally, and re-verified the diagnosis +independently rather than trusting it. Useful correction back: home declares +telegram in =:TRIAGE_SOURCES:=, but sentry excludes messengers from triage +intake, so the plugin never loaded on a sentry fire. Eleven overnight fires ran +clean against the broken file. I had assumed the sweeps were affected; the real +exposure is manual triage intake only. + +Told home its stopgap won't be reverted into a broken state — the next rsync +replaces it with canonical content carrying the same fix. On this machine that +lands as soon as its next startup runs, since the rsync reads the local rulesets +working tree. velox needs the push. + +Inbox back to zero. + +** 14:10 — Pushed, and closed the velox gap + +Pushed =1675613..bff0138= to origin after the pre-push reconcile (still 1 ahead, +0 behind). + +=.emacs.d= replied while the push was in flight. It had already verified bff0138 +here, re-run its own workflows rsync, and confirmed the corrected form landed. +It withdrew the bare-symbol lint suggestion, conceded the home omission, and +flagged one real gap: bff0138 was committed but not pushed, so velox stayed +exposed. That was true when written and stale by the time it arrived. + +Checked velox over tailscale (this host is ratio, per =uname -n=). It was 1 +behind / 0 ahead and sync-safe, so I fast-forwarded it through the same +=git-worktree-gate sync-safe= check startup uses. Velox is now at bff0138 and its +workflow file carries the corrected call, with the only bare ='main= occurrences +inside the gotcha prose. Both daily drivers covered. + +Corrected read carried into both replies: the exposure was manual triage intake +only, not the automated sweeps, because sentry excludes messengers. + +** Open follow-ups (surfaced to Craig, not acted on) + +1. The gotcha tells callers to check =(process-live-p (telega-server--proc))= + after a load, but the Step 1 recipe doesn't do it. Now that the corrected call + shouldn't kill the server, that check is what would catch a regression. Left + out deliberately as scope creep past the two approved fixes. +2. Both =working/triage-telegram-*= dirs are completed-task artifacts and want + filing per working-files.md. Revised read after checking: delete both + outright. Every file is tracked (=b19d420= and =bff0138=), so git holds them + permanently and a copy in =assets/= would only duplicate history. Nothing + links to them. + +** 15:00 — Second inbox round: .emacs.d self-correction + winvm lint findings + +=.emacs.d= wrote back to say it had overcorrected on home: it accepted "home was +in the blast radius" and then recorded that home "had been killing telega-server +on every sweep too", which home's own sentry data refutes. It fixed its task +record rather than leaving it. I told it the pattern wasn't one-sided — I made +the same move this morning, estimating home's blast radius instead of measuring +it, and home's data is what corrected me. It also offered the emacs-side half of +a completed-vs-truncated signal, which it has filed as =[#C]=, if the +=process-live-p= recipe change lands. + +=winvm= sent a link-integrity pass with three findings, all reproduced against +the rulesets source rather than only its local copy. I verified all three: + +1. =protocols.org:273= links =references/calendar-reference.org=, but the rsync + set is only =protocols.org=, =workflows/=, =scripts/=. Dead link in every + consuming project. home and =.emacs.d= have no =.ai/references/= at all. +2. =retrospectives/PRINCIPLES.org:38= violates the org-table standard. + =lint-org= confirms, checker =org-table-standard=. +3. =protocols.org= lints 8 mechanical + 19 judgment =misplaced-heading=, all + from Markdown =**bold**= in an org file. 48 bold spans, 14 line-initial. + +The check winvm couldn't run: adding =references/= to the sync brings =--delete= +with it, which would destroy project-owned files there. work is the only project +with a =.ai/references/= and its copy is byte-identical to the source, so nothing +would be lost. That clears the path to sync-it over drop-the-link. + +One refinement back to winvm on finding 3: the 8 mechanical hits are would-fix, +and the 14 line-initial bold spans are exactly what =lint-org --fix= would +rewrite without knowing they're emphasis rather than headings. So that half is +not safe to run mechanically even though the count suggests it is. + +Filed as =[#B] :bug:= (the dead link, Minor x every-project-every-sync = P2) and +=[#C] :chore:= (the two cosmetic defects, P3), both stamped =:LAST_REVIEWED:= +today since I graded them today. Verified todo.org's lint counts are unchanged +from the pre-edit baseline (mechanical=2, judgment=12, both pre-existing and +already in =inbox/lint-followups.org=). + +Inbox back to zero. todo.org is left uncommitted deliberately — Craig has a +pending decision that will likely touch it again, so batching beats a churn +commit. + +** 18:45 — Craig took both follow-ups. Liveness check staged. + +Added the liveness check to the Step 1 load call. It now returns ='server-died= +instead of an unconditional ='loaded=, and new prose routes that into the +existing SCAN FAILED definition rather than inventing a category: a server that +dies during load leaves a thin hash, which reads exactly like a quiet account, +which is the same false all-clear the down/not-loaded rule already prevents. + +Self-review caught a real defect in my own first draft. I called +=(telega-server-live-p)= bare, but Step 0 guards the same predicate with +=fboundp= because telega may not be loaded. A launch that failed outright would +have signalled void-function instead of returning the clean contract. Added the +guard, matching Step 0's idiom. Verified the predicate is exactly the +=process-live-p= expression the gotcha names (=telega-server.el:221=). + +Verified: parens balance at depth 0, lint-org 0/0, mirror identical, =make test= +green (exit 0) on the final state. + +Not committed — waiting on the approval gate. + +** 18:48 — Third inbox round + +=.emacs.d= sent a closing FYI marked no-action, agreeing my framing of the shared +failure (blast radius estimated rather than measured) named the trigger rather +than the failure. Deleted without reply, since replying to "nothing owed back" +is noise. + +home proposed renaming sentry.org's noun-sense "fire" to "pass", after Craig read +its "nine fires" as nine emergencies: "I assume you mean nine crises, not nine +loop cycles and I begin to get scared." The problem is real, well-evidenced, and +reaches Craig directly through digest headings. + +But the proposed term is wrong, and the reason home gave for it is the +disqualifier. =sentry.org= already uses "pass" as a precise numbered noun — the +pass list, the Pass Runner, "eleven finding/hygiene passes", "pass 12". With +exactly eleven hygiene passes, home's proposed =** Pass 11= heading collides with +an existing referent. That trades a term Craig misreads as urgent for one that is +genuinely ambiguous. + +Counter-proposed *cycle*: zero occurrences in the file, and Craig's own word in +the quote home cited. Checked and rejected "sweep" (3 uses) and "run" (used as a +noun). Filed =[#C] :chore:= with the grading and the collision analysis; replied +to home with the counter-proposal. + +** 18:50 — Three commits, and the collision confirmed from live evidence + +Craig approved both follow-ups and the =cycle= term. Three commits: + +- =43a4cf7= the liveness check. +- =614e3b1= removed both telegram working dirs. Filing by deletion, since every + file was already in git via =b19d420= and =bff0138= and an =assets/= copy would + only duplicate history. +- =ca508a1= filed the three handoff findings with their gradings. + +home wrote back confirming the "pass" collision was real, and that it had already +walked into it: its anchor now carries =** Pass 11= meaning the eleventh cycle, +three lines from =pass 12 (solo-task implementation)= meaning the twelfth item in +the pass list. Same file, two referents, introduced by its own normalization an +hour earlier. It found that in live evidence faster than reading the file would +have caught it. + +It was blocked on Craig's confirmation and had written a memory saying "pass", so +I sent the confirmation immediately. The memory was the urgent half — a stale one +teaches every future home session the ambiguity, where the anchor is one file. + +Recording Craig's approval flipped the sentry task to =:solo:=. The term was the +only judgment it carried, and the completion check is objective, so it can ride a +backlog run rather than waiting for someone to touch =sentry.org=. + +Pushed =bff0138..ca508a1=, velox fast-forwarded to match. + +** 19:45 — The cycle rename, and the leak home's scope missed + +home did its side first: renormalized its anchor by restoring the +pre-normalization backup and re-running fire→cycle from clean, rather than +reverse-mapping pass→cycle. That was the right call — reverse-mapping would have +needed a judgment on every instance to separate its own conversions from genuine +pass-list references, where re-running from clean makes it structural. It also +corrected its memory and handed the canonical back. + +Did the canonical rename with a script rather than by eye: protect the verb sites +by explicit pattern, assert zero unclassified =-ed/-ing= forms survive, then +substitute. 72 noun instances converted, 4 verb sites untouched (=/loop= fires +again, two "fires on approval", "record of what fired"). + +*The leak home's scope missed.* The term wasn't confined to =sentry.org=. +=wrap-it-up.org= said "a crashed fire", and =todo-cleanup.el= and its test both +said "every sentry fire" — all three naming a sentry cycle. Renaming only +=sentry.org= would have split the vocabulary across files. Found by grepping +every file that mentions sentry, then re-grepping without a context window after +the first pass truncated short-line matches and hid them. + +Verified: exactly 3 verb instances left in sentry.org, no placeholder leaked, the +digest commit template now reads =<date> <time> cycle=, capitalized plurals +handled, lint 0/0 on sentry.org, suite green (exit 0 — load-bearing here, since +=todo-cleanup.el= and its test are under test). The two =wrap-it-up.org= lint +findings are pre-existing and identical at HEAD. + +Committed =f3f5bfd=, pushed, velox fast-forwarded and verified. Notified home +(with the leak it hadn't seen) and =.emacs.d=. Closed the task =DONE=. + +Four commits this session, all pushed, both daily drivers current, inbox at zero. + +** 20:00 — Roam inbox zero, then the adversarial-review design + +Roam scan: 3 items, 1 claimed (=rulesets:= prefix), 2 unowned gear links left +for Craig. Filed the claimed one, removed it from roam under capture-guard + +roam-write lock, triggered =roam-sync=. A local =.emacs.d= FYI also cleared. + +The claimed item: "code reviews must occur before every commit an agent does, +and they should be hostile reviews from a subagent without the agent's context." + +Craig's decisions: *adversarial* rather than hostile (he took my push-back that +an agent told to attack manufactures findings), plus a requirement I had missed — +a re-review loop that runs until the reviewer approves — and that the rules must +not contradict afterward. Unopposed recommendations I proceeded on: dispatch on +every commit with the reviewer's own gate deciding triviality, and the flow lands +in the =publish= skill. + +Wrote it into three files: =publish/SKILL.md= Step 1 (dispatch contract, +adversarial-with-substantiation, the loop, bounds), =review-code/SKILL.md= (the +two levels of dispatch, the adversarial contract, re-review mode), and +=claude-rules/subagents.md= (a new Isolation Override section, since three +separate size rules there said don't dispatch small work). + +** 20:30 — Dogfooded it, and the reviewer found nine things + +Ran the new flow on its own diff: dispatched an isolated adversarial reviewer +with the diff plus a one-line claim, withholding everything else. It returned +REQUEST CHANGES with seven Important and two Minor, every one substantiated. I +checked each against the files rather than accepting them, and all nine were +real: + +1. =Skipped= from Phase 0 is not =Approve=, so trivial diffs dead-ended at a gate + with no defined pass. +2. =no-approvals.org= line 73 (the actual execution step) still described the old + inline unbounded flow; I had only updated the preamble at line 49. +3. =work-the-backlog.org= and =sentry.org= — the unattended callers — had no + receiver for "stop and surface to the user". The speedrun routes to + work-the-backlog, not the file I updated. +4. The Step 2 exception still said the review runs "when it applies", which my + rewrite had made false. +5. *The sharpest one.* Withholding the ticket/plan makes the author's claim + self-certifying and strands =review-code='s Intent-vs-Delivery criterion — the + one aimed at exactly the inherited-scope error this gate exists to catch. A + ticket is not the author's model; it is the independent record of what was + asked. I had not considered this. +6. The loop turned on the verdict token, so a single Minor could burn all three + rounds and escalate. +7. My override said it "doesn't relax the Prompt Contract" while field 2 of that + contract says paste your context verbatim — which would destroy the isolation + the whole change is built on. +8. todo.org carried an unrelated =references/= rewrite, and the new task body + listed as open the questions the same commit answered. +9. =subagents.md= still says subagent output is a claim to verify, unreconciled + with "approval is the reviewer's to give". + +All nine fixed. The =references/= hunk is split out as =3a933a2=. Round 2 sent +back to the same reviewer, which is the loop working as designed. + +** 21:30 — The loop closed at three rounds + +Round 2 (three findings): =review-code='s adversarial contract still said two +inputs, so the round-1 fix landed in =publish= but not in the text the reviewer +reads — the two files disagreed at the one seam the change was about. A +count/list regression my own fix introduced ("exactly two things" over a +three-item list). And a fourth verdict I had missed entirely: =review-code= +emits =Needs Discussion=, which is exactly what an adversarial reviewer reaches +for on an architectural objection, and the flow had no handling for it. + +Fixing =Needs Discussion= reproduced round 1's finding 3 one level down, which I +caught myself: all four unattended parking clauses keyed on "the loop hits its +bound", and a first-round =Needs Discussion= is not a bound hit. Rewrote all four +to trigger on "the review can't reach approval" with the three causes named, and +asked the reviewer to verify that independently rather than take it from me. + +Round 3: APPROVE, with one Minor — a recurrence of the count/list mismatch, since +my fourth-verdict fix left the lead-in saying "three outcomes" above four +bullets. Fixed the numeral. The committed diff therefore differs from the +approved one by exactly that word, which the flow's own Minor-only rule permits +rather than spending a fourth round. + +The reviewer also verified things I had not asked about and would not have +checked: that =failed= is already a legal outcome slug in work-the-backlog's +metrics table, that the three workflow mirrors carry identical blob hashes rather +than merely similar text, and that no fifth verdict token exists anywhere in +=review-code=. It filed one follow-up correctly rather than fixing it in-diff — +=start-work.md= Phase 7 still summarizes the publish flow instead of pointing at +it, and was stale before today. Filed =[#C] :chore:solo:=. + +Convergence shape across the three rounds: nine findings, three, one Minor. The +residue in later rounds was integration error from the previous round's fixes +rather than new design problems, which is the shape the bound is calibrated for. + +Committed =8062460=, pushed, velox fast-forwarded and verified. + +Six commits this session, all pushed, both daily drivers current, inbox at zero, +tree clean. + +** 2026-07-29 — Walking the remaining items, and a long lesson + +*Item 1, the =references/= dead link* (=5999f88=). Craig picked drop-the-link. +The adversarial review returned =Needs Discussion= — the fourth verdict, on its +first real use — and widened the fix twice, both correctly. My replacement prose +said credentials "live in the rulesets repo" without naming a file, which would +have sent readers to =calendar-reference.org=, whose three paths had been dead +since May. Now names =mcp/README.org=. And the file itself was orphaned by the +link removal, so both copies and the empty =references/= dirs are gone. Round 2 +approved with three Low findings, all against the task record: my count was wrong +(seven sites, not five) and =scripts/lint.sh='s =check_md_links= already exists +for that class, missing them only because it matches markdown syntax. + +*Rule gap found by using the rule.* =Needs Discussion= exits to the user, but I +never wrote what happens after the user answers. Treated it as a fresh review on +the reasoning that Craig adjudicated and the scope changed. Flagged to Craig; not +yet written into the skill. + +*The wrap-org-table bug* (=ecd5d7b=). work reported that the tool splits a logical +row and lint passes the result. Everything I *measured* held. Everything I +*inferred* on top was refuted, four times: + +1. Root cause "absence of rules in the input" — refuted by the double-run repro + (the tool corrupts its own correct, rule-delimited output). +2. "Tested and killed the empty-cell hypothesis" — the fixture was confounded. + With no hlines the code short-circuits at =:184= before the predicate is + reached, so I varied the empty cell while the path that reads it was switched + off, got a negative, and wrote it down as settled. +3. "The reporter's row-below observation discriminates between the paths" — it + doesn't; both produce that signature. Claimed twice. +4. "A static scan can't see primary-path exposure, needs simulation" — wrong, and + worse, I sent it to work, who built on it. Then my *corrected* advice (run the + predicate over rule-delimited groups) was also wrong: work implemented it and + showed it can't discriminate at any threshold, with worked examples where the + same structural signature has opposite correct verdicts. + +Three corrections sent to work, plus a fourth acknowledging their disproof. The +review loop *bounded out* at three rounds — the first bound-out under the new +rule, working as designed. Craig adjudicated by stripping the task to Verified / +Two-fixes-that-work / Open-questions, which is the right shape: the measurements +were never the problem. + +The fix that survived is work's read, not mine: check idempotence (reflow twice, +diff) rather than build a detector. It's true by construction and needs nobody to +decide what a group means. + +*The lesson, stated plainly.* Every refutation across three rounds landed on +inference, never on a measurement. I ran experiments and then over-read them, +repeatedly, at full confidence. work — after I'd sent them three wrong analyses — +labelled their own uncertain number as a floor on a population they couldn't +cleanly define, unprompted. That discipline is the thing to copy. + +I also found the 2026-07-27 note where I'd already observed this exact failure +and left it in a session summary instead of filing it. work's framing: a correct +observation recorded and then read as fine is the same failure as a green check +on a corrupted table. diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org index f63470c..9d2bd8f 100644 --- a/inbox/lint-followups.org +++ b/inbox/lint-followups.org @@ -1,17 +1,18 @@ * 2026-07-20 Mon — Task-review health: 1 top-level [#A]/[#B]/[#C] tasks unreviewed for >30 days (daily review may have slipped) -* lint-org follow-ups — todo.org (2026-07-25) -** TODO link-to-local-file — Link to non-existent local file "working/hook-fail-open/validate-el.diff" (line 2066) -** TODO misplaced-planning-info — Misplaced planning info line (line 2055) -** TODO link-to-local-file — Link to non-existent local file "working/hook-fail-open/pre-commit.diff" (line 2050) -** TODO misplaced-planning-info — Misplaced planning info line (line 2035) -** TODO org-table-standard — table violates the org-table standard: no closing rule; missing rule between rows — wrap-org-table.el reflows it (line 141) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 299) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 302) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 309) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 317) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 320) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 329) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 427) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 586) -** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 595) +* lint-org follow-ups — todo.org (2026-07-29) +** TODO misplaced-heading — Possibly misplaced heading line (line 2263) +** TODO link-to-local-file — Link to non-existent local file "working/hook-fail-open/validate-el.diff" (line 2239) +** TODO misplaced-planning-info — Misplaced planning info line (line 2228) +** TODO link-to-local-file — Link to non-existent local file "working/hook-fail-open/pre-commit.diff" (line 2223) +** TODO misplaced-planning-info — Misplaced planning info line (line 2208) +** TODO org-table-standard — table violates the org-table standard: no closing rule; missing rule between rows — wrap-org-table.el reflows it (line 314) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 472) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 475) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 482) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 490) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 493) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 502) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 600) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 759) +** TODO task-missing-last-reviewed — task has no :LAST_REVIEWED: — stamp it at creation with today's date (a task you just wrote and graded is reviewed); otherwise it enters the next staleness batch as never-reviewed (line 768) @@ -134,65 +134,6 @@ Fix is to point Phase 7 at the =publish= skill rather than restate the flow, whi Found by the adversarial reviewer during the 2026-07-28 review-flow change, and correctly filed rather than fixed there: the line was untouched by that diff. -** DONE [#C] sentry.org calls one loop cycle a "fire" :chore:solo: -CLOSED: [2026-07-28 Tue] -:PROPERTIES: -:LAST_REVIEWED: 2026-07-28 -:END: -Done 2026-07-28. 72 noun-sense instances in =sentry.org= became "cycle"; the four verb-sense uses stayed. Three more lived outside the file — =wrap-it-up.org= ("a crashed fire"), =todo-cleanup.el= and its test ("every sentry fire") — all naming a sentry cycle, so they moved too. home's proposal was scoped to =sentry.org= alone, so the leak would have split the vocabulary across files. - -Craig read home's "nine fires" as nine emergencies and went looking for what was burning (2026-07-28): "I assume you mean nine crises, not nine loop cycles and I begin to get scared." The term reaches him directly — digest headings render as =** Fire 11 — 08:32 CDT= in the anchor he reads every morning. 35 instances in =sentry.org=. - -Grading: Minor severity (a user-facing artifact that miscommunicates, no data loss) x most users frequently (every digest, on every project running sentry) = P3 = [#C]. - -*Take the problem, not home's proposed term.* home proposed "pass", reasoning that it already lives in the file's vocabulary. That is exactly what disqualifies it. =sentry.org= already uses "pass" as a precise numbered noun: "the pass list", "the Pass Runner", "eleven finding/hygiene passes", "pass 12" for the implementation pass. There are exactly eleven hygiene passes, so home's proposed digest heading =** Pass 11= collides with an existing real referent. Renaming would trade a term Craig misreads as urgent for one that is genuinely ambiguous. - -Counter-proposal: *cycle*. It appears zero times in =sentry.org=, so there is nothing to collide with. It is also Craig's own word from the very quote that surfaced this ("not nine loop cycles"). =** Cycle 11 — 08:32 CDT= reads cleanly. Checked and rejected: "sweep" (already used for hygiene and property sweeps) and "run" (already used as a noun, "first live run"). - -Keep the verb sense of fire throughout ("the notify fires", "the path never fires") — only the noun meaning one loop cycle changes. Past session anchors are historical records and stay as written. - -Craig approved "cycle" on 2026-07-28. That settles the only judgment the task carried, so it is =:solo:= now: the surface is the 35 noun-sense instances in =sentry.org=, and the completion check is objective — zero noun-sense "fire" left, verb sense untouched, lint clean, suite green, canonical and mirror in sync. - -Source: home handoff, 2026-07-28. - -** DONE [#B] references/ is linked from protocols.org but never synced :bug: -CLOSED: [2026-07-28 Tue] -:PROPERTIES: -:LAST_REVIEWED: 2026-07-28 -:END: -Craig picked option 1 on 2026-07-28: drop the link, point at the calendar workflows instead. The four of them sync already and carry the MCP tool names, both account ids, the gcalcli fallback, and the conflict-check discipline — everything the reference was cited for. - -The adversarial review then returned =Needs Discussion= and widened the fix twice, both correctly: - -- My first replacement said credentials "live in the rulesets repo" without naming a file. The only calendar-named document there was =calendar-reference.org=, whose three credential paths have all been dead since the OAuth keys moved into the encrypted MCP bundle in May. So the prose sent a reader to a stale file, which fails more quietly than the dead link it replaced. Now names =mcp/README.org=, the real authority, verified to document =gcp-oauth.keys.json= as gitignored and regenerated at install. -- =calendar-reference.org= was left orphaned by the link removal: zero live inbound references, two copies, and =references/= is not in =sync-check.sh='s gate (=paths=(protocols.org workflows scripts)=), so the copies could drift silently. Deleted both, and the empty =references/= directories with them. Its operational content is fully covered by the four workflows and its credential paths were all stale, so nothing live was lost. - -The review also found the same defect class at seven other sites, filed separately. - -One fact died with the file, dropped deliberately rather than by accident: that the Google Cloud app runs in production mode, so tokens don't expire after seven days. It's checkable in the console, and it was the last live line in a document whose other credential facts had all gone stale. - -=protocols.org:273= links to =references/calendar-reference.org=, but startup.org's rsync copies only =protocols.org=, =workflows/=, and =scripts/=. So the link is dead in every consuming project. Confirmed: the file exists at =claude-templates/.ai/references/=, and neither home nor =.emacs.d= has a =.ai/references/= at all. - -Grading: Minor severity (a documented reference an agent can't follow, workaround is to search or ask) x every user every time (every consuming project, every sync) = P2 = [#B]. - -Pinned 2026-07-28 for Craig's decision. Analysis below is complete; only the choice is open. - -*Revised recommendation: drop the link, don't add the sync.* My first read was add =references/= to the rsync. Looking at what the directory actually holds reversed it: - -- =references/= holds exactly one file, and =protocols.org:273= is its only citation anywhere in the tree. -- The four calendar workflows (=add-=, =edit-=, =delete-=, =read-calendar-event(s).org=) already sync to every project, and already carry the operational detail: the MCP server name, both account IDs, the gcalcli fallback, conflict-checking. None of them cites =calendar-reference.org=; they are self-sufficient. -- What the reference uniquely adds is credential *file locations* (an OAuth keys path, a GPG-encrypted gcalcli secret) — no secret values. Re-auth is a rare operation Craig performs himself, not something an agent in another project needs a pointer to. - -So adding a synced directory carrying =--delete= semantics, to deliver one mostly-redundant file, is a poor trade. It also cuts against the rightsizing work: =protocols.org= is read into context every session, and a dead link is noise in a file being slimmed. - -Preferred fix: replace the link with a one-line pointer to the calendar workflows, which travel and are current. The reference file stays rulesets-only for the credential locations. - -Alternatives if Craig prefers: add =references/= to the rsync (the =--delete= hazard is not present today — work is the only project with a =.ai/references/= and its copy is byte-identical), or fold the credential locations into the calendar workflows and then drop the link (most complete, but spreads local absolute paths across four more synced files). - -Not =:solo:= — it changes a synced template, which needs Craig's approval by the inbox rule, and the sync-vs-drop choice is his. - -Source: winvm link-integrity pass, 2026-07-28. - ** TODO [#C] Two lint defects at the template source :chore: :PROPERTIES: :LAST_REVIEWED: 2026-07-28 @@ -303,19 +244,6 @@ The proposed Claude-memory migration auditor is related only by runtime portabil No prepared diff: this is a shared configuration design decision, and the current local wrappers/configs remain machine-owned evidence rather than canonical source. Say "spec the MCP registry sync" to start the decisions walk. -** DONE [#B] Parked: telegram source treats "down" as launch, not SCAN FAILED (from .emacs.d) -CLOSED: [2026-07-28 Tue] -:PROPERTIES: -:LAST_REVIEWED: 2026-07-24 -:END: -Applied 2026-07-28, merged with the segfault root-cause fix that arrived the same morning rather than applied alone. - -Merging was necessary, not tidiness. The parked proposed file still carried the bad =(telega--loadChats 'main)= call at its own lines 52 and 122, so applying it as-is would have shipped a file that fixed the wording defect while preserving the call that kills the server. Its third hunk also added prose citing "tdlib segfaults in native mode (SEGFAULT gotcha below)" — pointing at the section the new handoff rewrites to say those deaths were our own bad argument, not tdlib memory corruption. - -What landed: all three parked hunks (the down-is-launch directive, the SCAN-FAILED-only-after-launch-attempted rewording, the =(setq telega-use-docker t)= restored to the Step 1 code block), plus both corrected =loadChats= call sites and the rewritten gotcha. The native-mode prose was reconciled in two places so it no longer leans on the refuted story: the Step 1 comment now states plainly that docker mode and the loadChats bug are separate concerns (the deaths happened *in* docker mode, so docker mode is neither a defense against it nor evidence for it), and the Quick Reference line says "crashed in native mode (2026-06-09)" instead of "segfaults", with the same disambiguation. - -Verified: both live call sites use the TL object; the two remaining ='main= occurrences are inside the gotcha prose describing the bug. lint-org clean, mirror synced, suite green. - ** VERIFY [#B] A SCAN FAILED source must not advance its sentinel (engine, not the plugin) :PROPERTIES: :LAST_REVIEWED: 2026-07-24 @@ -2334,3 +2262,72 @@ Fix direction (per home): while inside a =begin_example= / =begin_src= block, sk Home answered it and I re-verified both halves here: =grep invalid-block= over =lint-org.el= returns nothing, and =org-lint--checkers= enumerates =invalid-block= in batch Emacs alongside =link-to-local-file=, =invalid-babel-call-block=, and =missing-language-in-src-block=. So this is the same shape as the =link-to-local-file= episode: suppress an =invalid-block= finding whose line falls inside a verbatim block, on our side of org-lint's output. No local checker to edit. Regression fixture, ready to use: home's own =.ai/notes.org= PENDING DECISIONS example block (lines 386-398) holds an unescaped =** Feature Name or Topic= and trips both delimiters — findings at lines 386 and 398. Home is deliberately leaving its copy unescaped so it stays a fixture, and asked to be pinged when the filter lands so it can re-run. The filter should take those two findings to zero without touching the file. +** DONE [#C] sentry.org calls one loop cycle a "fire" :chore:solo: +CLOSED: [2026-07-28 Tue] +:PROPERTIES: +:LAST_REVIEWED: 2026-07-28 +:END: +Done 2026-07-28. 72 noun-sense instances in =sentry.org= became "cycle"; the four verb-sense uses stayed. Three more lived outside the file — =wrap-it-up.org= ("a crashed fire"), =todo-cleanup.el= and its test ("every sentry fire") — all naming a sentry cycle, so they moved too. home's proposal was scoped to =sentry.org= alone, so the leak would have split the vocabulary across files. + +Craig read home's "nine fires" as nine emergencies and went looking for what was burning (2026-07-28): "I assume you mean nine crises, not nine loop cycles and I begin to get scared." The term reaches him directly — digest headings render as =** Fire 11 — 08:32 CDT= in the anchor he reads every morning. 35 instances in =sentry.org=. + +Grading: Minor severity (a user-facing artifact that miscommunicates, no data loss) x most users frequently (every digest, on every project running sentry) = P3 = [#C]. + +*Take the problem, not home's proposed term.* home proposed "pass", reasoning that it already lives in the file's vocabulary. That is exactly what disqualifies it. =sentry.org= already uses "pass" as a precise numbered noun: "the pass list", "the Pass Runner", "eleven finding/hygiene passes", "pass 12" for the implementation pass. There are exactly eleven hygiene passes, so home's proposed digest heading =** Pass 11= collides with an existing real referent. Renaming would trade a term Craig misreads as urgent for one that is genuinely ambiguous. + +Counter-proposal: *cycle*. It appears zero times in =sentry.org=, so there is nothing to collide with. It is also Craig's own word from the very quote that surfaced this ("not nine loop cycles"). =** Cycle 11 — 08:32 CDT= reads cleanly. Checked and rejected: "sweep" (already used for hygiene and property sweeps) and "run" (already used as a noun, "first live run"). + +Keep the verb sense of fire throughout ("the notify fires", "the path never fires") — only the noun meaning one loop cycle changes. Past session anchors are historical records and stay as written. + +Craig approved "cycle" on 2026-07-28. That settles the only judgment the task carried, so it is =:solo:= now: the surface is the 35 noun-sense instances in =sentry.org=, and the completion check is objective — zero noun-sense "fire" left, verb sense untouched, lint clean, suite green, canonical and mirror in sync. + +Source: home handoff, 2026-07-28. +** DONE [#B] references/ is linked from protocols.org but never synced :bug: +CLOSED: [2026-07-28 Tue] +:PROPERTIES: +:LAST_REVIEWED: 2026-07-28 +:END: +Craig picked option 1 on 2026-07-28: drop the link, point at the calendar workflows instead. The four of them sync already and carry the MCP tool names, both account ids, the gcalcli fallback, and the conflict-check discipline — everything the reference was cited for. + +The adversarial review then returned =Needs Discussion= and widened the fix twice, both correctly: + +- My first replacement said credentials "live in the rulesets repo" without naming a file. The only calendar-named document there was =calendar-reference.org=, whose three credential paths have all been dead since the OAuth keys moved into the encrypted MCP bundle in May. So the prose sent a reader to a stale file, which fails more quietly than the dead link it replaced. Now names =mcp/README.org=, the real authority, verified to document =gcp-oauth.keys.json= as gitignored and regenerated at install. +- =calendar-reference.org= was left orphaned by the link removal: zero live inbound references, two copies, and =references/= is not in =sync-check.sh='s gate (=paths=(protocols.org workflows scripts)=), so the copies could drift silently. Deleted both, and the empty =references/= directories with them. Its operational content is fully covered by the four workflows and its credential paths were all stale, so nothing live was lost. + +The review also found the same defect class at seven other sites, filed separately. + +One fact died with the file, dropped deliberately rather than by accident: that the Google Cloud app runs in production mode, so tokens don't expire after seven days. It's checkable in the console, and it was the last live line in a document whose other credential facts had all gone stale. + +=protocols.org:273= links to =references/calendar-reference.org=, but startup.org's rsync copies only =protocols.org=, =workflows/=, and =scripts/=. So the link is dead in every consuming project. Confirmed: the file exists at =claude-templates/.ai/references/=, and neither home nor =.emacs.d= has a =.ai/references/= at all. + +Grading: Minor severity (a documented reference an agent can't follow, workaround is to search or ask) x every user every time (every consuming project, every sync) = P2 = [#B]. + +Pinned 2026-07-28 for Craig's decision. Analysis below is complete; only the choice is open. + +*Revised recommendation: drop the link, don't add the sync.* My first read was add =references/= to the rsync. Looking at what the directory actually holds reversed it: + +- =references/= holds exactly one file, and =protocols.org:273= is its only citation anywhere in the tree. +- The four calendar workflows (=add-=, =edit-=, =delete-=, =read-calendar-event(s).org=) already sync to every project, and already carry the operational detail: the MCP server name, both account IDs, the gcalcli fallback, conflict-checking. None of them cites =calendar-reference.org=; they are self-sufficient. +- What the reference uniquely adds is credential *file locations* (an OAuth keys path, a GPG-encrypted gcalcli secret) — no secret values. Re-auth is a rare operation Craig performs himself, not something an agent in another project needs a pointer to. + +So adding a synced directory carrying =--delete= semantics, to deliver one mostly-redundant file, is a poor trade. It also cuts against the rightsizing work: =protocols.org= is read into context every session, and a dead link is noise in a file being slimmed. + +Preferred fix: replace the link with a one-line pointer to the calendar workflows, which travel and are current. The reference file stays rulesets-only for the credential locations. + +Alternatives if Craig prefers: add =references/= to the rsync (the =--delete= hazard is not present today — work is the only project with a =.ai/references/= and its copy is byte-identical), or fold the credential locations into the calendar workflows and then drop the link (most complete, but spreads local absolute paths across four more synced files). + +Not =:solo:= — it changes a synced template, which needs Craig's approval by the inbox rule, and the sync-vs-drop choice is his. + +Source: winvm link-integrity pass, 2026-07-28. +** DONE [#B] Parked: telegram source treats "down" as launch, not SCAN FAILED (from .emacs.d) +CLOSED: [2026-07-28 Tue] +:PROPERTIES: +:LAST_REVIEWED: 2026-07-24 +:END: +Applied 2026-07-28, merged with the segfault root-cause fix that arrived the same morning rather than applied alone. + +Merging was necessary, not tidiness. The parked proposed file still carried the bad =(telega--loadChats 'main)= call at its own lines 52 and 122, so applying it as-is would have shipped a file that fixed the wording defect while preserving the call that kills the server. Its third hunk also added prose citing "tdlib segfaults in native mode (SEGFAULT gotcha below)" — pointing at the section the new handoff rewrites to say those deaths were our own bad argument, not tdlib memory corruption. + +What landed: all three parked hunks (the down-is-launch directive, the SCAN-FAILED-only-after-launch-attempted rewording, the =(setq telega-use-docker t)= restored to the Step 1 code block), plus both corrected =loadChats= call sites and the rewritten gotcha. The native-mode prose was reconciled in two places so it no longer leans on the refuted story: the Step 1 comment now states plainly that docker mode and the loadChats bug are separate concerns (the deaths happened *in* docker mode, so docker mode is neither a defense against it nor evidence for it), and the Quick Reference line says "crashed in native mode (2026-06-09)" instead of "segfaults", with the same disambiguation. + +Verified: both live call sites use the TL object; the two remaining ='main= occurrences are inside the gotcha prose describing the bug. lint-org clean, mirror synced, suite green. |
