diff options
| -rw-r--r-- | .ai/sessions/2026-05-16-12-35-task-review-spec-and-google-keep-mcp.org | 211 | ||||
| -rw-r--r-- | inbox/lint-followups.org | 15 |
2 files changed, 226 insertions, 0 deletions
diff --git a/.ai/sessions/2026-05-16-12-35-task-review-spec-and-google-keep-mcp.org b/.ai/sessions/2026-05-16-12-35-task-review-spec-and-google-keep-mcp.org new file mode 100644 index 0000000..67ad58c --- /dev/null +++ b/.ai/sessions/2026-05-16-12-35-task-review-spec-and-google-keep-mcp.org @@ -0,0 +1,211 @@ +#+TITLE: Session Context — inbox lint follow-ups + date-coverage walk +#+AUTHOR: Craig Jennings & Claude +#+DATE: 2026-05-16 + +* Summary + +** Active Goal + +Three arcs. (1) Absorb the morning's inbox handoff containing seven lint warnings plus eight date-coverage entries the wrap-it-up scan flagged on todo.org. (2) =/brainstorm= a recurring task-review habit so the date-coverage scan can retire — the scan was generating cleanup work because it was solving the wrong problem (assuming high-priority tasks need dates). (3) Install a Google Keep MCP server on both machines via the existing =mcp/= pipeline. + +** Decisions + +- *Defer the 8 date-coverage entries* to the first task-review cycle rather than walking them tonight — they'll be absorbed when the habit lands. Inbox handoff deleted; its other payloads (cj-comment lint suppression, line 2139 false positive) were either already fixed in =3fb4c80= or inspected and dismissed. +- *Brainstorm output: pure Emacs custom agenda + keystroke macros* (Approach B) over five other candidates. Rejected: Claude-driven command (heavy daily friction), hybrid Emacs+Claude (premature for v1), random sample (no coverage guarantee), write-time hook (silent on quiet weeks), section-rotating (uneven section sizes). +- *State model:* =:LAST_REVIEWED:= property drawer per top-level task; sort NIL-first so untouched tasks surface naturally; batch N=7 (~12-day cycle on ~80 open tasks). +- *Promote =task-review.org= to template-level* (canonical at =claude-templates/.ai/workflows/=, rsync'd to every project), with three trigger aliases in =INDEX.org=. Startup nudge stays project-specific via =startup-extras.org=. Wrap-up watchdog flips from "do all priorities have dates?" to "is the review habit happening?" at a 30-day threshold. +- *Google Keep MCP server: feuerdev/keep-mcp* via =uvx= over kud/mcp-google-keep (macOS Keychain) and davenicoll. Linux-friendly, env-var auth fits =secrets.env.gpg=, default-safe modification scope (only modifies notes carrying its =keep-mcp= label). +- *Master token retrieval: path #2 (DevTools EmbeddedSetup + gpsoauth.exchange_token).* Path #1 (password-based gpsoauth.perform_master_login) is restricted by Google since 2025. +- *Invocation workaround: =uvx --from keep-mcp python -m server.cli=.* The README's =pipx run keep-mcp= form doesn't translate cleanly to =uvx= — keep-mcp's =mcp= entry-point script collides with the official =mcp= SDK's same-named script (a transitive dep). Module-level invocation bypasses the collision. + +** Data Collected / Findings + +- =/lint-org --check= on =todo.org= post-=3fb4c80=: 0 mechanical, 1 judgment remaining (line 2139, =misplaced-heading=). The =3fb4c80= cj-comment suppression eliminated the six false positives at lines 16 and 1291. +- Line 2139 misplaced-heading is itself a false positive: =**= inside =...== verbatim markers (correctly wrapped). Leave alone. +- The wrap-it-up date-coverage scan is read-only — it doesn't modify =todo.org=, just appends candidates to the lint-followups file. The recurring noise comes from candidates piling up across wrap-ups without per-entry disposition. +- todo.org has ~80 open top-level =[#A]= / =[#B]= / =[#C]= tasks (children inherit parent priority and don't count as separate review units). +- keep-mcp package is on PyPI as =keep-mcp= 0.3.1 (= feuerdev/keep-mcp). Package's =[project.scripts]= declares =mcp = "server.cli:main"=; the module is literally =server= (not =keep_mcp=). +- MCP =initialize= handshake against =uvx --from keep-mcp python -m server.cli= returns =keep v1.27.1=, confirming the right entry point boots. +- =claude mcp list= on both machines reports =google-keep: ... ✓ Connected=. +- =ssh velox= from ratio resolves to tailscale (=100.127.238.103= via =velox.tailf3bb8c.ts.net=) but timed out from this session. =velox.local= via mDNS works once the host is up. +- velox needs explicit =PATH=$HOME/.local/bin:$PATH= prefix for non-interactive ssh — =uv= and =claude= both live there and aren't picked up by default. + +** Files Modified + +Three commits pushed to =origin/main=: + +- =70af2a0 chore(ai): sync lint-org and wrap-it-up from claude-templates= — Phase A startup picked up =3fb4c80= (cj-comment lint suppression) and =684891d= (LINT_ORG_FOLLOWUPS default to =./inbox/=) that hadn't propagated to the project mirror. +- =9c5aff1 feat(mcp): add google-keep server= — =mcp/servers.json= entry plus =mcp/secrets.env.gpg= reground with two new env vars. Body documents the entry-point-collision workaround for future archaeology. +- =daf960f docs(design): task-review spec + filed [#A] task= — new =docs/design/task-review.org= (~350 lines: problem, six approaches, recommended design, six chunks, open questions, six-step Next Steps). =todo.org= gains a top-of-section =[#A]= entry pointing at the spec. + +Working tree at wrap time: just =.ai/session-context.org= (becomes the session record via rename). + +** Next Steps + +- *Smoke test the keep MCP* after a Claude Code reload on either machine — Craig will return for this. +- *Implement the task-review spec.* Six components in order: (1) extract =task-review-staleness.sh= with bats tests, (2) replace date-coverage section in =wrap-it-up.org= with the health-check, (3) author =task-review.el= in archsetup with ERT tests, (4) author =task-review.org= workflow + INDEX entry, (5) add startup nudge to =.ai/project-workflows/startup-extras.org=, (6) smoke test. +- *Carryover from prior sessions remains:* =[#C]= consolidate =claude-templates/Makefile= post-fold, =[#C]= wrap-it-up Step 3.5 GitHub-family-remote assumption, =[#B]= Phase A inbox-scan blind to =claude-templates/inbox/=, =DOING [#A]= memory-sync (pending VERIFY on stow approach), =[#A]= =/update-skills= skill, =[#A]= =create-documentation= skill, =[#A]= 2026-05-04 audit review pass. + +* Session Log + +** Startup (08:58 CDT) + +Clean startup — no =session-context.org=, no cross-agent traffic, no Active +Reminders, no Pending Decisions. Template syncs ran clean. Read the 5 most +recent Summaries. Inbox had one file: +=2026-05-16-0512-from-work-lint-followups-handoff.org= — a re-routed payload +from the work project containing (a) seven lint warnings against +=rulesets/todo.org= and (b) eight =[#A]=/=[#B]= tasks without +=DEADLINE=/=SCHEDULED= flagged by wrap-it-up's date-coverage scan. + +Noted that two of the root causes the handoff calls out are already fixed: +=3fb4c80 feat(lint-org): recognize cj-comment blocks= (suppresses the +six line-16/line-1291 false positives) and =684891d fix(workflows): +default LINT_ORG_FOLLOWUPS to current project inbox= (the routing bug that +sent these to the wrong project's inbox in the first place). + +Craig picked option 1: re-run =/lint-org --check= to confirm the cj-comment +suppression, then walk line-2139 and the date-coverage list together. + +** Confirmed cj-comment suppression; line 2139 inspected + +=lint-org --check= on =todo.org=: 0 would-fix mechanical, 1 judgment +remaining (line 2139, =misplaced-heading=). All six cj-comment warnings +gone — =3fb4c80= confirmed working. + +Line 2139 is inside the body of a =** DONE [#B] Document startup +pull-ordering rule= entry. The text is =before proceeding" rule shipped +2026-05-15 in the =** Startup Pull Ordering== — the =**= sits inside +=...== verbatim markers and is correctly wrapped. False positive, leave +alone. + +** Pivot: /brainstorm on task-review habit (09:something CDT) + +Walked the eight date-coverage entries up to row 1; surfaced two +encoding-vs-design-intent tradeoffs (durable inline =# no-date by +intent= comment vs. closing-paragraph rationale that the operator +dismisses no-date in daily-prep, not in =todo.org=). Then read the awk +scan together and confirmed it doesn't modify =todo.org=, just appends +flagged candidates to =$followups=. + +Craig reframed: the whole org-lint date-coverage business is symptom of +a wrong assumption — that =[#A]=/=[#B]= tasks /need/ dates. They don't. +Some tasks are important without being time-bound. What's actually +needed is a regular habit of walking the task list, reverifying that +each task is still important, well-written, and actionable. With that +habit in place, the date-coverage scan becomes redundant and can be +retired. + +Invoked =/brainstorm=. Phase 1 question 1 asks about the failure mode +the habit should prevent (wrong priorities / vague entries / forgotten +entries / stale entries / all of the above). + +** Brainstorm output — task-review design + +Phase 1 close: /A daily 5-min review surfacing N oldest-unreviewed +top-level =[#A]= / =[#B]= / =[#C]= tasks for re-grade, kill, or light +prose touch — rotating through the list over weeks — until Craig +trusts the priorities and content of =todo.org= at a glance./ +Failure modes addressed in order: priority drift, stalled commitments, +prose decay. Success metric: trust (subjective), not throughput. + +Phase 2: 6 approaches considered (3 conventional, 3 tail). Picked +Approach B — pure Emacs custom agenda + keystroke macros. Rejected +Claude command (too heavy daily), hybrid (premature for v1), random +sample (no coverage guarantee), write-time hook (quiet weeks miss), +section-rotating (uneven section sizes). + +Phase 3 — design chunks walked + confirmed: +1. State model: =:LAST_REVIEWED:= property drawer per top-level task. +2. Architecture: single elisp file =task-review.el= in archsetup. +3. Selection: top-level =**=, open keywords, =[#A]=/=[#B]=/=[#C]=, + sort by =LAST_REVIEWED= asc, NIL first. Batch N=7 (~12-day cycle). +4. Keymap: =1=/=2=/=3=/=r=/=k=/=d=/=e=/=s=/=q=. Confirm on kill. +5. Retire date-coverage scan; replace with review-habit health check + in wrap-up. Threshold 30 days. Watchdog only — one line if stale. +6. Workflow promoted to template-level. =task-review.org= in + =claude-templates/.ai/workflows/=. INDEX trigger aliases: + =task review=, =review tasks=, =task-review=. Startup nudge + stays project-specific via =startup-extras.org=. Threshold 7 days. +7. Testing: ~20 ERT (data layer + actions), ~5 bats (staleness + script), manual smoke checklist. Extract staleness math to + =task-review-staleness.sh= as single source of truth. + +Design doc written to =docs/design/task-review.org= (used =.org= per +file-format preference, not =.md= as the brainstorm skill's default). + +Filed implementation task at =todo.org:10= → =** TODO [#A] Implement +task-review daily-habit per spec=, body links the spec + lists the +six implementation components. + +** Cleanup + +Inbox handoff =2026-05-16-0512-from-work-lint-followups-handoff.org= +deleted — signal fully absorbed: (a) cj-comment lint suppression +confirmed working post-=3fb4c80=; (b) line-2139 misplaced-heading +inspected as false positive (=**= inside =...== verbatim markers, +correctly wrapped, leave alone); (c) eight date-coverage entries +deferred — they'll be absorbed into the first task-review cycle once +the spec is implemented. The replacement health-check (threshold 30 +days at wrap-up, 7 days at startup) takes over the watchdog role. + +** Pivot: install Google Keep MCP server + +Brainstorm artifacts (=docs/design/task-review.org=, =todo.org= +=[#A]=, =.ai/session-context.org= log) all on disk. Working tree +has uncommitted changes — implementation deferred to a future +session via the filed task; brainstorm artifacts will commit at +wrap-up. Pivoting to new ask: install a Google Keep MCP server +into the existing =mcp/= pipeline. + +** Google Keep MCP install — ratio + +Picked =feuerdev/keep-mcp= (PyPI =keep-mcp= 0.3.1) over kud or +davenicoll. Reasons: =uvx= analogue of existing =npx -y= pattern, +env-var auth fits =secrets.env.gpg=, default-safe modification scope +(only modifies notes carrying its =keep-mcp= label), Linux-friendly. + +Master token retrieved via DevTools EmbeddedSetup flow (path #2 — +=accounts.google.com/EmbeddedSetup= → =oauth_token= cookie → +=gpsoauth.exchange_token=). Token stored in =mcp/secrets.env.gpg= +as =GOOGLE_KEEP_MASTER_TOKEN=, with =GOOGLE_KEEP_EMAIL= set to +=craigmartinjennings@gmail.com=. Re-encrypted via symmetric +=gpg -c --cipher-algo AES256=, plaintext lived only in =/dev/shm= +and was =shred=-deleted. + +Invocation gotcha: =uvx --from keep-mcp mcp= resolved to the +official =mcp= SDK CLI (shipped as a dependency of =keep-mcp= and +shadowing keep-mcp's own =mcp= entry-point script). Verified via +=server.cli= module-invoke: =uvx --from keep-mcp python -m server.cli= +boots cleanly and answers an MCP =initialize= handshake as =keep +v1.27.1=. Final =servers.json= entry uses that =python -m server.cli= +form, not the README's =pipx run keep-mcp= form. + +Working tree state at this point: +- =mcp/servers.json= — modified (new =google-keep= entry). +- =mcp/secrets.env.gpg= — modified (new ciphertext after symmetric + re-encrypt with the two added env vars). +- =mcp/gcp-oauth.keys.json= — touched by =install.py= (pre-existing, + decrypted by install regardless). + +=claude mcp list= verified: =google-keep: uvx --from keep-mcp python +-m server.cli - ✓ Connected=. + +Velox install pending: needs the new commits pushed to =origin/main=, +then ssh + pull + =python mcp/install.py= on velox to register +locally there. Velox already has =uv= per recent activity. + +** Commits + push + +Three commits landed on =origin/main=: +- =70af2a0 chore(ai): sync lint-org and wrap-it-up from claude-templates= — Phase A startup brought in the canonical =3fb4c80= (cj-comment lint suppression) and =684891d= (LINT_ORG_FOLLOWUPS default fix) deltas that hadn't yet propagated to the project mirror. +- =9c5aff1 feat(mcp): add google-keep server= — adds =google-keep= to =servers.json= via =uvx --from keep-mcp python -m server.cli=, with the entry-point-collision rationale in the body. =secrets.env.gpg= grew two vars. +- =daf960f docs(design): task-review spec + filed [#A] task= — the brainstorm output, plus the implementation task at =todo.org:10=. + +Pre-push reconcile 0/4, push clean. + +** Velox install + +First attempt failed because non-interactive ssh has no DISPLAY and no TTY — gpg pinentry-gtk silently cancelled. Retried with =ssh -t velox.local= and =GPG_TTY=$(tty)=. The "pseudo-terminal will not be allocated" warning fired (Bash tool subprocess has no TTY to allocate) but pinentry did pop a dialog on velox — Craig didn't notice it for a moment, then answered. Install ran cleanly; =claude mcp list= verified =google-keep: ... ✓ Connected=. + +Reaching velox: =ssh velox= timed out (resolved to tailscale IP =100.127.238.103= via =velox.tailf3bb8c.ts.net=, but that route was unreachable from this session). =velox.local= via mDNS worked once Craig confirmed the host was up. diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org new file mode 100644 index 0000000..b87722a --- /dev/null +++ b/inbox/lint-followups.org @@ -0,0 +1,15 @@ + +* 2026-05-16 lint-org follow-ups — todo.org +** TODO line 2153 — misplaced-heading — Possibly misplaced heading line + +* 2026-05-16 Sat — Date coverage: [#A] / [#B] tasks without DEADLINE or SCHEDULED +Review each: add a date, drop the priority, or confirm 'no-date by intent' inline. +- 10: ** TODO [#A] Implement task-review daily-habit per spec +- 28: ** DOING [#A] Check that memories are sync'd across machines via git.m +- 58: ** TODO [#A] Build =create-documentation= skill for high-quality project/product docs +- 692: ** TODO [#A] Review pass: tighten skills and rulesets after 2026-05-04 audit +- 1221: ** TODO [#B] Build =ov-1= skill for DoDAF OV-1 (High-Level Operational Concept Graphic) +- 1295: ** TODO [#A] Build =/update-skills= skill for keeping forks in sync with upstream +- 1621: ** TODO [#B] Add =make remove= for interactive ruleset removal via fzf +- 1686: ** TODO [#B] Document the =mcp/= install pipeline in =mcp/README.org= +- 1773: ** TODO [#B] Phase A startup blind to =claude-templates/inbox/= post-fold :bug:fold: |
