diff options
Diffstat (limited to 'todo.org')
| -rw-r--r-- | todo.org | 163 |
1 files changed, 118 insertions, 45 deletions
@@ -58,64 +58,81 @@ Decisions settled with Craig, 2026-07-28, and shipped: Remaining: nothing on the design. The change shipped in this session. -** TODO [#C] start-work Phase 7 still summarizes the old publish flow :chore:solo: +** TODO [#B] wrap-org-table splits logical rows, and lint drives it :bug: :PROPERTIES: -:LAST_REVIEWED: 2026-07-28 +:LAST_REVIEWED: 2026-07-29 :END: -=.claude/commands/start-work.md:336-339= hands off with "Follow =commits.md= exactly" and "Run =/review-code --staged= before each commit" — no isolated reviewer, no re-review loop. It was already stale before the 2026-07-28 review change, because =commits.md= moved the publish flow into the =publish= skill in an earlier commit, so the pointer names a file that no longer holds the flow. +Reported by work 2026-07-28 against =arch-00-deepsat-platform-spec-draft.org=. Reproduced here. -Grading: Cosmetic severity (a stale summary beside a correct canonical, and start-work is attended so the escalation target exists) x most users frequently = P3 = [#C]. +*** Verified -Fix is to point Phase 7 at the =publish= skill rather than restate the flow, which is what let it drift in the first place. Worth a sweep for other files that restate the flow instead of pointing at it. +Each of these is a measurement, re-run under adversarial review. The analysis I built on top of them was wrong three times, so this section is deliberately separated from the open questions below. -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. +- *The defect.* =wrap-org-table.el= turns one logical table row into two or more, by writing a rule between its continuation lines. Content survives; structure does not. +- *Root cause.* =wot--continuation-group-p= (=wrap-org-table.el:168=) requires every line past the first to carry at least one empty cell. When a row overflows in every column its continuation line is fully populated, the predicate rejects the group, and =wot--logical-rows= appends each physical line as its own row (=:197=). +- *Controlled A/B.* Rules present in both, continuation line's middle cell the only variable: blank merges, populated splits. +- *Idempotence is broken.* Running the tool twice on its own correct output corrupts it. Pass 1 emits a properly rule-delimited three-line row; pass 2 splits it into three rows. The docstring at =:203-204= asserts the opposite, and =wot-reformat-is-idempotent= passes because its fixture overflows only one column. +- *lint doesn't just miss it, it causes it.* =lint-org.el:424= calls the same predicate. Given the tool's own correct output — a rule after every logical row — lint reports "missing rule between rows — wrap-org-table.el reflows it". Nothing is missing. Follow that advice and the tool splits the row; lint then reports the result 0 mechanical, 0 judgment. Control: a conformant table whose continuation keeps an empty cell returns 0 and 0. So the loop is not two independent green lights, it is the linter manufacturing a false violation and certifying the damage it caused. +- *A second path.* With no hlines at all, =wot--logical-rows= short-circuits (=:184=) before the predicate is reached, so every physical line becomes a row. +- *Nothing invokes the tool unattended.* =todo-cleanup.el= names it in comments only; the entry-script guard from the 2026-07-09 incident holds. +- *rulesets is exposed*: =todo.org= carries a four-row attachment-sanitization table with no rules between rows. Don't reflow it until the tool is fixed — reflowing is the trigger. -** 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. +*** Two fixes that were verified to work -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=. +- *Conformant round-trip.* Replacing the predicate body with =(> (length group) 1)= — pure rule-delimited grouping, no emitter marker, no new field — makes the corrupting pass-1 output round-trip cleanly. +- *Telling a continuation group from two real rows at runtime.* Provenance isn't available (=wot-reformat-table-string= receives a string), but the test is cheap: merge the group, re-wrap at the allocated widths, compare to the group as given. A continuation group reproduces itself under merge-then-wrap; two genuinely distinct short rows don't, because merged they fit on one line. -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]. +Start with a red test from the double-run repro — it needs no unusual input and falsifies the docstring and the passing idempotence test together. Emission is already correct (=:222-224= emits one rule per element of =rows=), so the repair is entirely in how =rows= is computed. -*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. +*Prefer the round-trip check to any detector.* work implemented the predicate-based detection I recommended and demonstrated it cannot discriminate at any threshold (2026-07-29, worked examples from their repo). Run bare it flags 144 files — essentially every table — because an ordinary header-plus-body table is one multi-line fully-populated group and rejecting it is the predicate working correctly. Add a per-row-ruled precondition and it cuts to 9, but at 9 it still mixes a genuinely wrapped row (=arch-09:40=, a header row whose second line continues the sentence) with two distinct rows legitimately sharing a rule (their =todo.org:117=, where splitting is the *right* answer). Same structural signature, opposite correct verdicts. The difference is whether one line continues the other as prose, which is semantics and not in the parse. -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"). +So =lint-org.el:424= cannot simply inherit the repair, and a checker keyed on the predicate would train people to ignore it. The idempotence property is the checkable one: reflow twice and diff. It sidesteps detection entirely, because round-tripping the tool's own output correctly is true by construction and needs nobody to decide what a group means. -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. +*** Open questions -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. +- *What should no-hline input do?* My "refuse to reflow" instruction was wrong: adding rules to a ruleless table is the tool's main job, and =test-wrap-org-table.el:147= asserts exactly that. The real danger is narrower — a no-hline table where some line carries an empty cell, so a physical line might be a continuation. Needs a decision on refuse, ask, or heuristic. +- *Which path bit work?* One question settles it: did the =arch-00= Document Status table have rules between its rows before the reflow? I inferred "probably secondary" from a file-level scan, which can't resolve a table-level incident. +- *How exposed is work?* Partly resolved by their own implementation, 2026-07-29. *Four secondary-path files are exact.* The primary-path number is 9 under a per-row-ruled precondition, which they correctly label a floor on a population they cannot cleanly define rather than a measurement — the precondition also drops the minimal =a_full= fixture, which has only two groups. My earlier "24 secondary-path files" certification was not sound: their original signature also matches every correctly-reflowed table, so it never partitioned. +- *Does the grade go up?* Currently Major x most users frequently = P2 = [#B] (any table you reflow that overflows every column, which is what a width violation sends you to the tool to fix). The lint-drives-it finding arrived after that grading and may lift it. -Source: home handoff, 2026-07-28. +*** Provenance -** TODO [#B] references/ is linked from protocols.org but never synced :bug: +work reverted their table and left it over-budget at 134 columns, correctly: an over-wide table is cosmetic, a table that says something else is not. I hit this same failure on 2026-07-27, wrote "reflowed a table into a worse shape and lint-org then passed it" into a session summary, and never filed it — which is why work met it three weeks later. Their framing beats the apology: a correct observation recorded and then read as fine is the same failure as a green check on a corrupted table. + +Process note for whoever picks this up. This task bounded out of its review loop at three rounds. Every finding across all three landed on inference, never on a measurement — the reproductions held throughout while the reasoning built on them was refuted repeatedly. Trust the Verified section; re-derive anything else. + + +** TODO [#B] Synced workflows link outside the synced set with ../../ :bug: :PROPERTIES: :LAST_REVIEWED: 2026-07-28 :END: -=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. +Seven link sites across four synced workflows, three distinct targets, all escaping the =.ai/= boundary into rulesets repo-root paths. From a consuming project's =.ai/workflows/=, =../../= is that project's root, where none of these exist: -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]. +- → =../../claude-rules/todo-format.md= (five sites): =open-tasks.org:163=, =task-audit.org:84=, =task-review.org:60=, =task-review.org:64=, =task-review.org:99= +- → =../../docs/design/task-review.org= (one site): =task-review.org:11= +- → =../../flush/SKILL.md= (one site): =suspend.org:22= -Pinned 2026-07-28 for Craig's decision. Analysis below is complete; only the choice is open. +Verified dead in both home and =.emacs.d=; they resolve only in rulesets, which is why nobody noticed. -*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: +Grading: Minor severity (a documented reference an agent can't follow, workaround is to search) x every user every time (every consuming project, every sync) = P2 = [#B]. Same grade as the =references/= link this came from, and the same mechanism — a synced file linking a path the sync doesn't deliver — with seven sites instead of one. -- =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. +Fix direction, two halves. Rewrite the seven as prose references naming the file, the same move taken for the credential paths: a link that resolves in one repo shouldn't be a link in a file that ships to two dozen. Then close the gate, or the eighth arrives unnoticed. -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. +The gate already exists and is nearly right. =scripts/lint.sh='s =check_md_links= was written for this exact class — its comment says so ("Validate cross-references to =claude-rules/= — the install-layout problem"). It misses these for two concrete reasons: it matches only markdown link syntax (=grep -oE '\[[^]]*\]\([^)]+\)'=), so org =[[file:...]]= links are invisible to it, and its driver loop only feeds it =claude-rules/*.md= and the language rule files, never =.ai/workflows/*.org=. Extending it on both axes is a smaller and more durable fix than a manual sweep. -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. +Found by the adversarial reviewer on the =references/= fix, 2026-07-28, as the sibling class the original report missed. -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). +** TODO [#C] start-work Phase 7 still summarizes the old publish flow :chore:solo: +:PROPERTIES: +:LAST_REVIEWED: 2026-07-28 +:END: +=.claude/commands/start-work.md:336-339= hands off with "Follow =commits.md= exactly" and "Run =/review-code --staged= before each commit" — no isolated reviewer, no re-review loop. It was already stale before the 2026-07-28 review change, because =commits.md= moved the publish flow into the =publish= skill in an earlier commit, so the pointer names a file that no longer holds the flow. -Not =:solo:= — it changes a synced template, which needs Craig's approval by the inbox rule, and the sync-vs-drop choice is his. +Grading: Cosmetic severity (a stale summary beside a correct canonical, and start-work is attended so the escalation target exists) x most users frequently = P3 = [#C]. -Source: winvm link-integrity pass, 2026-07-28. +Fix is to point Phase 7 at the =publish= skill rather than restate the flow, which is what let it drift in the first place. Worth a sweep for other files that restate the flow instead of pointing at it. + +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. ** TODO [#C] Two lint defects at the template source :chore: :PROPERTIES: @@ -227,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 @@ -2258,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. |
