aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-31 18:15:03 -0500
committerCraig Jennings <c@cjennings.net>2026-05-31 18:15:03 -0500
commit18f6c4c877940d740406b859f61a540fc48f13f5 (patch)
tree0096f8e661a7c22af3037528e8923da63d757a42
parentaee7793ddf1802c1574c2d23bf5acd823e7eba1e (diff)
downloadrulesets-18f6c4c877940d740406b859f61a540fc48f13f5.tar.gz
rulesets-18f6c4c877940d740406b859f61a540fc48f13f5.zip
fix(workflows): commit template-sync churn deterministically
Phase A's startup rsync copies template updates from rulesets into each project's .ai/, but nothing committed that churn, so it accumulated across sessions and eventually blocked Phase A.0's auto-fast-forward (git won't ff a dirty tree). Two projects hit it the same day. I added a Step 4.0 to wrap-it-up.org that commits the churn as its own chore commit before the session-work commit, guarded so it only auto-commits synced .ai paths matching rulesets canonical byte-for-byte and surfaces anything that doesn't. startup.org Phase C now surfaces leftover churn at session start as the crashed-session safety net. Both skip the rulesets repo, where .ai/ is a committed mirror. I also moved four misplaced PROPERTIES drawers in todo.org (DONE tasks) from after the resolution prose to immediately under the CLOSED line, so org parses them as real drawers.
-rw-r--r--.ai/notes.org2
-rw-r--r--.ai/workflows/startup.org10
-rw-r--r--.ai/workflows/wrap-it-up.org41
-rw-r--r--claude-templates/.ai/workflows/startup.org10
-rw-r--r--claude-templates/.ai/workflows/wrap-it-up.org41
-rw-r--r--inbox/lint-followups.org6
-rw-r--r--todo.org12
7 files changed, 109 insertions, 13 deletions
diff --git a/.ai/notes.org b/.ai/notes.org
index 216712f..68ce3fb 100644
--- a/.ai/notes.org
+++ b/.ai/notes.org
@@ -79,6 +79,6 @@ Format:
Markers maintained by workflows to record when they last ran. Read by other workflows that gate their behavior on freshness.
:LAST_AUDIT: 2026-05-28
-:LAST_INBOX_PROCESS: 2026-05-30
+:LAST_INBOX_PROCESS: 2026-05-31
Format: one =:MARKER: YYYY-MM-DD= line per workflow. Workflows overwrite their own marker on completion.
diff --git a/.ai/workflows/startup.org b/.ai/workflows/startup.org
index c08bd8a..16e983d 100644
--- a/.ai/workflows/startup.org
+++ b/.ai/workflows/startup.org
@@ -166,6 +166,16 @@ This phase touches the user and runs sequentially:
- Briefly note significant template updates noticed during sync (new workflows, protocol changes).
- *Task-review nudge.* If the Phase A staleness count (step 11) is greater than zero, surface one line: "=<N>= top-level tasks unreviewed for >7 days — say 'let's do a task review' to run a cycle." If zero, say nothing.
- *Language-bundle sync.* If the Phase A step-12 call (=sync-language-bundle.sh=) printed anything, surface it. =fixed= lines are informational — the drift was already repaired (note that =.claude/= is now dirty if the project commits it). A =drift= line on =settings.json= is surface-only and needs the printed =make install-<lang> PROJECT=.= to reconcile; flag it so the user can decide. If the call was silent, say nothing.
+ - *Template-sync churn (safety net).* Check whether Phase A's rsync left uncommitted churn in the synced =.ai/= paths — accumulated from a prior session that crashed before wrap-up, or freshly added this session when rulesets advanced. Without surfacing, it builds up silently until it blocks Phase A.0's auto-ff (git won't ff a dirty tree). Skip in the rulesets repo itself (there =.ai/= is a committed mirror, kept honest by the pre-commit hook). The check is sequential here, after the rsync has finished — not a Phase A step, to keep that batch race-free.
+
+ #+begin_src bash
+ if [ ! -d claude-templates/.ai ] && [ -d "$HOME/code/rulesets/claude-templates/.ai" ]; then
+ n=$(git status --porcelain -- .ai/protocols.org .ai/workflows/ .ai/scripts/ 2>/dev/null | wc -l)
+ [ "$n" -gt 0 ] && echo "synced-.ai-dirty: $n uncommitted template-sync file(s)"
+ fi
+ #+end_src
+
+ If it reports a count, surface one line: wrap-up's Step 4.0 will commit it as =chore: sync .ai tooling from templates=, or offer to commit it now. If silent, say nothing. This is the crashed-session counterpart to the wrap-up commit step (the primary fix). From the 2026-05-31 jr-estate + work handoffs.
- *Surface pending cross-agent messages.* If =cross-agent-status= reported any pending messages, list them with their =cross-agent-recv= decision (process / query / reject) per file. For =process= messages in this project's inbox, propose handling now or after the current task. For pending in other projects, mention the count so the user knows to switch projects when ready. If HALT was active, surface that prominently — cross-agent activity is paused until =cross-agent-resume= clears it.
2. *Process inbox if non-empty.* Mandatory — don't ask, just delegate to [[file:process-inbox.org][process-inbox.org]]. That workflow owns the value gate (advances an existing TODO / improves the project / serves the mission), the per-source rejection flow (Craig / project handoff / script), the priority-scheme check before filing, and the =.eml= extraction path. Single source of truth for the discipline.
3. *Execute project-specific startup extras* (the contents of =.ai/project-workflows/startup-extras.org= read in Phase A). If the file didn't exist, skip.
diff --git a/.ai/workflows/wrap-it-up.org b/.ai/workflows/wrap-it-up.org
index 7fc86e4..593cb93 100644
--- a/.ai/workflows/wrap-it-up.org
+++ b/.ai/workflows/wrap-it-up.org
@@ -254,6 +254,46 @@ Skip the step entirely if the project doesn't use Linear (e.g. personal projects
** Step 4: Git commit + push
+*** Step 4.0: Commit template-sync churn first (consuming projects)
+
+The startup workflow's Phase A rsyncs template updates from rulesets into this project's =.ai/= (=protocols.org=, =workflows/=, =scripts/=) every session that rulesets has advanced. Nothing commits that churn, so without this step it accumulates across sessions and eventually blocks Phase A.0's auto-fast-forward (git refuses to ff a dirty tree). Commit it here, as its own =chore:= commit, before the session-work commit — so the sync stays separate from what the session actually shipped and the tree ends clean.
+
+The guard is conservative: only auto-commit a dirty synced path when it matches the rulesets canonical byte-for-byte (a modified/new file equals canonical, or a deletion pairs with a file retired upstream). If any synced path is dirty but /doesn't/ match canonical — a local hand-edit to a file that's supposed to be sync-managed — surface it and don't auto-commit. Anything outside the three synced paths is untouched here; the normal Step 4 commit and the worktree-leftover step handle it.
+
+#+begin_src bash
+# Skip in the rulesets repo itself: there .ai/ is a committed mirror of
+# claude-templates/.ai/, kept in sync by the pre-commit hook and committed
+# alongside template edits — not downstream sync churn. The presence of
+# claude-templates/.ai/ in this repo is the tell.
+if [ ! -d claude-templates/.ai ] && [ -d "$HOME/code/rulesets/claude-templates/.ai" ]; then
+ canon="$HOME/code/rulesets/claude-templates/.ai"
+ safe=1
+ commitlist=()
+ while IFS= read -r line; do
+ f="${line:3}" # strip the 2-char status + space
+ rel="${f#.ai/}"
+ if [ -e "$f" ] && [ -e "$canon/$rel" ] && diff -q "$f" "$canon/$rel" >/dev/null 2>&1; then
+ commitlist+=("$f") # modified/new here, matches canonical
+ elif [ ! -e "$f" ] && [ ! -e "$canon/$rel" ]; then
+ commitlist+=("$f") # deleted here AND retired upstream
+ else
+ safe=0 # synced path dirty but != canonical
+ fi
+ done < <(git status --porcelain -- .ai/protocols.org .ai/workflows/ .ai/scripts/)
+
+ if [ "$safe" -eq 1 ] && [ "${#commitlist[@]}" -gt 0 ]; then
+ git add -- "${commitlist[@]}"
+ git commit -q -m "chore: sync .ai tooling from templates"
+ echo "wrap-up: committed ${#commitlist[@]} synced .ai file(s) as a template-sync chore."
+ elif [ "$safe" -eq 0 ]; then
+ echo "wrap-up: synced .ai paths are dirty but not all match rulesets canonical — NOT auto-committing. Resolve manually:"
+ git status --porcelain -- .ai/protocols.org .ai/workflows/ .ai/scripts/ | sed 's/^/ /'
+ fi
+fi
+#+end_src
+
+The commit isn't pushed here — the push step below pushes the current branch, which carries both this chore commit and the session-work commit. A crashed session that never reaches wrap-up leaves the churn for the next startup, which surfaces it (see startup.org Phase C) so it never silently accumulates.
+
*** Review changes
#+begin_src bash
@@ -421,6 +461,7 @@ Before considering wrap-up complete:
- [ ] Any orphan-planning-line warnings reviewed (fix or accept)
- [ ] Inbox carries nothing but expected pipeline artifacts (=.gitkeep=, =lint-followups.org=, =PROCESSED-*= prefixes), OR each remaining handoff has an explicit deferral logged in the valediction
- [ ] Linear Dev-Review sweep ran; any merged-PR tickets moved to Done or PM Acceptance (skip if project doesn't use Linear)
+- [ ] Template-sync churn committed as its own =chore: sync .ai tooling from templates= (consuming projects only; skipped in rulesets), or surfaced if a synced path didn't match canonical
- [ ] After wrap-up commit + push, =git status --short= is empty OR every remaining line has an explicit user-deferred decision logged in the valediction
- [ ] Each leftover was investigated and the user saw a concrete resolution recommendation
- [ ] Runtime artifacts added to =.gitignore=, follow-up commit pushed, =git status= re-verified
diff --git a/claude-templates/.ai/workflows/startup.org b/claude-templates/.ai/workflows/startup.org
index c08bd8a..16e983d 100644
--- a/claude-templates/.ai/workflows/startup.org
+++ b/claude-templates/.ai/workflows/startup.org
@@ -166,6 +166,16 @@ This phase touches the user and runs sequentially:
- Briefly note significant template updates noticed during sync (new workflows, protocol changes).
- *Task-review nudge.* If the Phase A staleness count (step 11) is greater than zero, surface one line: "=<N>= top-level tasks unreviewed for >7 days — say 'let's do a task review' to run a cycle." If zero, say nothing.
- *Language-bundle sync.* If the Phase A step-12 call (=sync-language-bundle.sh=) printed anything, surface it. =fixed= lines are informational — the drift was already repaired (note that =.claude/= is now dirty if the project commits it). A =drift= line on =settings.json= is surface-only and needs the printed =make install-<lang> PROJECT=.= to reconcile; flag it so the user can decide. If the call was silent, say nothing.
+ - *Template-sync churn (safety net).* Check whether Phase A's rsync left uncommitted churn in the synced =.ai/= paths — accumulated from a prior session that crashed before wrap-up, or freshly added this session when rulesets advanced. Without surfacing, it builds up silently until it blocks Phase A.0's auto-ff (git won't ff a dirty tree). Skip in the rulesets repo itself (there =.ai/= is a committed mirror, kept honest by the pre-commit hook). The check is sequential here, after the rsync has finished — not a Phase A step, to keep that batch race-free.
+
+ #+begin_src bash
+ if [ ! -d claude-templates/.ai ] && [ -d "$HOME/code/rulesets/claude-templates/.ai" ]; then
+ n=$(git status --porcelain -- .ai/protocols.org .ai/workflows/ .ai/scripts/ 2>/dev/null | wc -l)
+ [ "$n" -gt 0 ] && echo "synced-.ai-dirty: $n uncommitted template-sync file(s)"
+ fi
+ #+end_src
+
+ If it reports a count, surface one line: wrap-up's Step 4.0 will commit it as =chore: sync .ai tooling from templates=, or offer to commit it now. If silent, say nothing. This is the crashed-session counterpart to the wrap-up commit step (the primary fix). From the 2026-05-31 jr-estate + work handoffs.
- *Surface pending cross-agent messages.* If =cross-agent-status= reported any pending messages, list them with their =cross-agent-recv= decision (process / query / reject) per file. For =process= messages in this project's inbox, propose handling now or after the current task. For pending in other projects, mention the count so the user knows to switch projects when ready. If HALT was active, surface that prominently — cross-agent activity is paused until =cross-agent-resume= clears it.
2. *Process inbox if non-empty.* Mandatory — don't ask, just delegate to [[file:process-inbox.org][process-inbox.org]]. That workflow owns the value gate (advances an existing TODO / improves the project / serves the mission), the per-source rejection flow (Craig / project handoff / script), the priority-scheme check before filing, and the =.eml= extraction path. Single source of truth for the discipline.
3. *Execute project-specific startup extras* (the contents of =.ai/project-workflows/startup-extras.org= read in Phase A). If the file didn't exist, skip.
diff --git a/claude-templates/.ai/workflows/wrap-it-up.org b/claude-templates/.ai/workflows/wrap-it-up.org
index 7fc86e4..593cb93 100644
--- a/claude-templates/.ai/workflows/wrap-it-up.org
+++ b/claude-templates/.ai/workflows/wrap-it-up.org
@@ -254,6 +254,46 @@ Skip the step entirely if the project doesn't use Linear (e.g. personal projects
** Step 4: Git commit + push
+*** Step 4.0: Commit template-sync churn first (consuming projects)
+
+The startup workflow's Phase A rsyncs template updates from rulesets into this project's =.ai/= (=protocols.org=, =workflows/=, =scripts/=) every session that rulesets has advanced. Nothing commits that churn, so without this step it accumulates across sessions and eventually blocks Phase A.0's auto-fast-forward (git refuses to ff a dirty tree). Commit it here, as its own =chore:= commit, before the session-work commit — so the sync stays separate from what the session actually shipped and the tree ends clean.
+
+The guard is conservative: only auto-commit a dirty synced path when it matches the rulesets canonical byte-for-byte (a modified/new file equals canonical, or a deletion pairs with a file retired upstream). If any synced path is dirty but /doesn't/ match canonical — a local hand-edit to a file that's supposed to be sync-managed — surface it and don't auto-commit. Anything outside the three synced paths is untouched here; the normal Step 4 commit and the worktree-leftover step handle it.
+
+#+begin_src bash
+# Skip in the rulesets repo itself: there .ai/ is a committed mirror of
+# claude-templates/.ai/, kept in sync by the pre-commit hook and committed
+# alongside template edits — not downstream sync churn. The presence of
+# claude-templates/.ai/ in this repo is the tell.
+if [ ! -d claude-templates/.ai ] && [ -d "$HOME/code/rulesets/claude-templates/.ai" ]; then
+ canon="$HOME/code/rulesets/claude-templates/.ai"
+ safe=1
+ commitlist=()
+ while IFS= read -r line; do
+ f="${line:3}" # strip the 2-char status + space
+ rel="${f#.ai/}"
+ if [ -e "$f" ] && [ -e "$canon/$rel" ] && diff -q "$f" "$canon/$rel" >/dev/null 2>&1; then
+ commitlist+=("$f") # modified/new here, matches canonical
+ elif [ ! -e "$f" ] && [ ! -e "$canon/$rel" ]; then
+ commitlist+=("$f") # deleted here AND retired upstream
+ else
+ safe=0 # synced path dirty but != canonical
+ fi
+ done < <(git status --porcelain -- .ai/protocols.org .ai/workflows/ .ai/scripts/)
+
+ if [ "$safe" -eq 1 ] && [ "${#commitlist[@]}" -gt 0 ]; then
+ git add -- "${commitlist[@]}"
+ git commit -q -m "chore: sync .ai tooling from templates"
+ echo "wrap-up: committed ${#commitlist[@]} synced .ai file(s) as a template-sync chore."
+ elif [ "$safe" -eq 0 ]; then
+ echo "wrap-up: synced .ai paths are dirty but not all match rulesets canonical — NOT auto-committing. Resolve manually:"
+ git status --porcelain -- .ai/protocols.org .ai/workflows/ .ai/scripts/ | sed 's/^/ /'
+ fi
+fi
+#+end_src
+
+The commit isn't pushed here — the push step below pushes the current branch, which carries both this chore commit and the session-work commit. A crashed session that never reaches wrap-up leaves the churn for the next startup, which surfaces it (see startup.org Phase C) so it never silently accumulates.
+
*** Review changes
#+begin_src bash
@@ -421,6 +461,7 @@ Before considering wrap-up complete:
- [ ] Any orphan-planning-line warnings reviewed (fix or accept)
- [ ] Inbox carries nothing but expected pipeline artifacts (=.gitkeep=, =lint-followups.org=, =PROCESSED-*= prefixes), OR each remaining handoff has an explicit deferral logged in the valediction
- [ ] Linear Dev-Review sweep ran; any merged-PR tickets moved to Done or PM Acceptance (skip if project doesn't use Linear)
+- [ ] Template-sync churn committed as its own =chore: sync .ai tooling from templates= (consuming projects only; skipped in rulesets), or surfaced if a synced path didn't match canonical
- [ ] After wrap-up commit + push, =git status --short= is empty OR every remaining line has an explicit user-deferred decision logged in the valediction
- [ ] Each leftover was investigated and the user saw a concrete resolution recommendation
- [ ] Runtime artifacts added to =.gitignore=, follow-up commit pushed, =git status= re-verified
diff --git a/inbox/lint-followups.org b/inbox/lint-followups.org
deleted file mode 100644
index b581f80..0000000
--- a/inbox/lint-followups.org
+++ /dev/null
@@ -1,6 +0,0 @@
-
-* 2026-05-31 lint-org follow-ups — todo.org
-** TODO line 2418 — obsolete-properties-drawer — Incorrect contents for PROPERTIES drawer
-** TODO line 2335 — obsolete-properties-drawer — Incorrect contents for PROPERTIES drawer
-** TODO line 2321 — obsolete-properties-drawer — Incorrect contents for PROPERTIES drawer
-** TODO line 2304 — obsolete-properties-drawer — Incorrect contents for PROPERTIES drawer
diff --git a/todo.org b/todo.org
index 968aaaf..f28aad9 100644
--- a/todo.org
+++ b/todo.org
@@ -2300,10 +2300,10 @@ Verification: simulate two agents sharing a project (separate AI_AGENT_ID values
Parent: see [[Generic agent runtime support — Codex spec v0]] above for the larger arc this is sliced from.
** DONE [#C] Decide on category-3 rule copies in the deepsat tree :chore:quick:solo:
CLOSED: [2026-05-31 Sun]
-Diffed 2026-05-31. Both copies (coding-rulesets vendored + orchestration_dashboard_mvp) are byte-identical to each other and stale against canonical: =testing.md= 221 lines behind with 5 lines unique to the copies (older wording or a small team tweak), =verification.md= 40 behind with nothing unique. Same older vendored version in both spots. Left untouched per the A1 decision — team-owned, and canonicalizing would create a cross-repo dependency on the private rulesets (the orchestration_dashboard_mvp pair is team-visible from Vrezh's PR thread). No files modified.
:PROPERTIES:
:LAST_REVIEWED: 2026-05-28
:END:
+Diffed 2026-05-31. Both copies (coding-rulesets vendored + orchestration_dashboard_mvp) are byte-identical to each other and stale against canonical: =testing.md= 221 lines behind with 5 lines unique to the copies (older wording or a small team tweak), =verification.md= 40 behind with nothing unique. Same older vendored version in both spots. Left untouched per the A1 decision — team-owned, and canonicalizing would create a cross-repo dependency on the private rulesets (the orchestration_dashboard_mvp pair is team-visible from Vrezh's PR thread). No files modified.
While symlinking personal-project =.claude/rules/= mirrors to the rulesets canonical on 2026-05-07, two locations didn't fit the "personal mirror → symlink" pattern and were left untouched pending judgment:
@@ -2315,12 +2315,12 @@ For each: read the file, diff against the rulesets canonical, decide whether it'
Decision (Craig, 2026-05-31): *leave team-tree copies alone.* Personal rulesets does not reach into team repos — canonicalizing would create a cross-repo dependency on the private rulesets, and the orchestration_dashboard_mvp copy is team-visible. This makes the task solo: diff each copy against canonical, record whether it's identical / drifted / overridden in the disposition, and close as "left alone (team-owned)" without modifying the team-tree files.
** DONE [#C] Audit language-specific rule files for cross-project duplication :chore:solo:
CLOSED: [2026-05-31 Sun]
-Audited 2026-05-31. Findings: in sync with canonical (=languages/<lang>/claude/rules/=) — work =python-testing.md=, deepsat =typescript-testing.md=, =.emacs.d= =elisp-testing.md= + =elisp.md=. Drifted — =gloss= and =chime= (byte-identical to each other): =elisp-testing.md= 44 lines behind (canonical added Batch-Mode Reproducibility + Isolating Emacs State; zero lines unique to the copies), =elisp.md= one line behind (canonical expanded the edit-cohesively guidance). No project-specific additions anywhere — every copy is either current or purely stale.
-
-Disposition: *leave them project-local* (the task's own option). The language-rule copies in code projects are the bundle's deliberate copy-and-sync model, not the symlink pattern the generic rules (commits/testing/verification/subagents) use in personal doc-projects. =sync-language-bundle.sh= auto-fixes drifted bundle rules on each startup, so gloss/chime self-heal the moment those projects next boot — no canonicalize/symlink needed, and symlinking would fight the bundle model. Did not reach into work/deepsat/gloss/chime/.emacs.d from here (cross-project boundary; team copies left alone per the 2026-05-31 category-3 decision).
:PROPERTIES:
:LAST_REVIEWED: 2026-05-28
:END:
+Audited 2026-05-31. Findings: in sync with canonical (=languages/<lang>/claude/rules/=) — work =python-testing.md=, deepsat =typescript-testing.md=, =.emacs.d= =elisp-testing.md= + =elisp.md=. Drifted — =gloss= and =chime= (byte-identical to each other): =elisp-testing.md= 44 lines behind (canonical added Batch-Mode Reproducibility + Isolating Emacs State; zero lines unique to the copies), =elisp.md= one line behind (canonical expanded the edit-cohesively guidance). No project-specific additions anywhere — every copy is either current or purely stale.
+
+Disposition: *leave them project-local* (the task's own option). The language-rule copies in code projects are the bundle's deliberate copy-and-sync model, not the symlink pattern the generic rules (commits/testing/verification/subagents) use in personal doc-projects. =sync-language-bundle.sh= auto-fixes drifted bundle rules on each startup, so gloss/chime self-heal the moment those projects next boot — no canonicalize/symlink needed, and symlinking would fight the bundle model. Did not reach into work/deepsat/gloss/chime/.emacs.d from here (cross-project boundary; team copies left alone per the 2026-05-31 category-3 decision).
The four canonical rules (=commits=, =testing=, =verification=, =subagents=) are now symlinked across the five personal-project mirrors as of 2026-05-07. But several language-specific rule files exist in multiple project mirrors and may be duplicated or drifted:
@@ -2331,10 +2331,10 @@ The four canonical rules (=commits=, =testing=, =verification=, =subagents=) are
The Elisp pair is the most suspicious — three repos using essentially the same rules. Audit: diff these across the projects, check for drift, then decide whether to canonicalize them under =~/code/rulesets/claude-rules/languages/<lang>/= and symlink, or leave them as project-local.
** DONE [#C] Refactor =daily-prep.org= to delegate to =triage-intake.org= for the triage section :chore:solo:
CLOSED: [2026-05-31 Sun]
-Collapsed Phase 3's inline source scans (sub-steps 3b email / 3c mark-read / 3d Slack / 3e Linear / 3f PRs / 3g dedup, ~280 lines) into four: 3b runs the triage-intake engine, 3c surfaces today's reactive items as Day's Priorities thin links, 3d re-sorts by urgency, 3e writes the audit footer from the engine's coverage. Source coverage carries via the engine's Phase 0 two-dir glob (general + .ai/project-workflows/ plugins), so the work account's Gmail/Slack/Linear/GHE plugins still get scanned. Adapted the downstream refs (Prep Doc Structure rule, Heads-up FYI source, Recommended Approach Pattern reframed as engine-applied), removed the orphaned Linear-digest note, added a Living Document entry. Verified: workflow-integrity clean (no dangling script refs), sync-check clean, full suite green. daily-prep.org went 825 → 576 lines.
:PROPERTIES:
:LAST_REVIEWED: 2026-05-28
:END:
+Collapsed Phase 3's inline source scans (sub-steps 3b email / 3c mark-read / 3d Slack / 3e Linear / 3f PRs / 3g dedup, ~280 lines) into four: 3b runs the triage-intake engine, 3c surfaces today's reactive items as Day's Priorities thin links, 3d re-sorts by urgency, 3e writes the audit footer from the engine's coverage. Source coverage carries via the engine's Phase 0 two-dir glob (general + .ai/project-workflows/ plugins), so the work account's Gmail/Slack/Linear/GHE plugins still get scanned. Adapted the downstream refs (Prep Doc Structure rule, Heads-up FYI source, Recommended Approach Pattern reframed as engine-applied), removed the orphaned Linear-digest note, added a Living Document entry. Verified: workflow-integrity clean (no dangling script refs), sync-check clean, full suite green. daily-prep.org went 825 → 576 lines.
=daily-prep.org= still does its own inline triage (Gmail × 3 accounts, Slack, Linear, GHE PRs, calendars) as part of the full prep flow. =triage-intake.org= is now a source-agnostic engine that loads =triage-intake.<source>.org= plugins (refactored 2026-05-26), so daily-prep could call the engine and consume its synthesis instead of duplicating the source-scan logic. That DRYs up a large workflow and keeps both flows in sync when sources change — a source change now lives in one plugin that both flows pick up.
@@ -2414,11 +2414,11 @@ Three wins: handoff is one paste not a re-read; forces specs to be implementable
If the spec lacks an =Implementation phases= section, the step is the prompt to ask the author to add one before =Ready=.
** DONE [#C] Add =.aiignore= for agent inventory exclusions :chore:solo:
CLOSED: [2026-05-31 Sun]
-Shipped a gitignore-syntax =.aiignore= at the rulesets root (deps, build output, language caches, editor cruft, token artifacts, lockfiles-as-agent-read-skip) and documented the convention + defaults + lockfile policy in protocols.org ("Recursive Reads"). Per Craig's scope call (2026-05-31): did NOT wire audit.sh / diff-lang.sh / sync-language-bundle.sh — they do targeted finds over .ai/.claude/bundle dirs, never naive whole-tree walks, so honoring .aiignore there would be dead code. Script-side honoring belongs in a future catalog/inventory tool if one ships; the real consumer today is agent recursive reads (the protocols guidance).
:PROPERTIES:
:CREATED: [2026-05-28 Thu]
:LAST_REVIEWED: 2026-05-28
:END:
+Shipped a gitignore-syntax =.aiignore= at the rulesets root (deps, build output, language caches, editor cruft, token artifacts, lockfiles-as-agent-read-skip) and documented the convention + defaults + lockfile policy in protocols.org ("Recursive Reads"). Per Craig's scope call (2026-05-31): did NOT wire audit.sh / diff-lang.sh / sync-language-bundle.sh — they do targeted finds over .ai/.claude/bundle dirs, never naive whole-tree walks, so honoring .aiignore there would be dead code. Script-side honoring belongs in a future catalog/inventory tool if one ships; the real consumer today is agent recursive reads (the protocols guidance).
From the codex enhancement backlog (item #8). Filesystem scans by agents and helper scripts pick up =node_modules=, =__pycache__=, =.pytest_cache=, lockfiles, generated OAuth artifacts, and test caches, even when those are gitignored. Token waste during exploration and skewed project summaries.