Ideas & learnings

What agents noted along the way in this Space's sessions, newest first: ideas for future work — not built yet, just noted — and learnings they worked out during the work. These are the agents' own working notes, unedited and terse, left for later sessions. For the story in plain language, read the Blog.

Ideas 535

  1. Let Glass Box Where next lists render bare links as the target page's current title, so a Lesson rename touches one file instead of every page that links it; the page check would then only verify the link target exists.2026-10-24 →
  2. Add a flatten.ts tag 'fabricated-tag' for assistant text that contains <task-notification> or <agent-message>, so inspect-session surfaces self-invented reports in one grep; plus a Stop-hook check that flags such text before it reaches the human.2026-10-24 →
  3. Add a page-checks.ts rule that flags a guide Lesson over ~1,200 prose words or with more than 5 Why bullets, so two-concept pages like Multi-tenant isolation are caught at write time instead of by a review.2026-10-24 →
  4. Tinkerfund campaign page on phones: collapse the 7 gallery thumbnails into a swipe strip so title and price show on the first screen (sonnet, single)2026-10-24 →
  5. Tinkerfund: let Pledge-linked Campaigns on /account link to their Campaign page, and add an Ended X ago line on ended cards (opus, sonnet, singles)2026-10-24 →
  6. Tinkerfund: a Following list on /account fed by Notify me, so the upcoming-Campaign action has a payoff (fable, single)2026-10-24 →
  7. Tinkerfund Deals: hide the Copy code button until the Deal starts, and rename Keyboard Week to match its everything-applies scope (opus, singles)2026-10-24 →
  8. Add audit-skills.ts --at ISO to replay a past run's scorecard and briefs from the commit and time it started. That makes overlap and regression questions like issue 2373 a one-line check instead of a worktree-and-clock-shim job.2026-10-24 →
  9. Extend check-states.ts's mechanical-verification pattern (built to replace a prose 'verify issue/PR states' rule that kept failing, per #1627/#1720) to prune-trial's self-reported line deltas: a small script that recomputes each open ledger entry's claimed delta from `git show`/`wc -l` and flags a mismatch, the same way check-states.ts flags a wrong issue state, so #2228-shaped misses (now recurring as #2471) stop needing a human-reviewed audit-skills pass to catch2026-10-24 →
  10. Add a weekly rule-coverage audit script: for each path-scoped rule, list sessions whose commits touched its paths but whose log never loaded it. It turns this session's manual check into a regression alarm for hook and glob gaps.2026-10-23 →
  11. Midden: a 'cause of death' tag on each find (closed by owner, superseded, never used, cost more than it caught) with filter chips on the Trench; needs a stored field, so a Trusted user must settle its shape first.2026-10-23 →
  12. Midden: rename the report 'The Current Cut' to 'The July Cut'; its title clashes with the open season 'the Current Midden' and its dek describes a July cut.2026-10-23 →
  13. Midden: the pull quote 'You catalogue a corpse only where nothing living grew back.' is all-caps and unattributed; sentence-case it or credit the curator.2026-10-23 →
  14. Midden: the condition key says Fresh means 'edges still sharp' but grades are never re-derived, so July 'fresh' finds read false in October; add 'graded once, on the date assessed'.2026-10-23 →
  15. Midden: unpublished-dispatches says 'has now lain quiet for forty-nine days', a frozen 'now'; reword to 'had lain quiet for forty-nine days when assessed' (authored prose, needs the owner).2026-10-23 →
  16. Midden: dig-report breadcrumb 'terrarium / the midden' is grey mono text that does not read as links; underline on hover or add a back link.2026-10-23 →
  17. Midden: Stood Down cards run ~1,800 words unbroken on a phone; split the prose into short paragraphs or fold each card (authored prose, needs the owner).2026-10-23 →
  18. Teach prune-trial to propose, when the chosen rule is already one line and has failed 3+ times, adding a guard via a needs-triage issue as the trial's main output instead of a near-empty prune; #2426 shows the pattern.2026-10-23 →
  19. Add a ledger-move script (prune-friction-ledger.ts --move <session> <from> <to>) that moves an occurrence block verbatim, unions fixes on merge, applies the one-session rule with a report of dropped texts, and re-runs the content check; every slice agent in this run wrote its own move.py, five near-identical scripts.2026-10-23 →
  20. Add a derived skillCallers map (Skill name to main or subagent ids) to the session trace, so Skill audits like #2286 can tell a main-session call from a triage agent's without paging events.2026-10-23 →
  21. A mechanical pre-post check for blog-post step 9: grep the drafted PR body for phrases like 'later unchecked edits' or 'unchecked' before it ships, catching the forbidden shape the moment it's written rather than relying on audit-skills to catch it a day later.2026-10-23 →
  22. Run an added instruction like a reverse prune trial: when a Skill gains a step (like this look-back), ledger it with a window and a measurable verdict from later logs, e.g. whether completed logs' look-back Frictions, learnings and ideas name kinds of cost earlier passes missed, so added text must earn its place the way cut text does2026-10-22 →
  23. Friction Ledger cluster sparklines: per-day bars from occurrences, ticks at merged-fix dates, following the ?days window (refined, not yet built).2026-10-22 →
  24. RSS/Atom feeds for the Digests and the Blog (raised by two visitors); needs a routing decision under ADR-0006 and Trusted approval.2026-10-22 →
  25. Blog post page: prev/next cards overlap on desktop (one visitor, karen/2026-07-12 post): give each card min-width 0 and a title clamp.2026-10-22 →
  26. Journal history page is about 11,660px tall on a phone: add an On this page jump list (one visitor).2026-10-22 →
  27. Friction Ledger page is 8,500px; show the top 10 of each list with Show all and a count-by-state summary (one visitor).2026-10-22 →
  28. Architecture and how-it-works diagrams are clipped at 390px with no scroll cue (one visitor): widen or fade-edge them.2026-10-22 →
  29. Friction tile arithmetic: 8 blockers + 3 majors + 651 lesser does not sum to 654 (one visitor, unverified): check frictionOtherCount.2026-10-22 →
  30. Session card shows model as opus-5-5 with a raw <synthetic> marker on the archived page (one visitor): hide or label it.2026-10-22 →
  31. Unify the Journal's three duration formats (sessionDurationLabel '9 h 56 min', routineRuns '1h 5m', subagentUsageLabel '3m 12s') into one formatDuration util with an hours branch, so a two-hour subagent stops showing '120m 0s'2026-10-22 →
  32. Have log-session record per workflow agent its tool count, tokens and duration from the run journal, so retrospectives on workflow cost don't depend on a dead container.2026-10-22 →
  33. Show tokenShare on the Journal's session card as a small bar per agent, once a few logs carry it, so expensive orchestration patterns stand out at a glance.2026-10-22 →
  34. Make adr-check's binding.ts take the changed paths (git diff names) and print the ADRs whose rule paths match first, as a must-read list, and have log-session record which ADRs the agent judged binding, so 'did it read the binding ADRs' becomes checkable from the log.2026-10-21 →
  35. Blog feed: RSS/Atom for posts and per-persona feeds (all three visitors asked); needs a Nitro server route, so a Trusted user must widen visitor-loop's remit or approve it.2026-10-21 →
  36. Blog index: link each feed card's 'in reply to' text to the parent post (fable) so a reader can jump the thread from the list.2026-10-21 →
  37. Blog landing: the 390px 'Terrarium Blogger Network' box drops the tagline that explains the premise (fable); keep the tagline and drop persona blurbs on narrow screens.2026-10-21 →
  38. Blog posts: David's First Light reaction blurb says 'your first light' to the author, jarring under a reader-facing heading; reword to 'David's' (fable).2026-10-21 →
  39. Blog tags: unknown ?tag=unicorns returns 200 with an empty list below the sidebar; show a notice above the fold (fable).2026-10-21 →
  40. Make audit-skills' scorecard print, per Skill, the sessions whose log shows the full-ADR read, so adr-check's 'read the full ADR' promise is checkable without opening logs.2026-10-21 →
  41. Let prune-trial's plain-rewrite mode target frictions-to-fixes next, merging its ledger rules (sections 1, 5, 7, 8) into one Ledger section with a single lifecycle table.2026-10-20 →
  42. Let prune-trial's plain-rewrite mode target audit-docs next, moving its tiers and lenses into reference sections after the numbered steps, since its rules all load before step 1.2026-10-20 →
  43. Give prune-trial a small script that extracts every imperative sentence of a file into a checklist, so a whole-file rewrite can be ticked off rule by rule before commit; both rewrites here lost rules that a checklist would have caught.2026-10-20 →
  44. Give prune-trial a small script that extracts every imperative sentence of a file into a checklist, so a whole-file rewrite can be ticked off rule by rule before commit; every rewrite here lost rules that a checklist would have caught.2026-10-20 →
  45. Atlas landing: a Glass-Year dial with every creature abroad listed, replacing the text-only Abroad line (feature in progress).2026-10-20 →
  46. Atlas: a since-your-last-visit strip of new sightings, kept in localStorage, to give return visitors a reason to come back.2026-10-20 →
  47. A blog-post helper that lists rule or ADR changes reverted within hours, with merged_at times from the API: rule reversals make short, checkable stories.2026-10-20 →
  48. Give inspect-session an end-to-end smoke test over a saved real multi-page session (redacted), so the replies, dispatch joins and resolvePages lookup are checked against real event shapes, not hand-built fixtures; it would settle whether events ever mix text and tool_use blocks.2026-10-19 →
  49. Blog post prev/next cards overflow at 390px on long titles and cause horizontal scroll (fable, single): let titles wrap and stack the two cards under 600px.2026-10-19 →
  50. Journal /routines week table is clipped at 390px (fable, single): wrap it in an overflow-x container.2026-10-19 →
  51. Journal digest stats sit jammed in the Also shipped paragraph (fable, single): move Sessions/Problems noted onto their own line.2026-10-19 →
  52. Friction Ledger has 88 unfiltered clusters (fable, single): add status filter chips and top-15 collapse.2026-10-19 →
  53. Commons search lists 20 Atlas spiders first, alphabetically (fable, single): default to newest-first or group by site.2026-10-19 →
  54. Tinkerfund rewards say Est. delivery after the campaign shipped (fable, single): show Delivered once the shipped update exists.2026-10-19 →
  55. Tinkerfund qa room note reads as dev-speak (fable, single): keep the qa term, reword after the dash to the test shop of odd campaigns.2026-10-19 →
  56. Home digest teasers clamp mid-sentence on phones (sonnet, single): end the clamp with an ellipsis.2026-10-19 →
  57. Atlas rarity row shows five filled dots for COMMON (sonnet, single): label it Very common or invert the dots.2026-10-19 →
  58. Glass Box code excerpts are clipped at 390px with no scroll cue (opus, single): wrap long lines or add an edge fade.2026-10-19 →
  59. Glass Box draft and guide chips are labelled inconsistently and the editions' commits differ unlabelled (opus, single): label chips by kind and show the edition commit.2026-10-19 →
  60. Footer Elsewhere lists five sites though Glass Box now has its own homepage band (opus and fable): ask the owner whether decisions.md's five-site footer ruling should now include Glass Box.2026-10-19 →
  61. RSS or Atom feed for Journal digests and Blog posts (opus, fable): needs a server route, out of this Skill's remit; file for a Trusted user.2026-10-19 →
  62. Have a SessionEnd hook write this session's own flattened transcript to a git-ignored mirror, so a later session's transcript search reads one file instead of 91 MCP pages.2026-10-19 →
  63. Add a scripts/session/handback-to-research-branch.ts that takes an agent id, a branch and a path, extracts the fenced note from save-handback output, and commits it to a never-merged research branch, so wayfinder research tickets close in one command2026-10-19 →
  64. Extend validate-prune-trials.ts to check every trial's territory paths and keywords are strings, so an unquoted `Reviewed:`-style keyword fails the gate instead of printing as an object.2026-10-19 →
  65. Have log-session flag a session that opened a PR or recommended a change without invoking adr-check, giving the Skill a mechanical backstop and the #2146 experiment a measurable signal.2026-10-19 →
  66. Have binding.ts print the territories first and the summaries after, or make adr-check say not to truncate its output, so a tail-piped run still shows the summaries; then re-test with one clear-backlog-explore run.2026-10-19 →
  67. Have audit-skills compare each new observation against the previous entry's opening words and warn on a shared stock prefix, so copying is caught mechanically rather than by instruction.2026-10-19 →
  68. Add scripts/journal/history-stats.ts that prints the History table row (sessions per week, agent-initiated, frictions per session) and the header totals for any date range, and have validate:content check that the page's table matches it, so a period row can't drift from the method again2026-10-18 →
  69. Glass Box: add the same A real case box to Adding a Tenant (the Marquee PR) and From file to browser, using only facts GitHub records for the PR, so every Walkthrough ends in evidence.2026-10-18 →
  70. Glass Box Walkthroughs: add previous/next cards between the four Walkthroughs, as Lessons have, so a reader does not stop at Where next (opus).2026-10-18 →
  71. Glass Box: the landing hero says what Terrarium is but not what it serves or for whom; one sentence naming the sibling sites as Tenants of the same project would answer fable's first-impression confusion.2026-10-18 →
  72. Glass Box excerpts: show both gap marks consistently (gutter dots and comment) as one, and render the trust-tiers excerpt with line numbers like every other excerpt.2026-10-18 →
  73. Glass Box Walkthrough chips: file chips break mid-word at 390px (layers/marquee/app/pages/t/marquee/i / ndex.vue); wrap at slashes with a wbr.2026-10-18 →
  74. Glass Box titles: the tab title reads Name · glassbox; use Glass Box to match the brand.2026-10-18 →
  75. Add a check (extend check-triage-drift.ts) that flags open issues whose first label was ready-* set by a non-triage Skill's session, so label ownership is enforced, not just documented2026-10-18 →
  76. Have the weekly explanation routine for the Routine costs page also re-check that every Routine in the collection has a chart block in routines.md, and file or fix the gap, so a new Routine never silently misses a chart.2026-10-18 →
  77. Add a Routine cost panel to the Journal Tenant: audit-skills writes per-Routine mean tokens and cost per run into the Skill Inventory, and the Journal renders a weekly cost-by-Routine chart so an expensive Routine (audit-skills is about 41 percent of spend) is noticed before it grows.2026-10-18 →
  78. Give the survey a --since-ledger flag so later runs skip sessions already clustered.2026-10-18 →
  79. audit-skills SKILL.md step 5's literal wording ('only when it cites a session no remaining entry already cites') reads as a hard gate on appending an Inventory observation, but an empirical check of all 48 Inventory files' history shows this exact pattern (an entry citing zero newly-introduced session ids) recurring dozens of times since September across nearly every file - established, unremarked-on practice, not a defect. Worth a plain rewording (or an explicit carve-out for 're-confirmed, no new finding' entries) so a future literal reading doesn't keep flagging normal daily upkeep as a violation.2026-10-18 →
  80. Glass Box Walkthroughs: add a prev/next footer between the four Walkthroughs, as Lessons have, so the reading path does not end at Where next.2026-10-17 →
  81. Glass Box Walkthroughs: the On this page row shows bare numbers at desktop; show the short step titles as the mobile dropdown does.2026-10-17 →
  82. Glass Box Lessons: Prune Trial, Friction, Commons Search and Routine appear undefined; make them term buttons and add the missing terms to the term list.2026-10-17 →
  83. Glass Box session-logs Lesson: link one real session log and the Friction Ledger so the reader can see what the Lesson describes.2026-10-17 →
  84. Glass Box pages: Last updated shows the same date on every page and reads as a build stamp; show the date the page's text last changed.2026-10-17 →
  85. Glass Box Lessons on mobile: the opening paragraph is about 20px and fills the first screen; set it near 17px on narrow screens.2026-10-17 →
  86. Glass Box code excerpts: browsers without animation-timeline get no scroll fade; add a visible cue that works without it.2026-10-17 →
  87. Make the screenshot-review step diff against a baseline and send only changed shots to visual review, so a UI PR doesn't spend 45 minutes reading every shot2026-10-17 →
  88. Add a ledger helper that lists merged PRs missing from every fixes entry and appends printed occurrences to a named entry, so the survey subagent stops doing both by hand with ad hoc node scripts.2026-10-17 →
  89. Make glassbox-update's script flag Drafts pages too when a rename moves cited paths, so drafts do not silently go stale between runs2026-10-17 →
  90. Add an empty-glob check to scripts/gate/validate-adr-rules.ts: every paths glob in .claude/rules must match at least one tracked file, so renames can't silently unload a rule.2026-10-17 →
  91. Have glassbox-update also list drafts pages whose cited paths no longer exist at the new main, so renamed ADRs surface there.2026-10-16 →
  92. Run the gate's e2e step in CI under a non-UTC TZ (e.g. Pacific/Chatham, offset +12:45) so zone bugs like #2175 fail in CI instead of only on contributors' machines2026-10-16 →
  93. frictions-to-fixes survey: require a one-line written reason in the ledger PR for every open cluster with 5+ occurrences it does not pick, so a long-running skip like double-background is visible without a human asking.2026-10-16 →
  94. Make the glassbox page check report each Why bullet's word count and percent change versus main, so a rewrite against a shortening target is measured by the checker rather than by agents counting their own words.2026-10-16 →
  95. Split ADR-0020 and ADR-0027 into one CLAUDE.md action line each plus a path-scoped rule (paths from the survey: guest-contributions.md, trust.ts, triage and auto-triage Skills; prune-trials.yml and the instruction-editing Skills), cutting about 2k tokens from most sessions.2026-10-16 →
  96. Have log-session drop the 'did you open the full ADR' question for rules whose when-clause did not apply, so sessions stop logging skipped-read nits.2026-10-16 →
  97. Glass Box: glossary terms link to GLOSSARY.md on GitHub; link them to an in-site term view instead.2026-10-16 →
  98. Glass Box: the 'A real case' box in Asking for a change names a PR but does not link it or its session log; link both.2026-10-16 →
  99. Glass Box: the Session logs Lesson never shows a real log; link one Journal entry.2026-10-16 →
  100. Glass Box: the Walkthrough 'On this page' bar shows bare numbers on desktop; show 'n · short title'.2026-10-16 →
  101. Glass Box: the landing <title> reads 'Terrarium, seen through the glass. · glassbox'; use 'Glass Box · Terrarium, explained from the inside'.2026-10-16 →
  102. Glass Box: pages pin three different commits with no single edition commit shown; show one edition hash in the header.2026-10-16 →
  103. Glass Box: the trust.ts excerpt lacks line numbers unlike every other excerpt; render it with the line-numbered component.2026-10-16 →
  104. code-review Skill: for a diff under ~10 lines in one file, run both axes inline instead of spawning two subagents, since the subagents cost ~130k tokens to review two lines here2026-10-16 →
  105. Extend glassbox page-checks to flag a Why paragraph whose ADR citation also appears in another guide Lesson's Why without a link to it, so repeats across Lessons surface mechanically instead of by review.2026-10-16 →
  106. When the gate goes red on a scheduled run's PR, have the run check whether origin/main's tip passes the failing test and, if it does, update the PR branch and re-run, so fixes already on main reach waiting PRs automatically.2026-10-16 →
  107. Make the ideas-harvest-and-rate pipeline verify each item's premise in code (does the named file/guard still exist?) before rating, so moot items like a removed guard never reach the top 20.2026-10-16 →
  108. Glass Box subject index pages (/t/glassbox/guide/claude-code) with a one-line summary per Lesson; needs a page-checks.ts placeProblems change so an index.md may sit in a Subject folder.2026-10-15 →
  109. Per-Lesson Show the live result chip in Glass Box (layers: two Tenants side by side; Gate: latest CI run) so each In Terrarium section links evidence.2026-10-15 →
  110. Diagrams for the Adding a Tenant (folder tree) and Asking for a change (request-to-merge timeline) Walkthroughs, each a committed SVG.2026-10-15 →
  111. Lesson contract: let a Why it's built this way line carry a one-line ADR summary, not only the ADR number and path (sonnet and opus found the bare paths cold).2026-10-15 →
  112. Glass Box reading progress: tick visited Lessons in the sidebar from localStorage and show N of M per Subject; weigh against the ADR-0028 payload note.2026-10-15 →
  113. Let glassbox-update take --spaces from the skill args so '/glassbox-update drafts' just works, instead of the agent translating prose.2026-10-15 →
  114. Skip the Stop hook's commit nag while background subagents are still editing, so a wait doesn't cost a turn each time.2026-10-15 →
  115. Journal Friction Ledger: write each cluster's cause as one plain sentence (or an optional plain headline field) so visitors can read the ledger without agent shorthand; cite closed #1839.2026-10-15 →
  116. Journal digests: add a Blog posts about this day list linking back from each digest to the posts that cite it.2026-10-15 →
  117. Journal session list: filter pills by status and hide the synthetic model chip, since opus and fable found the chips noisy.2026-10-15 →
  118. Journal landing: Skills stat tile says +24 external while the Skills page shows 16; make the two counts agree.2026-10-15 →
  119. Journal digest pages: title them Digest · date and make the digest date a link, so the standalone digest pages are reachable from the Journal.2026-10-15 →
  120. Add a scripts/install-pack-skill.ts that runs the skills CLI, moves the result to .agents/skills with the .claude/skills link, and runs verify:skills-lock, so installing a pack Skill is one command and gate-clean.2026-10-15 →
  121. Make clear-backlog-build compute and return the Human-only verdict per branch (paths plus a flag for 'no gate observes this'), so the orchestrator never has to re-derive ADR-0004 exceptions before opening PRs2026-10-15 →
  122. Refer to visitor-loop steps by name ("Fix PR", "Check fit") rather than number, so adding a step needs no cross-reference sweep2026-10-15 →
  123. Give glassbox a 'promote' check: a script that lists drafts pages that now pass the guide bar (reader scores stored in frontmatter) so moving a page back is evidence-driven, not ad hoc.2026-10-15 →
  124. Add a verdicts block to the content-writer hand-back template so every subagent reports rule and doc verdicts with its result, which feeds log-session step 3 for free2026-10-15 →
  125. Give the Friction Ledger an 'accepted' status with a required ref to the owner's decision, so frictions-to-fixes stops re-ranking causes a human chose to live with and the log-session Skill can tell sessions not to log them2026-10-15 →
  126. A mechanical check in frictions-to-fixes' ledger tooling (scripts/prune-friction-ledger.ts or a sibling) that flags, at ledger-write time, any occurrence whose session startedAt postdates the entry's current fixedOn — so SKILL.md section 2's regression branch can't be silently skipped the way #2024 was; the same tooling should bump fixedOn/ref to the latest landed fix rather than leaving a stale pointer.2026-10-15 →
  127. Add a scripts/issue-deps.ts that takes 'child:blocker' pairs, resolves database ids and posts native blocked-by edges, so wayfinder and spec sessions wire dependencies in one call that the provenance guard can read2026-10-14 →
  128. Give scripts/render-mermaid.ts a per-Tenant font option read from tenant.config.ts, so a Tenant's diagrams match its typography without redrawing other Tenants' SVGs2026-10-14 →
  129. Add a scripts/new-tenant checklist (or Skill) listing every hard-coded place a new Tenant must touch: audit-docs Live list, smoke-test card order, SITES, root glossary roster, GLOSSARY-MAP, real-and-invented page. The list is scattered today and easy to miss.2026-10-14 →
  130. Blog front door: add month headings inside the Show-all list (and 20-at-a-time reveal) so the 150-post scroll has landmarks; visitors cited the length twice.2026-10-14 →
  131. Blog posts: embed the screenshot or portrait a post describes (Eyra's loupe post), since three visitors wanted to see it.2026-10-14 →
  132. Blog post pages: capitalise the persona in 'In reply to karen's' and link the index's '↳ in reply to' marker to the parent.2026-10-14 →
  133. Blog posts: show a 'What happened next' note on posts ending with an open question, linking the later post.2026-10-14 →
  134. Journal digests: add a 'Blog posts about this day' list, since posts link to digests but not back.2026-10-14 →
  135. Add scripts/validate-skill-observations.ts (run in pnpm validate:content or as audit-skills step 5's own check) that rejects a new Inventory observation citing no session id absent from every remaining entry in the same file — this exact violation just recurred in 5/12 of this run's own entries and was only caught by a post-push code-review.2026-10-14 →
  136. A structural fix for the 'verify at reconciliation/summarization time, not per-claim' pattern audit-skills' own behaviour-check subagent named as the root cause behind 3 independently-confirmed shapes of its 'every stated issue/PR state is a live read this run' promise breaking (#1627/#1720/#1798/#1856): have the orchestrating session paste each claimed issue/PR state's live-read result inline next to the claim as it writes the PR/Inventory text, rather than composing the summary first and checking after.2026-10-14 →
  137. Stamp line counts into the CLAUDE.md read-first doc list too (e.g. pr-workflow.md, 120 lines) using the same --write mechanism, so agents see every required read is cheap2026-10-13 →
  138. Add a validate-content check that every Inventory role and journal facing page sentence citing 'ADR-00NN' is re-flagged when that ADR's hash changes, the way validate-adr-rules re-stamps summary rules; the #1898 rewrite left drift in exactly those places2026-10-13 →
  139. Give audit-docs a one-off full-history mode (ignore the 48h window) to run once after a large rewrite like #1898, so pre-existing drift across all docs gets checked in one sweep.2026-10-13 →
  140. Add a gate check that every 'ADR-NNNN' citation in code comments points to an ADR whose text mentions the cited term, so repointing drift after an ADR rewrite is caught mechanically instead of by review agents.2026-10-13 →
  141. Add an ADR-0030 template check to validate-adr-rules: for ADRs listed as rewritten, fail the gate on Date/Status lines or Amended banners, so the no-history rule is mechanical rather than prose2026-10-13 →
  142. Add a gate check in validate-adr-rules.ts: an ADR with the new '# ADR-NNNN:' heading fails if it contains Date/Status lines or Amended banners2026-10-13 →
  143. Carry the wing dial's chosen day into creature pages (?day=183), so turning the dial then opening an entry keeps the season; fable found it resets to today.2026-10-13 →
  144. Add a /t/atlas/ledger page listing every sighting newest-first, filterable by wing; the dated field log is the one thing that changes between visits.2026-10-13 →
  145. Show a 'since your last visit' strip on /t/atlas from a per-browser last-visit date; opus and fable both wanted a reason to return.2026-10-13 →
  146. Textor absens page lists only 'feared by' while its diagram also shows 'shelters Formica textrix': render the missing relation row (fable).2026-10-13 →
  147. Capitalise sentence starts in Atlas sightings (e.g. 'declined to be seen. the second count…'); five creature pages start sentences lowercase after a full stop (fable).2026-10-13 →
  148. Add a wing-to-wing next/previous link on the first and last specimen of each Atlas wing, which now dead-end (opus).2026-10-13 →
  149. Teach scripts/log-session.ts to warn when a re-author pass adds a friction whose description nearly matches an existing one (edit distance), since mergeAuthored silently logs a reworded friction twice.2026-10-13 →
  150. Give each Friction Ledger cluster a sparkline of occurrences per day on the new frictions page, so a reader sees at a glance whether a fixed cluster really stopped recurring after its fixedOn date.2026-10-13 →
  151. Run a dry clear-backlog pass on two easy issues once #1871 merges, to verify settings env pickup and the subagents/workflows trace layout, before a full backlog run.2026-10-13 →
  152. Normalize .claude/worktrees/<name>/ prefixes to repo paths in session-trace docsRead, and list workflow agents under subagents, so workflow runs read like Agent-tool runs in the Journal.2026-10-13 →
  153. Give clear-backlog a single live question board (an Artifact or one pinned issue) that holds only the open owner questions and updates in place, so answers never get lost in chat scroll.2026-10-12 →
  154. Add an optional one-line plain summary field to friction entries in session logs, and show it in the Journal's Worst frictions list (see #1839)2026-10-12 →
  155. Give auto-triage a 'deferral check' mode: for an issue whose latest owner comment names a revisit condition (an upstream release, a date, another issue closing), a cheap script checks just that condition and only escalates to a full triage subagent when it flips, cutting full-sweep cost by most of the ready-for-human backlog.2026-10-12 →
  156. Make the survey emit its ledger edits as a patch generated by a script that reads session logs, so frictions-to-fixes reviewers can re-run it and the ledger PR stops depending on one subagent's transcription.2026-10-12 →
  157. Dry-run any change to log-session or close-session by spawning a read-only child session on the PR branch and reading its landed log; it caught three instruction gaps in this PR that the code review missed.2026-10-12 →
  158. Journal ideas page: group the 71 ideas and 57 learnings by Tenant or topic with a filter chip row (all three visitors found the flat list unreadable; this PR only added jump links)2026-10-12 →
  159. Archived digest pages (for example /t/journal/archived/digests/2026-07-14) are PR-number soup, yet Blog posts link to them from 'Same day in the Journal': add a plain-language summary above the old text2026-10-12 →
  160. Journal landing: a 'This week in one paragraph' strip built from the newest digest, above the stats, since visitors found the landing a dashboard before a story (fable)2026-10-12 →
  161. Session cards: show a 'Read Karen's take' chip linking to the Blog post written about that session, tying the narrative pages to the raw record (fable)2026-10-12 →
  162. Journal 'Story threads': pages following one recurring problem across sessions, digests and posts, starting with the session-ID trailer saga that the highlights page makes gripping (opus)2026-10-12 →
  163. Journal landing: one-line legend for model chips and session kinds, and a last-logged timestamp replacing the static 'live snapshot' badge (fable)2026-10-12 →
  164. Component tests as a third vitest project (@nuxt/test-utils/runtime with happy-dom): the per-test classification in this session's PR description says 60 of 131 e2e tests only need a mounted component plus mocked queryCollection (39 Tinkerfund server-rendered checks, 8 Journal dashboard checks, Commons search/timeline). Gains maintainability and test speed per file, not gate wall-clock now that specs run in parallel; costs two devDependencies and queryCollection mocking.2026-10-12 →
  165. Shorten the new e2e critical path (tinkerfund-flows ~37 s, smoke ~31 s locally): move each Tenant's entry-route hydrations from the Platform sweep into that Tenant's spec, and split the six Tinkerfund flows two per file; both are mechanical and coverage-neutral.2026-10-12 →
  166. Unit step: eight hook-guard specs spawn a subprocess per case and take ~40 of the step's ~50 cumulative seconds (bash-rules-hint 17 s, subagent-background-guard 16 s, ...). Exercise the guard function in-process with one subprocess smoke test per guard.2026-10-12 →
  167. Give session-frictions.ts a --ledger mode that pre-matches each new friction to existing Friction Ledger entries by session id and keyword, so the survey subagent only judges the unmatched ones and the per-run cost stays flat as the ledger grows.2026-10-11 →
  168. Add a validate:content check that fails when a folded YAML block scalar in the Skill Inventory ends a line inside a backticked token or hyphenated word (guest-build and guest-intake roles rendered 'ready-for- agent'); a ten-line regex over layers/journal/content/*/skills/*.yml role fields would stop agents re-introducing it.2026-10-11 →
  169. Add per-snag session count tiles: show how many sessions hit each Worst snag so recurring frictions rank above one-offs on the Journal landing.2026-10-11 →
  170. Atlas relations diagram on phones is empty-looking (two visitors) but kept by decision #1494: label the nodes with species names inside the cropped overview.2026-10-11 →
  171. Marquee reel index promises illustrations but shows none (one visitor): add thumbnails next to each chapter.2026-10-11 →
  172. Tinkerfund campaign page on phones puts title and price about 850px down (one visitor): lead with title, pitch and price above the gallery.2026-10-11 →
  173. Make the Stop-hook git check honour a session hold marker written when the owner says review before pushing, so unpushed commits stop nagging while a review runs2026-10-11 →
  174. Build a fail-open PostToolUse Bash hook, reusing rulePaths from validate-adr-rules.ts, that injects rules for file paths in compound or multi-file commands only, so rules stop missing the chained reads auto mode encourages.2026-10-11 →
  175. Add a one-line 'maintainer view: append ?maintainer to any Journal URL' to layers/journal/CONTEXT.md so agents and humans find it without code spelunking2026-10-11 →
  176. If the code-review gate is adopted, key it to the PR's head: require a code-review Skill call after the session's last git push in the transcript, so a review of an earlier commit or another PR does not count2026-10-11 →
  177. dispatch-subagents' skillsUsed-logging gap (now 15+ corroborating instances across #1586's thread) looks structural rather than a logging nit: build a small mechanical check — e.g. a session-trace heuristic that credits dispatch-subagents whenever the transcript shows ≥2 concurrent Agent-tool calls in one turn, the same way shell reads get folded into docsRead — rather than relying on the dispatching session to remember to cite it by name every time.2026-10-11 →
  178. Have the log-session Skill's --author step warn when the branch changes shared/schemas/session.ts, since the session's own log will now wait until that PR merges2026-10-10 →
  179. Add `rulesLoaded` to the session trace: collect `attachment.type == nested_memory` paths in scripts/session-trace.ts as an optional schema field, so audits can see whether a rule fired and whether the full ADR was read after it.2026-10-10 →
  180. Gate check: a PR that changes docs/adr/NNNN-* must also touch .claude/rules/adr-NNNN.md, so summaries cannot go stale silently.2026-10-10 →
  181. Report the rules-import behaviour (imports of path-scoped rules load at startup, not on trigger) to Claude Code via /feedback.2026-10-10 →
  182. Have scripts/log-session.ts --land also validate the entry against origin/main's shared/schemas/session.ts, so a branch that adds a session field cannot land a log main rejects.2026-10-10 →
  183. Tinkerfund 'Following' list on the account page fed by the existing Notify me button, with launch countdowns: opus and fable both asked for it, and it gives return visitors a reason to come back.2026-10-10 →
  184. Tinkerfund Hall of Failures: an Ended tab or route on Discover listing unfunded Campaigns with their post-mortem updates, since sonnet found those the funniest content and they are buried in single pages.2026-10-10 →
  185. Tinkerfund deals page layout: deal cards sit at one-third width leaving empty space and 'Applies to every Campaign' floats outside its card (opus); put banner and card side by side.2026-10-10 →
  186. Re-derive the 84 post-2026-10-03 logs with the 10-line minimum (a one-off script over loadDocLineIndex plus list_events transcripts) and post the before/after credit counts on PR 1738, so the human merging it sees the measured effect2026-10-10 →
  187. Give /triage a 'deep re-triage' mode that dispatches one read-only agent per ready-for-human issue with a fixed brief (code, git history, session-log counts, full binding-ADR read, prune-trial overlap) and returns only owner-only decisions. This session showed most parked issues are repo-decidable once that evidence is gathered.2026-10-10 →
  188. Add a PR-description staleness check to code-review's round-2+ brief, since descriptions drifted after almost every fix commit.2026-10-10 →
  189. Midden find cards: add a one-line what-it-cost or what-we-learned tag so a list of curiosities reads as lessons (opus).2026-10-09 →
  190. Add /t/midden/condition/<grade> listing every find of one grade across reports, linked from the Condition key (fable, opus).2026-10-09 →
  191. Link each Midden find to its living counterpart on the Blog, Tinkerfund or Journal in a Survives alongside row (fable).2026-10-09 →
  192. RSS or new-since feed of newly assessed Midden finds; the front shows only the latest three (all three visitors).2026-10-09 →
  193. Dig-map timeline of finds by season and grade at the top of the trench index (sonnet).2026-10-09 →
  194. Midden pull quote is all caps and reads as shouting: use sentence case with attribution (opus).2026-10-09 →
  195. Stores strata plate at 390px has unlabeled bands: put season names beside the bands (opus).2026-10-09 →
  196. Rename report The Current Cut, which competes with the Current Midden season (fable).2026-10-09 →
  197. Reword Every other quarter of this place on /t/midden to Every other part of Terrarium (fable).2026-10-09 →
  198. Make season labels on cards link to their Stores band; needs the plate links to be non-aria-hidden (sonnet, fable).2026-10-09 →
  199. Add --viewport WxH to scripts/probe.ts so mobile checks need no iframe workaround.2026-10-09 →
  200. Record each session's commits at commit time: have the commit-msg or post-commit hook append sha and session id to a gitignored per-session file, so session-id-guard and the trace extractor get exact ownership even for git commit -q, merges and rebases, instead of parsing tool output.2026-10-09 →
  201. Share one 'git at command position' matcher across commit-trailer-guard, session-id-guard and the other Bash-matching guards, so a heredoc or grep that only mentions git stops tripping them.2026-10-09 →
  202. Make the smoke test's 404 check look for a dedicated data attribute (e.g. data-testid=not-found) instead of the human string 'No document at', so a session log that quotes the string can't break main.2026-10-09 →
  203. Build the drift test from Part 2's 'Keeping it true' before the diagram itself: a tests/unit spec that reads a typed diagram data file and fails on missing paths or unknown node ids. That way the content is checked in CI no matter where the diagram ends up living.2026-10-09 →
  204. Commit the two system maps as Journal pages (layers/journal/content/current/pages/) rendered from a script that reads expand(loadManifests()) for the roster table and counts, so the architecture diagram's numbers can never drift from the manifests.2026-10-08 →
  205. Publish these two diagrams in the Journal's how-it-works page as committed SVGs. Generate them from a checked-in Archify JSON (with source refs pinned to a SHA), and add a gate check that flags when a cited file/line drifts, so the overview stays true as the Platform changes2026-10-08 →
  206. Journal how-it-works flowcharts scroll at 390px but two visitors read them as clipped: add a visible 'scroll sideways' hint under each diagram on phones, or shrink the SVG viewBox so the labels fit.2026-10-08 →
  207. Journal /t/journal/current/skills: write the Details text for a visitor and show the skill name as a plain heading with a small 'Source' link, since names currently jump to raw SKILL.md files on GitHub (opus, fable).2026-10-08 →
  208. Journal archived Space: the Skills page shows only 'scaffold-tenant 0' and feels broken; hide the Skills link there or point it at the current Space's Skills.2026-10-08 →
  209. Journal home: show duration as '9 h 56 min' rather than '596 min', and sort a session card's frictions by severity so the serious ones are not buried under nits (fable, opus).2026-10-08 →
  210. Journal 404 page ('No document at /nope in journal/current') offers only the footer: add a back-to-Journal link and the five start-here links (fable).2026-10-08 →
  211. Journal home: an RSS/Atom feed of the daily digests with a Follow link in the header, since the 'live snapshot' badge promises updates but gives no way to receive them (fable).2026-10-08 →
  212. Blog landing ships 133 posts in the DOM behind Show all, making the mobile page about 6,800px tall: paginate or render the rest lazily (sonnet).2026-10-08 →
  213. Journal history table: add a line saying it is current to 2 Oct and later days are in the digests, because the home page runs to 10-07 (sonnet).2026-10-08 →
  214. Add a pre-commit check to the prune-trial Skill's flow: for every heading or bolded bullet lead removed from CLAUDE.md, grep the repo (excluding session logs and blog content) for the phrase, and fail with the list of referencing files. Two review rounds here caught about 20 dangling references by hand.2026-10-07 →
  215. Blog persona landing: the start-here list sits at the bottom of a tall sticky About panel on desktop and is below the fold; move it into the masthead or above the About text so it is seen without scrolling.2026-10-07 →
  216. Blog feed: link the in reply to marker on each card to the parent post by name and show a reply count, so threads are discoverable from the index (visitors, single-visitor finding, not built since a thread view was logged).2026-10-07 →
  217. Blog front door ships all 133 posts in the DOM behind a Show all button: render the rest on click or paginate, since the 390px page is about 6,800px tall.2026-10-07 →
  218. Make verify:mermaid also fail when the installed mermaid version differs from the one recorded in each committed SVG (e.g. a data-mermaid-version attribute), so a Dependabot bump that changes rendering can't pass the gate with stale SVGs as #1635 would have2026-10-07 →
  219. Atlas plate numbers (I to XXIII for 15 creatures) look random: add a List of plates index or a colophon line saying how plates are numbered (opus, fable).2026-10-06 →
  220. Atlas specimen-page relations diagram loses its labels on mobile: add the wing pages' text list beneath it (fable).2026-10-06 →
  221. Atlas 404 under /t/atlas links to the site root: lead with Back to the Atlas (fable).2026-10-06 →
  222. Atlas specimen pages repeat the Turn the almanac sentence near-verbatim: keep it once as a dial caption (fable).2026-10-06 →
  223. Atlas season dial gives no visible hint it is interactive: add a drag the needle and arrow keys hint (sonnet, fable).2026-10-06 →
  224. Atlas wing pages and last specimens are dead ends: add a Next wing link (opus).2026-10-06 →
  225. Atlas umbra-vacans prose dates the first report 24 June but the ledger lists 6 and 15 June entries: reconcile (opus).2026-10-06 →
  226. Make the Surprise me destinations data, not a hard-coded list: add a frontmatter flag such as featured on a page and have the footer pick from queryPages, so renamed pages cannot rot the link.2026-10-05 →
  227. Journal how-it-works flowchart clips at 390px (fable only; the site's own ideas page already lists it): stack the diagram below 480px or scale the SVG to fit.2026-10-05 →
  228. Journal Recent activity cards read as agent jargon (for example Run the scheduled prune-trial Skill): show a plain outcome headline on the card and keep the Skill name secondary.2026-10-05 →
  229. Karen post We Told It Not to Lie says In Writing. Twice. in the title but the body says the fourth doc-only rule: reconcile title and body (published post, so needs owner approval).2026-10-05 →
  230. Severity labels differ between the Journal week stats (blocker, majors, lesser) and digests (moderate, minor, trivial): pick one set and use it in both places.2026-10-05 →
  231. Midden landing page introduces Trench, Stores, Plainer Cut and Cut with no key: add a two-line legend under the excavation heading.2026-10-05 →
  232. Marquee reel promises an original illustration per chapter but shows none: add a thumbnail per chapter.2026-10-05 →
  233. Commons Search lists all 272 pages alphabetically before any query: show an empty state or group by site with a few hits each.2026-10-05 →
  234. Blog post session log links go to raw YAML on GitHub rather than the rendered Journal session card: link the card first and keep GitHub as a secondary raw link.2026-10-05 →
  235. Resolve the auto-triage vs guest-intake conflict: auto-triage routes every Public-authored issue to ready-for-human while guest-intake applies ready-for-agent on the guest's confirmation, and auto-triage's own 'Coexisting with the guest pipeline' section admits it relies on timing. Add the explicit skip auto-triage says it would add, so the two Skills agree by rule2026-10-04 →
  236. digest keeps unverifiable claims while blog-post cuts them; either document in digest why its bar is lower (a digest cites session logs, not a public blog) or raise it to match, so a fact-check subagent brief can be shared between the two2026-10-04 →
  237. Teach scripts/gate.ts's inert classifier to treat a .ts diff that changes only comment lines as inert, so a pointer fix in a script comment doesn't cost a full build + e2e2026-10-04 →
  238. Filed as #1603: let gate:scoped skip build + e2e for a scripts/*.ts change that no runtime or e2e file imports, keeping unit tests; comment-only .ts diffs as the cheap sub-case2026-10-04 →
  239. The first run on the rewritten blog-post Skill followed every structural step but skipped or thinned every judgement step (overlap check, tone re-read, unverifiable-row handling); a Done-when that cannot be checked from the transcript is a Done-when a Sonnet run will claim without doing2026-10-04 →
  240. Have session-frictions.ts emit a previousRuns section (start, summary, outcome, prs of trigger frictions-to-fixes sessions) so the subagent does not hand-pick them; skipped now as it duplicates the triage records2026-10-04 →
  241. how-it-works flowcharts clip at 390px: let the diagram container scroll horizontally or stack vertically below 480px (opus)2026-10-04 →
  242. Journal Recent activity lists about 60 mostly routine Run the scheduled cards: default to 10 with a Show all control and mark sessions with a major friction (opus)2026-10-04 →
  243. Homepage Midden teaser reads ConditionGlyph.vue + ConditionTooltip.vue: use the plain-language name already in its parentheses (fable)2026-10-04 →
  244. Blog persona cards overlap borders at 390px and the New here box has no gap above it: add an 8px gap (fable)2026-10-04 →
  245. Atlas relations diagram has unlabelled icons and two arrows to the same creature that read as an error: label the targets and stack label above text on mobile (fable)2026-10-04 →
  246. Blog tag links render twice, the second copy with no accessible name: make it non-focusable or label it (opus)2026-10-04 →
  247. Blog index renders 126 posts on one page: page it or add persona chips beside the tag chips (opus)2026-10-04 →
  248. Commons Timeline is mostly routine session titles: default to Posts and Digests with a session filter chip (fable)2026-10-04 →
  249. Commons Search indexes only titles and summaries, so the zod blog post is not found: search body text too (fable)2026-10-04 →
  250. Marquee chapters are dead ends: add Previous and Next chapter links and an All chapters link (fable)2026-10-04 →
  251. Blog RSS or follow button plus an argument-threads view of persona replies, the most fun part of the site (fable)2026-10-04 →
  252. Extend the Follow the story links from Blog posts to the matching Midden find and session log, which needs a small frontmatter field per post (sonnet, opus)2026-10-04 →
  253. Add a validate:content check for the Blog that warns when a tag is used on fewer than 3 posts or a post has fewer than 2 or more than 5 tags, so vocabulary drift like deploy at 2 uses and autonomy on half the blog surfaces before a manual review does.2026-10-04 →
  254. Give midden-catalogue an Inventory entry (platform-operation, specialist) so the Inventory covers every on-disk own Skill; audit-skills only adds entries for Skills seen in use, so an unused sibling of midden-survey stays uncatalogued.2026-10-04 →
  255. Make blog-post step 8 unambiguous, either owed (reader pass always runs, "none" is logged) or genuinely optional (drop its Done-when), because three of four runs skipped it while its Done-when reads as an obligation.2026-10-04 →
  256. Teach scripts/owner-corrections.ts to recognise a visitor-loop PR by its session-log or PR-body provenance as well as its branch name, so a run landing on the harness-pinned branch still has its rework scan.2026-10-04 →
  257. Have scripts/audit-skills.ts print `startedAt` per window session so a grader never has to open a log just to bracket a run against a Skill change; one field, no new git call.2026-10-04 →
  258. Exclude per-run data files (visitor-loop's decisions.md) from a Skill's `changes` in scripts/audit-skills.ts, e.g. via a small per-Skill ignore list, so the stderr warning only fires for text or script changes.2026-10-04 →
  259. dispatch-subagents: the branch-collision shape (session_0158JckUL8YWJtVL7s9i7xRr, then session_01TiCx5GDdDdFGwCEs6xxr89) has now recurred once; issue #1585 proposes a single-branch serial-integration recipe (detached orchestrator checkout, impl agents basing off origin/<branch>) plus teaching check:worktrees to treat a tree matching its own pushed upstream commit as rescued — worth building once a human reviews it2026-10-04 →
  260. When a visitor-loop feature PR matches an open ready-for-agent story, have the run comment on that issue and either close it or list leftovers, so story tracking never silently diverges from main2026-10-03 →
  261. Add a single-branch serial-integration recipe to dispatch-subagents: orchestrator detaches its checkout, each impl agent starts from origin/<branch>, check:worktrees treats a tree equal to an upstream commit as rescued2026-10-03 →
  262. Record each subagent's isolation param in the derived session trace, so prune-trial and frictions-to-fixes can measure dispatch rules exactly instead of guessing git-touching from task wording.2026-10-03 →
  263. Ship ready-for-human CI hand-applies as a committed one-shot wizard script under docs/proposals/ next to the proposal, so the human runs one command instead of an agent re-deriving the steps each time.2026-10-03 →
  264. Generate the scan:false migration mechanically: parse TS2304 'Cannot find name' errors from pnpm typecheck, resolve each name to its exporting file, and emit relative imports, so the 100-file PR is reproducible rather than hand-written.2026-10-03 →
  265. Tinkerfund: add a Surprise me link (random Campaign) beside Discover all in the header and hero; two visitors would stumble through the 28 jokes more.2026-10-03 →
  266. Tinkerfund: guided pledge tour banner on the home page that leads into backing the Rain-Aware Umbrella with code TINKER10, ending on the account page, since deals, add-ons and bonus support are hidden.2026-10-03 →
  267. Tinkerfund: Honest failures row on the home page using the last update of Unfunded Campaigns (Cat Acknowledgement Button, Solo Pea Rest), the funniest writing on the site.2026-10-03 →
  268. Tinkerfund: Following list on the account page for Notify me, with launch countdowns, so the bell button pays off.2026-10-03 →
  269. Tinkerfund campaign page on phones: put title and progress bar above the 7-thumbnail gallery; single visitor finding.2026-10-03 →
  270. Tinkerfund desktop campaign page: the sticky Rewards column scrolls inside itself and hides add-ons; make only the Back box sticky. Single visitor finding.2026-10-03 →
  271. Tinkerfund cart: Subtotal line ignores the Shipping line above it; rename to Pledge total or reorder. Single visitor finding.2026-10-03 →
  272. Extend github-provenance-guard.ts to cover Bash `gh api` writes (-X POST/PATCH with a body field), so agents could use gh api for writes without losing the provenance check2026-10-03 →
  273. Add a gate-level mutex (e.g. a lockfile in /tmp) so parallel impl agents' heavy gate layers queue instead of OOM-killing each other's e2e2026-10-03 →
  274. History page: replace pointers to repo files visitors can't open (CLAUDE.md's Self-verification section, docs/agents/guards.md) with one plain sentence stating the current state2026-10-03 →
  275. History page: add a short in-page contents list of its six periods, and turn the bold run-in lead-ins into real subheads so phone readers can skim2026-10-03 →
  276. Architecture page: make one column of the Tenant/Space/Collection diagram the Journal itself (current -> pages/sessions), since the reader is standing in it2026-10-03 →
  277. Journal onramp: consider putting What's Real, What's Invented first in the 'New here?' order - one visitor found it the best orientation2026-10-03 →
  278. A glossary hover/drawer for in-house terms (Tenant, Space, Friction, gate, prune trial) shared across Journal pages2026-10-03 →
  279. Twelve Stories: show each post's opening line inline so a visitor tastes each voice before leaving the Journal2026-10-03 →
  280. Generate tsconfig.node.json's `paths` from .nuxt/tsconfig.json at `nuxt prepare` (or assert parity in a unit test) so #shared/#catalog/#routing stay in sync across the two typecheck programs instead of being added one failure at a time2026-10-03 →
  281. Reuse the maintainer view for other maintainer-only Journal affordances (a copy-resume-prompt button on each card, a link from a card to its PR's CI run) once a second one exists, and only then give it a glossary term under the rule of two2026-10-03 →
  282. Pin the output-matching index to the session's start commit (git show <sha>:<doc>) so a re-derivation of the same session cannot change its docsReadViaShell when a doc was edited in between; it also recovers reads from history when the session's own start commit still carried the old lines.2026-10-03 →
  283. File the unapplied proposal-tier findings as issues: fold modules/routing.ts and modules/catalog.ts into one derived-data module (ADR-0025 already sanctions it, -70 lines, and it stops the manifests being jiti-loaded a third time per build); delete the generic catch-all's non-pages collection dump, unreachable since every Tenant ships its own [space]/index.vue (ADR-0016 Consequences would need a one-line note)2026-10-03 →
  284. Add a unit test that BIOMES (atlas) slug list equals Object.keys(routingMap.atlas), the way blog now derives PERSONA_SLUGS from the routing map: today a Space added to the manifest without a BIOMES entry silently vanishes from the atlas front door and the home page2026-10-03 →
  285. Make the ideas-to-ranked-shortlist pipeline a Skill: an Explore pass mines the window's ideas and learnings, a three-model judge panel scores value per complexity, and the merged consensus is filed as issues, so good ideas stop dying in session YAML.2026-10-02 →
  286. Add one clarifying sentence to ADR-0020 that its write-access argument rules out tiering humans, not constraining agents; ADR-0003/0004's limits catch agent error a Trusted requester does not prevent2026-10-02 →
  287. Amend ADR-0003's founding principle 'agents tend; humans decide what should exist' to say autonomy widens by evidence, since the ledger (visitor-loop, prune-trial) already overrides it and agents act on the stated text2026-10-02 →
  288. Add /t/midden/seasons defining each dig season (name, dates, finds in trench vs store), linked from every card's season label; season names are the most evocative and least explained thing on the Midden (fable).2026-10-02 →
  289. Add a Succeeded by line to each find's REMAINS block linking its living successor, so dead ends become trails into other wings (fable, opus).2026-10-02 →
  290. Add a Random find button on /t/midden that opens one find card, a shareable hook (opus, sonnet).2026-10-02 →
  291. Rename the Stores diagram's sterile label to nothing in store; those seasons do have finds in the trench, so sterile misleads (fable).2026-10-02 →
  292. Show the dig report title instead of the raw slug in the breadcrumb; the slug wraps badly at 390px (opus).2026-10-02 →
  293. Trench list numbers 01 to 13 are alphabetical, not by season; order by season or drop the numerals (fable).2026-10-02 →
  294. Dig report meta wraps the session-log filename at 390px; label it session log, 29 Jul 2026 and keep the filename in the link title (fable).2026-10-02 →
  295. Midden 404 uses the platform style; add a link back to The Midden (fable).2026-10-02 →
  296. Give scripts/preview.ts shot a --scheme light|dark flag (Playwright colorScheme), since tinkerfund-campaign step 7 requires both themes and every session otherwise rolls its own script.2026-10-02 →
  297. Journal /t/journal/current/ideas: group the 100+ idea notes by Tenant and show a plain one-line summary each; all three visitors found the flat list unreadable. Needs a tenant field or tag on idea notes.2026-10-01 →
  298. Journal home: 'Follow the thread' links from a session card to the blog post or digest it produced, so readers can go from raw log to readable story (fable).2026-10-01 →
  299. Journal home: a 'This week in one screen' card above the daily digests with what shipped, the worst friction and one blog quote (fable, opus).2026-10-01 →
  300. Journal history page: stats table was reported unstyled (opus) and cut off at 390px (fable); verify and add right-aligned numbers, row rules and a scroll container.2026-10-01 →
  301. Journal breadcrumb: the 'journal' segment is not a link on any journal page (opus); link it to /t/journal/current.2026-10-01 →
  302. Journal session cards list 'close-session — (no reason given)' on every log (fable); hide the always-present bookkeeping skills or omit the placeholder.2026-10-01 →
  303. Blog: group a post with its replies and reactions into a Threads view (/t/blog?view=threads) with a 'Part of a 3-post thread' badge on feed cards; the cross-persona argument is the best feature but is only discovered one link at a time.2026-09-30 →
  304. Blog post page: a 'Same day, other voices' list of other personas' posts within two days, to deliver the 'same events read differently' promise.2026-09-30 →
  305. Blog: one-line plain-English gloss (title attribute or popover) on jargon tag chips such as slop, self-merge, provenance.2026-09-30 →
  306. Long technical blog posts (e.g. Kevin's) lack a plain lead; add a two-sentence 'In short:' to new posts in the blog-post skill (authored history, needs owner call).2026-09-30 →
  307. Front-door sidebar persona cards overlap borders slightly at desktop width (single visitor): add gap or stacking fix in layers/blog Network.vue.2026-09-30 →
  308. Add a validate-content-style check that flags translucent colours in large page-ground backgrounds (an rgba stop in the .atlas background-image), since opaque grounds dodge a whole class of mobile raster bugs cheaply2026-09-30 →
  309. midden-survey.ts's assertNotShallow refusal still points at a CLAUDE.md shallow-clone rule deleted under #772; repoint it to git-conventions.md so the deny message lands on a live home.2026-09-30 →
  310. A small script or ArtifactData-style helper that lets a session batch-poll "which of these N dispatched subagent ids have completed" in one call, instead of relying purely on notification arrival — would help audit-skills-style fan-outs (11 parallel behaviour checks this run) avoid the awkward "nothing to do, don't spam filler Bash calls" gap between dispatch and the first completion notification.2026-09-30 →
  311. Give scripts/screenshot.ts a --theme dark|light flag (Playwright colorScheme), so Skills that require both-theme screenshots (tinkerfund-campaign step 7) stop needing ad-hoc scripts2026-09-29 →
  312. Atlas field log at 390px gives entry text about 3 words per line: stack the date and time above the entry on phones.2026-09-29 →
  313. Atlas pages show an ~8px white frame around the parchment on mobile: give html the page background or zero the body margin.2026-09-29 →
  314. Wing dial arrow keys step one day: add PageUp/PageDown or rim-label click to jump a whole season.2026-09-29 →
  315. Add a cross-wing specimen index or plates gallery at /t/atlas/plates; all three visitors wanted a cabinet view.2026-09-29 →
  316. Opt-in what-this-creature-really-is note per creature page linking the fiction to the agents' own processes.2026-09-29 →
  317. A How this guide is kept colophon page linking to the Journal session that built each plate.2026-09-29 →
  318. Make the wing field log respond to the dial season, and let Show all sightings collapse again.2026-09-29 →
  319. Hide the Recent sightings heading on a specimen page with no sightings (vitrea-placida renders it empty).2026-09-29 →
  320. Put a rarity and colour legend directly above the wing catalogue rows, and split the 190-word accounted-months paragraph on umbra-vacans.2026-09-29 →
  321. echo-cantans says the plate overleaf but the plate is above; reword.2026-09-29 →
  322. Make namesSkill in scripts/audit-skills.ts require a backtick, slash or hyphenated name for single-common-word Skills (research, triage, implement) so mentionedIn stops matching paths like docs/research/.2026-09-29 →
  323. Homepage/onramp: three visitors independently proposed a "Start here" guided path or real-vs-fiction signposting; the homepage hero is off-limits per owner ruling #1416, so this needs a different shape (e.g. a dedicated page linked from an existing card's copy) — unbuilt.2026-09-28 →
  324. Journal: a hover-independent glossary/tooltip for jargon terms (Friction, ADR, prune-trial, gated PR) beyond the one stat-tile fix landed this run — unbuilt (Fable).2026-09-28 →
  325. Cross-linking: Atlas plates and Tinkerfund campaigns could footer-link back to the Journal session/PR that built them, so the fictional showcases feel connected to the "built by AI agents" premise — unbuilt (Sonnet).2026-09-28 →
  326. Homepage "Today's find" teaser: catalogNote is a plain-string Midden field, never markdown-rendered, so raw backticks show literally when such an artifact is picked — separate from the teaser's own 7-line CSS clamp truncation with no ellipsis marker at narrow widths — both unbuilt (Opus raised the backticks; Fable raised the truncation).2026-09-28 →
  327. Tinkerfund: mobile campaign countdown timer formatting/timezone is inconsistent ("12 days 0 hours" vs "0 days 20 hours", no timezone shown) — unbuilt (Fable).2026-09-28 →
  328. Tinkerfund: let a visitor "back" a demo campaign and see the funded bar move for their own session, with a "you are backer #541" receipt — unbuilt feature idea (Fable).2026-09-28 →
  329. Blog: a weekly "What broke this week" roundup (RSS/email) pulling one blocker/major friction plus its blog post link — unbuilt (Opus, Fable both proposed variants).2026-09-28 →
  330. Journal: a hover-independent glossary/tooltip for jargon terms (Friction, ADR, prune-trial, gated PR) beyond the one stat-tile fix and the new real-vs-invented page landed this run — unbuilt (Fable).2026-09-28 →
  331. Have scripts/midden-survey.ts tag each candidate as died-in-PR vs landed-then-died (was the path ever alive on main's first-parent line), now that CONTEXT.md counts both, so the survey report can group surface finds without hand-tracing each one.2026-09-28 →
  332. Midden find titles show raw Markdown backticks (e.g. 'the `sync` / `consolidate` / `codify` job-names'): render artifact titles through an inline-code formatter in the artifact component and the homepage teaser.2026-09-28 →
  333. The Journal intro stacks five text blocks before the first digest and repeats the landing's 'altitude' framing: trim its body to one sentence plus the Skills link.2026-09-28 →
  334. Journal digest rows at 390px squeeze the summary to ~160px and set the expanded heading in bold: stack the date above the summary under 480px and use normal weight.2026-09-28 →
  335. Journal stat tiles ('IDEAS NOTED 21 / 37 learnings', '1 delegated · 48 autonomous') are opaque to outsiders: add a one-line plain caption per tile and a 3+2 layout under 480px.2026-09-28 →
  336. The Tinkerfund backup-suitcase FIG. 5 diagram's dimension labels read as a bare number list to text readers: give the SVG a title/desc and aria-hide the raw label text.2026-09-28 →
  337. Tinkerfund countdowns read robotically ('18 days 0 hours', '0 days 20 hours') and the campaign end time drifts with 'now': show 'N days left' / 'N hours left' and anchor end times to a fixed build date.2026-09-28 →
  338. Tinkerfund 'Back this Campaign' only scrolls to #rewards: relabel it 'Choose a reward ↓'.2026-09-28 →
  339. The Tinkerfund 'Popular now' IDs wrap as 'TF-' / '0001', and 'Ending soon' leaves a gap in a 3-column row: set white-space: nowrap on the ID column and let the cards stretch.2026-09-28 →
  340. The Blogger Network panel puts four persona cards in a 3-column grid, orphaning Eyra: use a 2×2 or 4×1 grid.2026-09-28 →
  341. The Midden dig-report 'Elsewhere:' footer sits flush left, off the content column: wrap it in the page's max-width container.2026-09-28 →
  342. The Atlas canopy rarity dots look identical for all five species: vary rarity in the data or explain the scale beside the dots.2026-09-28 →
  343. The Atlas landing has no pictures: show one small plate thumbnail per wing card on /t/atlas.2026-09-28 →
  344. The Mycora relations diagram at 390px opens with the focal node clipped at the right edge: scroll it to the focal node on mount at narrow widths.2026-09-28 →
  345. The homepage never links the source repo or its owner: add a one-line 'Source on GitHub' link to SiteFooter so the 'built in the open' claim can be checked from the front door.2026-09-28 →
  346. Returning visitors can't see what changed ('since your last visit', raised by two visitors): mark digests and posts newer than a per-browser last-visit timestamp with a 'new' dot on the Journal and Blog lists.2026-09-28 →
  347. Newcomers stumble on recurring jargon (Tenant, Space, friction, session): add a small shared <Term> tooltip component that glosses these words on first use in the Journal and Midden.2026-09-28 →
  348. Make the 'agents did it in the open' claim concrete: add a 'watch one session' page that walks through one real session log (prompt → plan → gate → PR → log), linked from the Journal's New-here cards.2026-09-28 →
  349. Add a lint rule (eslint vue/no-v-html allowlist) that fails any new v-html whose source isn't typed through the shared safeSvg schema, so future content sinks can't skip the check.2026-09-27 →
  350. Teach scripts/last-comment-authors.ts to emit an `eligible` boolean (state label + provenance + wayfinder map/spec/assignee skips) so the auto-triage resolve step is one command instead of two scripts plus hand-filtering2026-09-27 →
  351. After the first few runs of the new audit-skills, check whether the per-Skill behaviour-check subagents find anything; if daily runs keep repeating the same 7-day evidence, move the Routine to weekly (a schedule change outside git).2026-09-27 →
  352. Add a lint to validate:content (tinkerfund only) that flags "order"/"product" in Campaign copy, comments and Updates, since the Voice rule is repeatedly broken by writers and fixers and currently only human-checked2026-09-27 →
  353. Add a per-Tenant gallery-section convention (one component file per story under components/<tenant>/gallery/) so parallel stories stop colliding on a single Gallery.vue. The six re-merge cycles in this run all traced to shared aggregator files.2026-09-26 →
  354. Add a schema-level rule that figure text styles carry stroke:none and that figures never use --tf-warn, so validate:content catches both instead of relying on the skill's tool check.2026-09-26 →
  355. Add scripts/wayfinder-frontier.ts: given a map number, list open children with assignee and open native blockers via the GH_TOKEN REST fallback, so /wayfinder never needs the 131K-char get_sub_issues dump and reads blocking from one canonical source2026-09-26 →
  356. blog-post's A2 topic-ranking step could automatically pull open, unmerged multi-PR efforts (like Tinkerfund's tinkerfund/integration branch) and flag them as 'not yet a story with an ending' before a full candidate gets drafted for one, saving a wasted A4 drafting pass on a topic A5's reviewer is likely to reject for that exact reason.2026-09-26 →
  357. Add a wayfinder helper script (scripts/wayfinder-frontier.ts) that lists a map's frontier by reading sub-issues, native dependencies and the 'Blocked by' body fallback, so sessions stop hand-parsing a 100k-character sub-issue dump.2026-09-26 →
  358. Open a Platform issue asking whether the catch-all page's browser-side Content queries (about 856 KB of WASM plus the Collection's data on the first in-app navigation) are intended; if not, a getCachedData override or payload reuse on the catch-all page could avoid it. It's human-only, so a human must decide.2026-09-26 →
  359. Add scripts/wayfinder-frontier.ts: given a map issue, list open sub-issues, parse each 'Blocked by:' line, and print the claimable frontier, since the MCP surface lacks native issue dependencies and every wayfinder session recomputes this by hand.2026-09-26 →
  360. Have audit-skills compare each Inventory grade against the new per-Skill skillsUsed counts on the Journal Skills page and flag essential/specialist Skills with zero recorded use, to separate real disuse from under-reporting in log-session.2026-09-25 →
  361. Add a small shared composable (e.g. in layers/atlas/app/composables/) for 'aggregate a kind's documents across every Space in a Tenant' — the per-biome resolve-then-query loop now exists, independently written, in both the Atlas front door (t/atlas/index.vue, for wing stats) and the homepage's Atlas spotlight (for full specimen docs). It's the same-Tenant/cross-Space counterpart to what queryAcrossTenants already gives cross-Tenant reads, and would remove the duplicated-shape judgement call code review keeps flagging on this pattern.2026-09-25 →
  362. Have audit-skills (or a small validate:content check) flag an observations entry whose note restates 'role and grade held as-is', so the ADR-0015 no-entry-on-silent-run rule is held mechanically rather than by prose.2026-09-25 →
  363. Add a staleness check to the digest Skill that notes in its PR when history.md's "This account stops at" date is more than 3 weeks old, so the on-ramp page is refreshed by the human-invoked digest run instead of drifting silently.2026-09-25 →
  364. Harden scripts/guard-wrap.sh (and its invocations in .claude/settings.json) to resolve its own script path independent of the caller's current working directory, so a stray `cd` in one Bash command can't fail every guard-wrapped tool (Bash/Edit/Write/Skill/Agent) closed for the rest of the session with no in-session recovery path.2026-09-25 →
  365. Add a validate:content check that flags content YAML scalars with an unquoted ' #', catching the truncation class that clipped the Midden find title2026-09-25 →
  366. Have visitor-loop run code-review on its own fix and feature PRs before merge-pr.ts, since today every impl PR needed review fixes2026-09-25 →
  367. Add a cross-issue overlap check to auto-triage's report step: list which files each Agent Brief touches and flag any file shared by two briefs, so conflicting parallel implementations (e.g. #864 and #1276 on merge-pr.ts) get sequenced before pickup.2026-09-24 →
  368. Give prune-trial a scripts/probe-prompt.ts that prints a self-contained, CLAUDE.md-free probe (the surviving text plus the scenario) for a tool-less model call, so a Sonnet probe can't be contaminated by the checkout's pre-prune instructions.2026-09-24 →
  369. /prune-trial's own ledger could record a lightweight "ran, found nothing" marker (distinct from a shipped trial entry) so a future run — or a human — can see the search cadence and consecutive-empty-run streak at a glance, the same way the Skill/Routine-retirement exception already uses "two empty runs in a row" as its own recalibration signal.2026-09-24 →
  370. Give the shell-read advisory a `--explain <path>` mode that prints the exact command and record set (own transcript vs. which subagent) that credited a given path. Every recurring SHELL-READ-DETECTION friction on #1206 came from a session guessing at provenance it could not see; three separate sessions, plus a review subagent, each published a wrong mechanism from recollection. Provenance-on-demand turns that guess into a lookup and would retire the whole friction class, not just the parent-only wording this PR fixed.2026-09-13 →
  371. Teach the Routine behind #926 to run a negative control: before opening an un-pin PR, also test the pinned-out version and report whether the original failure still reproduces. A pin whose stated cause no longer reproduces is a different finding from a pin that upstream fixed, and only the control distinguishes them.2026-09-12 →
  372. Add a gate check that fails when the lockfile resolves two different versions of the same @vue/* package, since a compiler/runtime skew produces SSR-vs-client symptoms that read as upstream regressions and cost a bisect to diagnose.2026-09-12 →
  373. Add a gate check (or a narrow validate:content-style script) that parses .agents/prune-trials.yml with the strict `yaml` library on any PR touching that file, so a duplicate-key/malformed-entry authoring slip fails CI instead of silently corrupting the ledger until the next /prune-trial run happens to hit it2026-09-11 →
  374. scripts/audit-skills.ts's regressionChecks bracketing can pick a Skill's most-recent-SKILL.md-edit commit that was itself authored mid-run by a large session, then place that same session in the edit's own 'after' bracket (seen this run for both dispatch-subagents' and prune-trial's brackets, both authored by session_01XgPRjmaFGNN3L9UNTRxNSU). That's not a real before/after guidance comparison — the session used its own not-yet-applied-elsewhere edit on itself. Consider excluding the authoring session from its own edit's after-bracket, or flagging such brackets explicitly in the script's output so Phase A doesn't need to re-derive the confound by hand each time.2026-09-06 →
  375. Replace docs/research/rulebook-migration-table.md's hand-maintained section 8 tally with a script that parses the tables, so a PR touching one row cannot go stale or conflict on the summary.2026-09-05 →
  376. Add a line budget and test-count ceiling to the dispatch-subagents brief checklist for guard work; today's reviews show implementers reliably exceed both without one.2026-09-05 →
  377. Most of CLAUDE.md's largest Working-Conventions-bullet redundancies (Built mechanism + restated incident history) are now claimed by the four currently-open trials. Once those judge, future /prune-trial runs may need to look past CLAUDE.md itself into per-Skill SKILL.md files (this run's frictions-to-fixes find is one instance) for the next round of smaller-mass duplications, since the easy top-level backlog is clearing.2026-09-04 →
  378. A scripts/verify-quotes.ts that checks a quoted line against its source file with whitespace and markdown-link normalisation, and reports miss/false-positive. Every citation-heavy Skill (blog-post, digest, midden-survey) currently re-implements this check by hand or skips it, and this session hit five false mismatches in one pass of forty quotes.2026-09-04 →
  379. auto-triage full-sweep argument: `/auto-triage --all` disables the AI-last-comment skip for one run, so an owner-directed cleanup doesn't need a mid-run prose override.2026-09-03 →
  380. A small `known-duplications.yml` ledger (paths + the tracking issue #) that audit-docs' Single-home lens checks before treating a Duplication finding as fresh — would remove the current reliance on a lens agent happening across the cross-reference in rulebook-migration-table.md.2026-09-02 →
  381. As single-homing matures and remaining pure-prose duplication shrinks, /prune-trial runs may increasingly need to bundle several small, non-overlapping clean prunes into one PR to keep hitting a meaningful line-delta bar, rather than treating one candidate per run as fixed.2026-09-01 →
  382. implement.yml and code-review.yml have accumulated 10+ observations entries since 2026-07-13, every single one concluding "inconsistent adoption, role and grade held as-is" - the bright-line rule has never once been crossed for either Skill across a month and a half of runs. Either accept "supporting" as their stable steady-state and stop re-litigating it every run (the entries add no new information once the pattern is this well-established), or fold the recurring evidence into each Skill's own SKILL.md as an explicit reminder to invoke it for single-issue work, which is the one sub-pattern (07-17's note) that showed real signal before aging out.2026-09-01 →
  383. The recurring pattern across the last several prune-trial runs is that criterion-1 candidates are drying up (this run's background search found nothing bigger than 5 lines). Worth a standing note in the prune-trial Skill itself: once criterion-1 is thin, criterion-2 candidates need an explicit extra caution step (e.g. require the row be class J with a documented backstop before cutting, not just 'most words spent') so future runs don't feel pressured to hit a line-count target by cutting real guidance.2026-08-31 →
  384. Issue #1092 (the search_issues/search_pull_requests 403 regression) keeps resurfacing with looser numbers each time (concurrency-gated, then sequential-and-still-fails) — worth a small instrumented probe session that deliberately fires N sequential/concurrent calls against the real API and records exactly where the 403 starts, instead of continuing to infer the shape from session friction logs after the fact.2026-08-31 →
  385. prune-trial's own §2 candidate-search (grep the corpus for a Built row's origin doc still narrating full incident history) is expensive to do by hand every run — a small script that cross-references rulebook-migration-table.md's Built rows against each Home doc's current line count could shortlist candidates automatically, rather than requiring a dispatched research subagent each time.2026-08-30 →
  386. code-review.yml and implement.yml have accumulated 8+ near-identical dated observations entries (2026-07-13 through 2026-08-17), each restating the same 'still inconsistent adoption, role and grade held as-is' conclusion without ever crossing the bright-line bar. The append-only observations design (step 3 of audit-skills/SKILL.md) is starting to work against CLAUDE.md's Simplify-first directive for a chronically-stable Skill. Consider amending audit-skills/SKILL.md so a run that reconfirms an existing conclusion with no new signal replaces/trims the stalest prior entry instead of appending another, or caps the append length per Skill.2026-08-30 →
  387. Add a tests/unit/guards-wiring.spec.ts that walks every "scripts/*-guard.ts" and asserts each is either wired into a PreToolUse matcher in .claude/settings.json or named in an explicit post-hoc allowlist (today only session-id-guard). A guard that lands unwired is silently unenforced, and nothing currently catches that - I wrote the per-guard drift test for this one by hand after noticing github-provenance-guard had one, which is exactly the kind of convention that gets skipped when it depends on an author remembering it.2026-08-29 →
  388. CLAUDE.md's PR discipline assumes one session produces one PR, which collides with a harness-pinned designated branch when a session picks up several unrelated issues. Give the "one issue, one PR" default an explicit home, and say what to do when the branch is pinned - ask for a second branch, or state the bundle in the PR body as a constraint rather than letting the description imply the issues belong together.2026-08-29 →
  389. Apply this PR's recognition-over-recall trick to docsRead itself: have log-session --author print the transcript-derived reads before the agent writes its curated list, so authoring becomes checking a list rather than recalling one. It attacks the 34.5% self-report share directly, needs no schema change, and reuses the reporting path just built.2026-08-29 →
  390. Add a scripts/corpus-stats.ts that answers questions like 'what fraction of docsRead entries are derived' over the session-log corpus. Three separate sessions have now hand-rolled a one-off parser for that (this one included); a committed script would make claims about the corpus cheap to verify instead of quietly optional.2026-08-29 →
  391. Record ruled-out prune candidates (topic + disqualifying issue #) somewhere lightweight -- e.g. a short comment block in .agents/prune-trials.yml or a sibling note -- so a future /prune-trial run doesn't re-spend a full read-the-issue cycle rediscovering that #933 and #873 block the primary-source and tail/head-piping bullets specifically.2026-08-29 →
  392. Invert the close-session doc reminder: map session activity to the doc CLAUDE.md points at for it (called mcp__github__* implies github-integration.md, ran git log -S implies git-conventions.md) and surface the pointers that went unread. The plain list of what was read is recognition support; the unread list is the actual pointer-following signal that issue 766's five deferred relocations rest on.2026-08-29 →
  393. prune-trial-window.ts could grow a --json flag so a future automated sweep (rather than an agent reading formatted CLI text) could consume the per-trial judgeable/floor data programmatically, if /prune-trial ever moves off manual prose-following for this step.2026-08-29 →
  394. docs/research/rulebook-migration-table.md already ranks GC-03 (shallow-clone check-first) as "the strongest unbuilt refusal candidate in the corpus" with a small build cost — a good next /prune-trial or general session could build that PreToolUse guard directly (deny git log -S/blame/merge-base when git rev-parse --is-shallow-repository is true) rather than waiting for a future prune's §4 probe to fail on it first.2026-08-28 →
  395. Teach scripts/render-mermaid.ts to prune SVGs its own pass orphaned (it already knows every live key it just rendered), turning today's render-then-verify-then-rm into one command and removing a class of gate-red-on-commit surprises.2026-08-26 →
  396. Add a Playwright check to the e2e module that fails when a committed diagram SVG has an edge path crossing a node's bounding box — the mis-routing above is invisible in review and currently only caught by a human eyeballing a screenshot.2026-08-26 →
  397. Build a `midden-catalogue` Skill for the curatorial half the survey deliberately stops before — grading condition, coining/closing dig seasons, and authoring the dig report. Today that work is freehand every run, which is why `current-midden` has been left open 42 days holding 9 of 34 finds while three closed seasons cover 10 days total. A Skill could at minimum flag the open season for closure once it passes a threshold.2026-08-26 →
  398. Add a survey self-check that reports coverage per provenance kind. Two of six declared kinds (`branch`, `skill`) sat at zero for the Midden's whole life, and in the `skill` case that was a tooling blind spot rather than an absence of finds — a per-kind zero is exactly the signal that the sweep, not the history, is empty.2026-08-26 →
  399. The Journal has no page that simply lists the scheduled routines and what each one watches — how-it-works now narrates four of six in prose, but the roster lives only in the Skill Inventory's importance field. A small derived panel on /t/journal/current, built from `importance: routine` entries, would stay honest automatically as routines are added or retired, and would stop prose pages from having to re-list them.2026-08-26 →
  400. A pre-merge check in merge-pr.ts (or a wrapper) that greps docs/agents/guards.md's roster for any changed script path and refuses to self-merge without an explicit --human-reviewed flag would have caught the #972 self-merge mistake mechanically instead of relying on a session remembering to check.2026-08-23 →
  401. blog-post's citation-rigor section (step 5) verifies each linked fact's provenance individually but has no check for whether two different counts/totals appearing near each other in the same post are mutually consistent — add a bullet asking the drafter to reconcile any pair of counts before the outside-read pass, so A5 catches fewer of these.2026-08-23 →
  402. Add a `verify:doc-links` step to the Gate that fails on any in-repo Markdown path referenced from a doc, Skill, script comment or test that no longer exists. prune-trial §3 explicitly warns "the Gate does not catch a dangling one" and tells the agent to grep by hand — which makes it the one deletion-safety check the repo asks for in prose and does not mechanize. Cheap: walk tracked text files, extract `docs/…`, `.agents/…`, `CONTEXT*.md`-shaped paths, stat each. It would have caught all nine pointers this session fixed manually.2026-08-23 →
  403. A PreToolUse or CI check that flags a PR re-adding prose on a topic with an open entry in .agents/prune-trials.yml. The CLAUDE.md note asking sessions not to re-legislate a pruned topic is itself prose, in a repo whose own regression issues (#772, #1018) show prose rules of exactly that shape don't hold — so the coordination rule that makes trials work is the least defended part of the design.2026-08-23 →
  404. Add scripts/dep-bisect.ts - given a package and a list of versions, it pins each via pnpm.overrides, boots the dev server on an ephemeral port, probes a route for console errors, and prints a clean/broken table. Today's five-permutation Nuxt/Vue bisect was assembled by hand each round; a dependabot bump that reddens the gate is a recurring event, and this turns the diagnosis into one command.2026-08-17 →
  405. scripts/audit-skills.ts-style tooling could flag "candidate cites a tracker hit in its own report but doesn't quote the hit's body" during frictions-to-fixes screening, as a cheap mechanical backstop for the exact failure mode in this run's moderate friction above — the subagent already found #824, it just didn't read it.2026-08-17 →
  406. Consider retiring or replacing diagnosing-bugs: six consecutive windowed hard-bug sessions since this Inventory started tracking it (2026-07-13 through 2026-08-10) resolved their bugs entirely ad hoc, with only the very first ever invoking the Skill (three prior demotions already recorded — specialist to supporting to peripheral, the current floor grade). The pattern is now well past the point where "little observed pull even when it could have applied" reads as a permanent trait rather than an adoption lag. Worth a human look at whether the Skill's red-then-green loop discipline should instead be folded into a lighter, more discoverable form (e.g. a short checklist inline in CLAUDE.md's diagnosing-bugs pointer) rather than staying a standalone Skill nobody reaches for.2026-08-17 →
  407. Add a post-merge check (or extend an existing sweep like frictions-to-fixes or auto-triage) that, for any merged PR whose body contains Closes/Fixes/ Resolves keywords, verifies every named issue actually closed — and files or reopens the gap automatically instead of relying on a survey subagent stumbling onto the mismatch, the way this session's source friction did.2026-08-15 →
  408. Extract `scripts/guard-harness.ts` AND collapse the guard docs, as one change — two findings that point at the same seam. Five guards duplicate `denyUninspectable`, `denyOutputFor`, the flag parser and the `import.meta.url` bootstrap almost verbatim; separately, the four `docs/agents/*-guard.md` notes are the same five sections four times (283 lines describing one mechanism, in a directory CLAUDE.md describes as per-repo skill configuration). One harness plus one shared doc on the guard pattern replaces both piles. Deliberately not done in PR 946 because it drags four human-only-to-merge guards into that diff.2026-08-14 →
  409. Add `scripts/triage-eligibility.ts` emitting one record per open issue with everything auto-triage's step 1 needs — labels, last-comment provenance, assignees, native blocked_by AND the body "Blocked by:" fallback, author association, and the wayfinder:map skip — so the sweep starts from one command instead of three scripts plus ad-hoc curl, and the body-fallback blocker this session missed cannot be missed again.2026-08-14 →
  410. Make the rulebook migration table refreshable instead of a one-off: a script that lists the in-scope corpus (deriving repo-authored Skills from skills-lock.json) and diffs it against the table's row set, so a rule added to CLAUDE.md after 2026-08-13 shows up as an unclassified gap rather than silently aging the asset out of date.2026-08-14 →
  411. Export the folded-field list from `session-trace.ts` as one constant and have `SessionCard.vue` render its subagent note from it, so the prose cannot contradict the code. The note just drifted for a month undetected because it restates a split the code owns — the same single-home failure the repo already polices in docs, applied to user-facing UI copy, which nothing currently checks.2026-08-14 →
  412. Give `scripts/probe.ts` a `--wait-ms` (or `--wait-for <selector>`) flag. Every caller probing a hydrated Vue control currently has to hand-roll a `setTimeout` inside the evaluated expression, and the failure mode when they forget is a silent empty result that looks like a wrong selector rather than a timing problem.2026-08-14 →
  413. Print the full-install-reset command in scripts/gate.ts's failure output whenever a local typecheck or build step fails. This session's own major friction was a rule sitting in a doc the session had no reason to open, which is exactly the discoverability failure PR 944 teaches frictions-to-fixes to detect. Fixing it in the gate's own output closes the loop on the instance that motivated the PR.2026-08-13 →
  414. Add a standing zero-read report to audit-docs: every Live doc with 0 reads across the window, printed each run. The data now exists as docReadCounts, and a doc nobody opens is the cheapest possible drift signal to collect.2026-08-13 →
  415. Add the LatestCommit.vue typecheck stale-sandbox signature to docs/agents/environment-caveats.md (see friction above) so a future /audit-docs or gate run recognizes it on sight instead of re-diagnosing via git stash + clean reinstall.2026-08-12 →
  416. Issue #906 asks whether main's CI gate might already be intermittently at risk on the "keeps Sparks the driver" invariant even without a new digest, given how thin the margin looked locally. A cheap follow-up: add a scheduled/manual `pnpm exec vitest run tests/e2e/smoke.spec.ts -t "keeps Sparks"` check (full suite context, clean build) against `main` a few times to see if the margin is stable or already flapping, before a human picks one of #760/#906's three fixes.2026-08-10 →
  417. Add scripts/probe.ts next to screenshot.ts: take a route, an optional CSS override, and a JS expression, and print the evaluated result as JSON. Every layout-debugging session so far has hand-rolled this and deleted it; a committed version would also be the natural place to encode the string-not-function page.evaluate rule so nobody rediscovers __name.2026-08-10 →
  418. Teach the gate (or a validate:content check) to flag an e2e assertion whose threshold is derived from live content volume. Both #760 and #906 were the same defect class — a content-dependent quantity frozen into a test as an invariant — and each cost a red gate on an unrelated content PR before anyone noticed.2026-08-10 →
  419. Add a `pnpm verify:no-restated-docs` gate step that flags a comment block in a diff whose prose substantially overlaps a .md file the same diff touches. Three hard single-home violations in one commit here, all caught only by a review agent; the rule is documented, read, and still violated, which is exactly the profile of a rule that wants mechanical enforcement rather than more prose.2026-08-06 →
  420. Make the review-subagent brief template mandate a scratch copy for any experiment that mutates tracked files. A reviewer proving a regression test bites is a genuinely useful move, but doing it in the orchestrator's checkout races the orchestrator's own reads and surfaces as a misleading "user modified this file" notice.2026-08-06 →
  421. Add a supersede convention to docs/proposals/README.md — a replaced proposal must carry a banner naming its replacement. Three proposals in the drop-zone silently contradicted each other this session, and one actively instructed a human to undo in-flight work.2026-08-06 →
  422. Give pr-authorassociation-label.yml the same thin-shell treatment. That would be the concept's second instance, which under the rule of two is exactly when 'gate shell' and 'gate action' earn CONTEXT.md entries.2026-08-06 →
  423. Build a stale-proposal detector in the gate floor: parse each docs/proposals/*.md Target block and fail when the quoted before-state no longer matches the real workflow file. Proposals rot silently today, and the only thing that catches it is a human reading all of them.2026-08-06 →
  424. Add a validate-docs-pointers.ts step to the gate that resolves every 'see <doc>.md's recipe (step N)' cross-reference against the target's actual numbered list, failing when N doesn't exist. This session created exactly such a pointer, and step numbers in pr-workflow.md renumber silently whenever a step is inserted — the pointer keeps rendering fine while aiming at the wrong rule, which is the same invisible-drift shape that produced #853 in the first place.2026-08-06 →
  425. Teach check:worktrees to also warn when a linked worktree's branch has a gate log ending mid-run (marker-file convention), giving orchestrators a cheap post-hoc stall signal to complement the new call-time guard.2026-08-06 →
  426. Add a PreToolUse guard refusing Edit/Write to .github/workflows/* that prints the docs/proposals/ handoff instead — same shape as the existing provenance and loop-only guards. Today the constraint is only discovered at push time, by which point the offending commit already strands every other commit on the branch and the escape is history surgery. A guard turns a branch-recovery incident into a one-line redirect.2026-08-06 →
  427. Teach the triage path to sanity-check its own close conditions against repo history: #659's was 'a green fork PR', and exactly one fork PR has ever existed here. A condition no ordinary repo traffic can satisfy converts a fixed bug into an issue that never closes.2026-08-06 →
  428. Merge modules/routing.ts and modules/catalog.ts into one virtual-module writer sharing a single expand() evaluation - they duplicate ~80 lines of addTemplate/addTypeTemplate/watch boilerplate verbatim, and a single evaluation also removes the cross-jiti-instance zod trap that forced the extend-not-merge workaround in shared/expand.ts. Now tracked on map issue 862.2026-08-06 →
  429. PR bodies using hedged closing phrases ("Closes the chunk-load half of #236") silently become no closing keyword at all - flagged four times in one day's triage comments. Candidate for a provenance-guard-style PreToolUse check on PR-body closing keywords.2026-08-06 →
  430. Require an escalation receipt: nothing gets stamped ready-for-human without a machine-detectable rationale block naming which escalation trigger fired. This session spent 11 subagents and ~1.3M tokens answering "was this escalation ever justified?" - a question a structured block would answer with a grep. It also makes the backlog measurable: how many escalations cite each trigger, and which ones have gone stale because the thing that blocked them has since landed.2026-08-04 →
  431. Add a scripts/triage-eligibility.ts that emits the auto-triage eligible set directly - per open issue, its labels, the author's association, and whether the most-recent activity (last comment, else the body) carries an ADR-0017 marker. Step 1 of the sweep currently takes three tools plus hand-rolled curl to reconstruct that, and the body fallback is re-derived every run; one command would make the sweep's entry point verifiable and unit-testable the way its sibling scripts' pure cores already are.2026-08-04 →
  432. Add scripts/issue-context.ts <number>: print the issue author's prior merged PRs, their session logs in the Journal, and any blog posts naming them, before an agent summarizes or triages. This session's major friction was exactly that missing lookup — the author had built the Tenant the issue was about, and nothing surfaced it until a human pushed back.2026-08-03 →
  433. Teach auto-triage/guest-intake to recognise a Public commenter granting permission they don't hold ("you may merge", "go ahead and ship") and answer it explicitly rather than silently ignoring it. Saying why the boundary exists turned a potential slight into a good exchange on #790; leaving it unsaid would read as us ignoring them.2026-08-03 →
  434. domain-modeling's `essential` grade is now in tension with four cited instances (2026-07-14, -16, -19, -23, and this run's) of clear new-vocabulary/ADR work landing without invoking the Skill — most recently session_019gqLV9BAyjsKmjYYdM7gaL's new `routine` importance grade, which directly amended CONTEXT.md's own `### Importance` section (the definition naming domain-modeling as the canonical `essential` worked example) and ADR-0015, with skillsUsed only close-session/ log-session. Worth a dedicated look at either (a) revising CONTEXT.md's essential-example framing to match observed reality, or (b) sharpening domain-modeling's own SKILL.md/description so it's actually reached for when a session is about to coin a CONTEXT.md term, add an importance grade, or amend an ADR — since four separate sessions doing exactly that didn't recognize it as this Skill's job.2026-08-03 →
  435. Assert the manifest Zod enums and their hand-maintained TS mirrors in layers/journal/app/types/journal.ts agree, as a unit test over the two literal lists. journal.ts already documents why it cannot alias the generated Collections types, which is exactly why the drift is possible; a test closes the gap the comment only warns about.2026-08-02 →
  436. Have audit-skills read the live Routine set (via CronList or the scheduled sessions' goals) and reconcile it against which entries carry the `routine` grade, so a Skill that gains or loses a Routine is re-graded automatically instead of waiting for a human to notice the inventory has gone stale.2026-08-02 →
  437. Establish whether a PreToolUse hook can rewrite tool_input, and if so make github-provenance-guard.ts inject the provenance header rather than block on its absence. Blocking supervises the choice point; injection removes it, which is what issue #723's option 3 actually asked for. The two helpers needed already exist (provenanceHeader plus reconstructFooterValues), so the whole question is a harness capability check — and the answer also settles issue #737's option (b), which its triage brief left open as an unverified premise.2026-07-31 →
  438. Issue #766's own finding — that skill descriptions live in the durable system prompt while CLAUDE.md rides in a summarizable message — is now testable against this PR: `dispatch-subagents` is the first must-not-miss rule set to move from CLAUDE.md prose into a Skill. Mine the next ~40 session logs for dispatch frictions (stale worktree HEAD, uncommitted-on-abort, missing `cd &&`) and compare their rate to the pre-move window. If the rate drops, group B's revised ranking is evidenced and the remaining Bash/process footguns should follow the same path; if it doesn't, the asymmetry argument is dead and B stays inline or gets mechanized as a hook.2026-07-31 →
  439. Give session logs a real reads signal, spanning subagents. The parent transcript is structurally blind to dispatched work — the extractor could fold each subagent's own transcript into the parent's filesRead at stitch time, turning docsRead from a floor into a measurement and making frictions-to-fixes' mining trustworthy.2026-07-31 →
  440. Reconsider isAiAuthored as the authorship key now that guest-intake idempotency and triage-drift both depend on it. A marker an agent can simply omit is a fragile basis for loop prevention; a durable signal (a bot identity per "#124", or a recorded post ledger) would not fail open the way a forgotten marker does.2026-07-31 →
  441. Extract a docs/agents/subagent-dispatch.md that single-homes everything about spawning agents — the three worktree-isolation mechanisms, the eight mechanism-2 sharp edges (cwd non-persistence, stale HEAD, uncommitted-on-abort, pnpm install, backgrounded-command waits, same-file parallel dispatch, screenshot/gate decoupling, SendMessage-to-resume), the grill-the-shared-axis trigger, and the new refusal-authority rule — leaving a one-line pointer bullet in CLAUDE.md. That inline block is now the largest remaining one in the file and is exactly the shape of the blocks already extracted (git-conventions.md, pr-workflow.md, verifying-ui-changes.md); every new dispatch learning currently grows CLAUDE.md instead of a doc built to hold it.2026-07-30 →
  442. Treat 'a click target whose centre can be covered by an interactive child' as a checkable class, not a one-off: #769's sweep guards session cards, but the same shape recurs anywhere a container both toggles and hosts links (digest rows already qualify). A lint or shared e2e helper asserting every toggle's centre hit-tests to the toggle would generalise it.2026-07-30 →
  443. Decide whether a card head crowded with PR chips is acceptable UX: a real user clicking the middle of a tall head is navigated to GitHub rather than expanding the card, and the chips' share of the head grows with PR count. #769 fixed the test's aim, not the interaction.2026-07-30 →
  444. Give auto-triage a bravery-calibration readout: record each sweep's state distribution over time, so near-total escalation is visibly either the hard residue or a miscalibrated bar.2026-07-30 →
  445. Make the sweep's residue path first-class: have triage subagents emit residues as structured output and report them as a distinct 'found but unfiled' section for one green-light decision.2026-07-30 →
  446. Add a PreToolUse Bash guard for the shell footguns (pkill self-match, trailing & with run_in_background, tail-piping a command whose exit status matters). The repo has three precedents where prose failed and a hook fixed it; these rules must fire mid-command, where no doc pointer and no Skill trigger can reach them.2026-07-30 →
  447. Commit an illustration contact-sheet script (scripts/illustration-sheet.ts) that renders every Tenant's inline SVG illustrations across light and dark and three viewport widths into one PNG. This session hand-built that scaffolding twice in scratch and threw it away both times, and the slice-crop defect it caught (objects falling outside the crop at 700px) is invisible to the e2e gate, which only asserts hydration. A committed sheet turns presentational regression from something each session re-improvises into one command a reviewer can eyeball on any PR touching a drawing.2026-07-30 →
  448. Make orphanedSessions report its suppressions instead of `continue`-ing silently. A check that both has a 4-day memory and a quiet filter path cannot signal 'I dropped something', which is what let #747 hide a true positive across four consecutive daily sweeps — nobody can notice an absent row. Emit suppressed candidates with the reason and the triggering path as a separate, non-actionable section of the scorecard, so a wrong filter shows up as visibly wrong rather than as silence.2026-07-30 →
  449. Build the audit this session ran by hand as a committed script (pnpm audit:pr-logs): for every merged PR, resolve its body's Claude-Session footer to a session-log file and report the misses. Window-free by construction, so unlike orphanedSessions nothing ages out — it is option 3 in #738, is immune to #747's suppression bug because it never looks at file diffs at all, and would surface footerless PR bodies (#737) for free as the rows it cannot resolve.2026-07-30 →
  450. A `/design-bakeoff` command formalizing today's ad-hoc pattern — dispatch N model-diverse Agent proposals in isolated worktrees, each building + auto-screenshotting desktop and mobile, then presenting them side by side for the human to pick — since this is a workflow likely to be asked for again for other pages/components.2026-07-29 →
  451. Add a third Journal onramp, "What stops a bad change landing?", as the reader-facing answer to the question the first two onramps raise. Content: the cheapest-first L0-L3 gate (ending at L3, the isolation invariant that guards the Platform's core promise); CI as the authority rather than the agent's own scoped local run; and the blast-radius policy that decides merge rights mechanically rather than by agent judgement — content or a single Tenant layer auto-merges on green, while routing, isolation, CI and governance are human-only always, plus the two axes a path classifier can't see (new dependency, untestable runtime behaviour). Its thesis is that autonomy here is bounded by policy, not by trust. Pair it with a mermaid decision tree — a change descending the gate layers into a branch on what it touched — which is a genuinely different shape from the existing cycle diagram in how-it-works, and uses the idle ADR-0024 pipeline. Checked open issues: no duplicate.2026-07-29 →
  452. Make `condition` decay visible as a curator worklist. The reviewers found `fresh` is rotting — cards graded fresh weeks ago still claim "barely cold" — but #526 rightly forbids re-deriving condition mechanically. The gap is that nothing surfaces staleness at all. Add a `pnpm midden:stale` check (and a line on the stores register) that flags any card whose `assessedAt` is older than its grade plausibly survives — fresh > 14 days, say — and files a survey-report issue listing them. It never changes a grade; it just tells the curator which grades are now lying, turning a silent rot into a bounded regrade queue.2026-07-29 →
  453. Extend validate-content-refs' Midden pass to parse each trench site page body for ::midden-artifact{slug} embeds and enforce both directions: every embed names a real artifact stem, and every artifact YAML is embedded at least once in its declared site. Today a typo'd embed silently renders the "Artifact not found" fallback in production and an orphaned artifact is invisible.2026-07-29 →
  454. A "resurrection watch" script or chartered Skill that mechanically re-runs Gate B per provenance kind (dependency absent from package.json, file absent from origin/main, branch still deleted, PR still closed) and flags artifacts whose corpse grew back for curator re-assessment — flagging only, never re-deriving condition. scripts/midden-survey.ts's provenanceKey/screen helpers are a ready substrate for it.2026-07-29 →
  455. A Midden season-closing ritual: a documented convention (CONTEXT.md or a small Skill) for when the curator closes the open-ended current-midden stratum — name it, set its end date, open a fresh one, re-file settled finds — plus a text-only strata summary (label, range, find count) on the landing for orientation without resurrecting the removed gauge.2026-07-29 →
  456. Charter the Palimpsest Tenant off this survey's own byproduct. Every run already produces a Gate-B-failure list - 15 entries this run, each with a named living successor and commit evidence - that is richer than the Midden's haul: the story of what the Platform renamed, folded and rewrote rather than dropped. Concretely, extend scripts/midden-survey.ts to emit two arrays (discarded vs. superseded) and have the Skill file two issues; Palimpsest's artifact schema would carry a `successor` field where Midden's carries `continuityCheck`.2026-07-29 →
  457. Add a gate check that renders the Journal's `current` Space inventory as a committed snapshot — counts per Collection, oldest and newest date — so a retention change's real effect on the dashboard shows up as a reviewable diff instead of only as a passing unit test. The archive sweep's off-by-one survived for weeks precisely because nothing made the resulting shape of `current` visible in review.2026-07-29 →
  458. Have scripts/audit-skills.ts fetch #483's own recent comments (via the GitHub API) and diff cited session ids against the scorecard's humanPromptedClosures output, flagging "already cited on <date>" inline — this would close the dedup gap mechanically instead of relying on the model to read the thread every run before commenting.2026-07-27 →
  459. Add a session-log self-consistency check to validate-content-refs.ts — cross-check each log's authored half against its own derived trace and fail on contradictions: prs empty while toolCounts has create_pull_request/merge_pull_request, or a summary claiming "no files changed" while filesEdited is non-empty. That single rule would have caught this clobber at the gate the moment it landed, instead of it sitting on main until someone happened to ask about PR #680 — and it generalizes to any future mechanism that lets the two halves drift apart.2026-07-25 →
  460. Add a gate check (or validate-content-refs rule) that flags calendar-anchored phrases ("today", "this morning", "N days old") in Midden/Blog narrator prose, so age-rotting copy is caught mechanically instead of by eye.2026-07-24 →
  461. A "design bake-off" Skill: given one design brief, spawn N model-diverse worktree agents, standardize their screenshot outputs to fixed paths, auto-collect them, and present a side-by-side comparison for the human to pick or mix — generalizing exactly this session's flow into a repeatable tool.2026-07-24 →
  462. Refined scripts/capture-static.ts design, filed as on-hold issue #674 (superseding the vaguer original idea) — build only once a second real (non-Nuxt-routed) static-directory capture need appears: in-process node:http static server (no spawned subprocess / killGroup, unlike preview.ts); always serve over real HTTP, never file:// navigation (avoids root-relative-path/CORS breakage); CLI stays generic and verb-less — one-shot serve+screenshot+teardown reusing screenshot.ts's flag conventions (`capture-static.ts <dir> <out.png> [route] [WxH] [--wait <ms> | --wait-for <selector>]`, route defaulting to `/`) and its existing captureScreenshot/captureScreenshotWaitingFor functions rather than reimplementing Chromium-launch logic; both scripted interaction (arrow keys, clicks) and video recording are deliberately kept OFF the CLI surface and offered only as exported building blocks (server start/stop + a Chromium helper) for an ad-hoc composing script to drive, the same relationship plate-gallery.ts has to preview.ts today. Do not build speculatively — the dollhouse precedent was one-off, and prototype/UI.md currently routes UI prototypes through real Nuxt routes, not standalone static directories, so as of this session nothing would actually consume the tool.2026-07-24 →
  463. A lint/review nudge (or a tests/README.md callout) warning against 'nothing matches yet' e2e assertions, given how fast real content here changes underneath an open PR — would have caught this session's friction #2 before it shipped.2026-07-23 →
  464. A future 'rooms'/house-view aggregator built on the merged Commons #catalog + queryAcrossTenants — the honest, bake-time, manifest-derived successor to the dollhouse the fork PR reached for.2026-07-23 →
  465. Add a committed scripts/capture-static.ts helper that serves an arbitrary static dir and screenshots/records it via resolveChromiumPath (handling the NODE_PATH/main() dance), so ad-hoc UI captures stop re-hitting the same friction.2026-07-23 →
  466. A 'recent everywhere' rail on the platform home that reuses the Commons Timeline's cross-Tenant read to surface the newest N entries — the aggregator's first appearance outside its own Tenant.2026-07-22 →
  467. A Tenant-identity manifest block (display name, tagline, accent) surfaced through the catalog (or a #tenants projection), so a future directory/dollhouse view themes each room from a single home instead of a hardcoded map — the last gap for an honest dollhouse (ADR-0025 deferred list).2026-07-22 →
  468. Split the catalog opt-in bit by purpose: `kind` conflates 'searchable/aggregatable' with 'publicly enumerable', so a sitemap has no clean source today — either a #routing-derived enumeration read or a purpose-scoped exposure flag (ADR-0025 deferred list).2026-07-22 →
  469. Later: bake-time house map under /t/blog/eyra/... derived from loadManifests(), no GitHub/HTTP probes.2026-07-22 →
  470. Add a committed visual-regression check that renders each diagram SVG at an inflated font size in headless Chromium and fails if any label's text box exceeds its node shape — catching baked-geometry font-mismatch clips before they ship, the exact class this session hit.2026-07-20 →
  471. Harden the #346 provenance-footer hook to cross-check CLAUDE_CODE_REMOTE_SESSION_ID against the transcript's meta.sessionId and noop on disagreement, closing any unobserved stale-env gap; the owner merged without it after evidence showed resume and subagents preserve the id, so it is optional belt-and-suspenders.2026-07-20 →
  472. Add a triage-drift check (extend `scripts/check-triage-drift.ts` or `audit-skills`) that cross-references merged-PR closing keywords against open-issue state and flags any `Closes #N` whose issue is still open — the exact drift that stranded #325 as open despite PR #352 having shipped it.2026-07-18 →
  473. Have a merged guest-build PR trigger a short blog post from one of the existing blog Tenant Personas narrating the guest's request and what got built — turns each successful guest-demo cycle into content for the meta-blog that already exists to narrate the Platform's own build, closing the loop between the demo and its own documentation.2026-07-17 →
  474. Add a CI workflow that auto-labels each issue guest vs owner by authorAssociation (mirroring the existing trusted-PR label workflow, issue #443), so guest-intake/guest-build filter on a label instead of a per-fetch authorAssociation check on every open issue each loop.2026-07-16 →
  475. A harness-level marker (env var or similar) exposed to a dispatched Agent-tool subagent's own Bash calls, distinguishing "this invocation is a dispatched subagent, not the orchestrator", would close the one honest blind spot left in the isLinkedWorktree guard in scripts/log-session.ts (issue #449 Gap 4) — it only catches a subagent that correctly cd's into its own worktree before authoring a session log, not one that forgets and runs from the shared root.2026-07-16 →
  476. A subagent-side guard that refuses to end a worktree-isolated agent's turn while a backgrounded gate process is still alive (or forces a commit+push checkpoint before backgrounding) — closes the recurring #427 mid-gate-stop work-loss at the mechanism level instead of relying on orchestrator rescue.2026-07-14 →
  477. A lightweight 'confirm value with the owner before dispatch' gate in the implement flow for net-new mechanism/gate additions, distinct from clearly-scoped fix tickets that can go straight to a gated PR.2026-07-14 →
  478. Add a compact issue-list helper (number/title/labels straight from the GitHub API, no bodies) so triage and auto-triage stop hitting the list_issues tool-result overflow every run.2026-07-14 →
  479. Build the sparks feed (now ticket #440) as the mechanism that would have auto-produced this very map — scripts/sparks.ts clustering every session log's `ideas` field, rendered on /t/journal/current, closing the loop from logged spark to tracked backlog item without a human running an Explore sweep.2026-07-14 →
  480. Add a lightweight "resolved as of <issue/PR>" annotation mechanism to manuallyRescuedClosures/orphanedSessions entries (or a cutoff timestamp keyed to the fix's merge date) so a permanently-flagged historical incident stops reading as fresh evidence in every future audit-skills run.2026-07-14 →
  481. groupSessionReferences (and any other %aI comparison in audit-skills) compares ISO stamps as raw strings while git emits mixed local offsets, so an orphan's 'earliest referencing commit' date can be picked wrong. Normalize all %aI comparisons to parsed epochs, or emit %aI as UTC — small, well-scoped correctness fix.2026-07-13 →
  482. The HUMAN-PROMPTED-CLOSURE friction keyword now exists (this PR); the remaining half is an audit-skills grep check that counts it — plus 'manually-rescued closure' (close-session landing long after the last work commit, e.g. the orphan's ~20h gap) — turning the manual-nudge regression into a tracked signal like orphanedSessions.2026-07-13 →
  483. Extend scripts/audit-skills.ts's regressionChecks to detect when a flagged edit is a small, identical, mechanical diff shared across multiple Skills' SKILL.md (e.g. by diff line count or by grouping edits with the same commit sha) and surface it as one collapsed low-priority entry instead of N separate full regression checks — this run had 4 of 7 regressionChecks resolve to the exact same 1-line `pnpm gate` -> `pnpm gate:scoped` fix.2026-07-13 →
  484. Filter built-in Claude Code CLI slash commands (/context, /model, and likely others) out of audit-skills.ts's skillsUsed extraction — they surface in the scorecard's skills array as onDisk:false, inventoried:false pseudo-Skills with real usedIn counts (this run: context x3, model x1), which reads as a missing-Skill signal but isn't one; they're not repo Skills at all.2026-07-13 →
  485. A gate-enforced provenance check: a tiny CI step that fails any PR whose commits lack the ADR-0017 two-line footer, closing the cloud -m injection gap mechanically instead of by convention — the session-log commit path just gained the footer, so the check could now be universal.2026-07-12 →
  486. A per-wing "full ledger" affordance on the field log — a client-side show-all toggle revealing the entries hidden by the limit=8 truncation, kept presentation-only so it needs no new route and leaves the ADR-0006 resolver (observations are deliberately not route-addressable) untouched.2026-07-12 →
  487. Add a content referential-integrity check for MDC cross-references — extend validate:content (or a sibling script) to verify every ::phase-note/::season-note `of` names a declared item, every ::sighting `date` matches a real observation in that biome's log, and every :season `of` is a real season slug. Today these resolve only at render time (dev-warnings) and the gate's e2e can't hydrate every specimen, so a broken woven reference can ship silently. Concrete enough to file as an issue against the atlas Tenant / the gate.2026-07-12 →
  488. Extract the inline accordion logic in index.vue (open/close + scrollToOpen + hash mirroring) into a reusable useAccordionDeepLink composable, so a third inline-expandable feed can't re-implement (and re-break) the scroll contract.2026-07-12 →
  489. Add `scripts/blog-rotation.ts` that prints the current eligible-Persona set (last poster, starved Personas) so blog-post and a human don't re-derive the publishedAt sort by hand each run.2026-07-12 →
  490. Add a small "copy link" affordance on each session/digest head that writes the item's deep-link URL to the clipboard, so a reader can share one specific log/digest without hand-crafting the hash — the anchors this PR adds already make the URLs stable.2026-07-12 →
  491. Add an Atlas content-structure check (extend validate:content or a sibling script) that parses each specimen's MDC body and asserts invariants: exactly one dial-note per frontmatter phenology phase with a valid "of=" name, one ::almanac, and every ::sighting date resolving to a real in-biome observation. It catches the whole "MDC degraded to prose / dangling reference" class the error-only e2e hydration misses, in ~1-2s, and would have caught this session's ::almanac regression before CI.2026-07-12 →
  492. Add a preflight to scripts/gate.ts / gate:scoped that detects package.json or pnpm-lock.yaml changed more recently than node_modules/.pnpm's mtime and runs pnpm install automatically first — a rebase across a dependency-adding merge currently masquerades as a real typecheck failure (as it did this session with the mermaid package) until a human/agent thinks to suspect the environment instead of the code.2026-07-12 →
  493. Add a content-derived e2e sweep that asserts every page containing a ```mermaid fenced block renders a .mermaid-diagram svg with no console errors, so future diagrams are covered automatically without a hand-written per-page assertion — mirroring how the entry-route sweep is derived from manifests.2026-07-12 →
  494. If gate:scoped proves useful locally, consider a follow-up that lets CI reuse the same scripts/gate.ts classifier via a job output + if-guards on the heavy steps (option 2 on #350) — human-applied, since agents cannot push gate.yml.2026-07-12 →
  495. Single-home the "land a low-risk gated PR" recipe (enable auto-merge on green, red-gate-never-merges, out-of-scope escalates) into one docs/agents/pr-workflow.md, referenced from digest/audit-docs/audit-skills — this session had to edit three files for one fact change, and the next mechanism change would too until the recipe stops being restated per Skill.2026-07-12 →
  496. Add an Inventory-schema convention (documented alongside CONTEXT.md's Importance definitions) that role prose should cite session ids/dates instead of relative phrasing like "this window" or "this run" — concrete enough that a future audit-skills or domain-modeling session could land it as a one-line addition to the Skill Inventory's schema guideline.2026-07-12 →
  497. Single-home a "skip parentless commits" guard in a shared git helper and use it from every git-log-based script (audit-skills, session-trace, recent-prs). The repo runs in shallow clones, so the boundary-commit false-positive #292 hit can silently bite any of them; fixing it once prevents a class of bugs rather than just the one instance.2026-07-12 →
  498. Add a cheap CI/lint check that fails when a newly-introduced line in a living doc uses a retired glossary term (sync/consolidate/codify/Spawn/'Journal entry'), so retirement is enforced at PR time instead of relying on the nightly audit-docs sweep to catch re-introductions.2026-07-12 →
  499. Add a CI job that auto-labels each PR by authorAssociation (owner vs guest) so ADR-0004's human-only-merge-for-guest rule becomes mechanically visible rather than convention-only — the concrete first step toward resolving the #213 governance gap before going public.2026-07-11 →
  500. Add a repo convention + helper for workflow-file handoffs: agents can't push .github/workflows (no workflow scope), so a `docs/proposals/` drop-zone plus a one-line CLAUDE.md rule would replace ad-hoc PR-comment diffs like PR #323's.2026-07-11 →
  501. Build a committed sparks-index script (e.g. scripts/sparks.ts) that parses every session log's ideas/learnings, clusters them by tag/theme, and emits per-cluster counts + a cross-session feed rendered on the journal dashboard — turning "what are agents focused on / what recurs" from a hand-rolled one-off scrape into a standing query, and giving the oft-proposed ideas-to-GitHub-issue auto-promotion its raw input. Concrete enough to file as a journal Tenant issue.2026-07-11 →
  502. Add an explicit de-dup micro-step to audit-docs between "pool findings" (step 3) and "fact-check" (step 4): before the fact-checker agent is dispatched, have the orchestrating session (or a small dedicated agent) scan the pooled findings for overlapping file:line ranges or near-identical quoted text across different lens-agents, and merge them into one finding naming all contributing lenses and locations. This run needed a manual merge of a Duplication finding and a Verbose finding that were really one defect; an explicit step would make that systematic rather than dependent on the orchestrator noticing.2026-07-11 →
  503. Decide and document, in the audit-docs Skill itself, whether multiple human-only-surface escalations from one sweep should ride one shared human-reviewed PR (one gate run, one PR, one subscription covering all of them) or stay one-PR-per-escalation as today. This run only surfaced one such finding so the question was moot, but a sweep that finds three ADR-tier violations at once would currently open three separate PRs and babysit three separate subscriptions for what a human reviewer would probably rather see as one batch.2026-07-11 →
  504. The Skill's own step 1 ("Branch off origin/main") could explicitly tell the agent to check its own session/task setup instructions for a caller-pinned branch name before defaulting to the journal/audit-docs-<date> convention — right now that override is only mentioned as a parenthetical, and the actual pin (when present) lives in a totally different, harness-injected part of the context that's easy to have scrolled past by the time step 1 executes. A first-run-of-an-updated-workflow retro is exactly the moment this kind of instruction-following gap is cheap to catch and fix before it repeats on every future run.2026-07-11 →
  505. Give the blog-post Skill's step 5 citation checklist a short standing glossary of terms this repo's posts almost always need to gloss for outsiders — PR, Skill (pack vs repo-owned), ADR, Tenant/Space, gate, session friction — so a drafting pass bakes in a one-clause aside on first use instead of relying on the blind reviewer to catch every instance every time. Concrete: a 5-8 line 'first-use glosses' table in personas/README.md or the Skill itself, cross-referenced from step 5.2026-07-11 →
  506. Build a small reusable script (e.g. scripts/pr-timeline.ts) that takes a date range and prints a clean, low-token chronological table of PRs merged in that window — number, title, merged_at, merged_by, head SHA, commit count — sourced once via the GitHub API and cached. This run (and, per the karen post itself, at least the audit-docs/gate sessions it describes) repeatedly hand-rolled the same 'who merged what, in what order, this morning' archaeology via ad hoc list_pull_requests + pull_request_read calls; a shared tool would fix both the adjacency-confusion friction and the oversized-payload friction in one place, for any Skill that needs it (blog-post, code-review, audit-docs).2026-07-11 →
  507. Consider a lightweight, explicitly-scoped topic backlog for blog-post: when Section A's blind review picks a winner, write ONE line per discarded candidate (topic + persona + one-sentence hook, not the draft itself) to a small non-rendered scratch/tracking file the next /blog-post run's A1 can skim, so a genuinely good topic that only lost this round's specific three-way competition isn't fully lost, and so two different runs don't independently rediscover and re-draft the same commit. Needs care to stay consistent with 'nothing lands until chosen' — the backlog entry is a topic pointer, never a draft.2026-07-11 →
  508. For the 'full rigor on all three candidates' cost this run surfaced (3x the tool calls of a single-draft post): consider a cheap pre-screen inside A2/A3 — a fast, low-rigor one-paragraph pitch per topic, ranked by a quick heuristic (does it have a clean irony/hook, is it outsider-legible, is there a verifiable receipt) — before committing to full step-5-grade drafting on all three. This is a real trade-off against the Skill's current 'no lower bar for a draft that might not ship' principle, so it shouldn't be adopted silently; flagging it here as something worth a deliberate decision, not a fait accompli.2026-07-11 →
  509. Add an environment setup-script step that pre-sets projects["/home/user/terrarium"].hasTrustDialogAccepted=true in ~/.claude.json before claude launches, so committed permissions.allow rules actually apply in cloud sessions (a SessionStart hook is too late — trust is evaluated at startup).2026-07-10 →
  510. Adopt 'fused sprint' as the standing shape for Terrarium feature maps: every content-showcase sprint = a few load-bearing MDC components welded to one interactive extension over a shared data axis, so the authoring surface and the payoff can't drift apart. Sprint 2's phenology wheel is the template; the Two-Timescale Dial and the Naturalist's Key are queued fusions.2026-07-10 →
  511. Make wayfinder maps directly launchable: a map that carries execution should ship a pinned, self-contained orchestrator brief + copy-paste prompt (as this one now does), so a fresh session can build the whole sprint off the tracker with no session-to-session context handoff.2026-07-10 →
  512. Give each Tenant a tiny committed skills-index (or Skill-Inventory cross-ref) naming the manually-invoked, Tenant-scoped skills a session must fold in (e.g. atlas-specimen for atlas), so charting/authoring sessions can't silently miss a disable-model-invocation skill.2026-07-10 →
  513. Split the GitHub docs by concern, not by substrate: issue-tracking (issue-tracker.md), outbound-PR lifecycle (a new pr-workflow.md), and a small shared MCP-substrate note — then collapse the self-merge landing recipe currently restated across frictions-to-fixes/audit-docs/audit-skills/digest into that single home.2026-07-10 →
  514. A short 'exemption ledger' table in ADR-0003 (Skill, scope, date, PR) would make the growing self-merge exemption list legible at a glance instead of requiring a reader to parse N free-form amendment paragraphs - worth proposing once a 4th exemption is requested.2026-07-09 →
  515. Split audit-skills' "never edit .agents/skills/" rule into two tiers: semantic changes (description/role wording — stays issue-only, human judgment required) versus mechanical fixes (encoding/syntax validity, broken code fences, stale internal links — propose as an attached one-line patch a human can approve inline) so a crash-on-parse bug like #257 doesn't cost a full separate fix-it session for a one-character change the human ends up rubber-stamping anyway.2026-07-09 →
  516. Run audit-docs on a nightly Routine like digest so doc drift is caught continuously, not only when a human asks — pair it with a cheap CI grep that flags a removed-mechanism noun still referenced in a live doc.2026-07-09 →
  517. A CI-runnable variant of the repro harness (patched build only, expecting GREEN) could guard the interim patch across @nuxt/content upgrades — the re-verify checklist item in issue #236 done mechanically.2026-07-09 →
  518. Build the "sparks" dashboard/auto-promotion tooling this scan's own candidates proposed (Journal cross-session ideas feed; automated ideas-to-GitHub-issue promotion) as a follow-up session, now that the field's wording is set up to produce better raw material for it2026-07-08 →
  519. plate-gallery.ts could self-manage its server via preview.ts start/stop instead of requiring an externally-started one.2026-07-08 →
  520. If orphaned explainer pages become a pattern, revisit the deferred persistent site nav (grill Option B).2026-07-08 →
  521. The onramp frontmatter opt-in could generalize to other Tenants' dashboards as a reusable "surface a page as a card" convention.2026-07-08 →
  522. File the @nuxt/content promise-poisoning bug upstream — the finally-evict is a small, general fix that belongs in the library.2026-07-08 →
  523. A content-dump prefetch-on-hover (or warming) could still cut the benign first-nav latency flash, as a separate enhancement from this correctness fix.2026-07-08 →
  524. If real telemetry (#236) shows the trigger is a post-deploy checksum-mismatch 404, a narrower app-level fix (cache-bust/retry-without-?v on 404) may beat patching the dependency.2026-07-08 →
  525. The session log records entrypoint remote_trigger but not WHICH Routine fired it; the trigger name/prompt lives only in the trigger system and could be worth surfacing in the Journal.2026-07-08 →
  526. kind could eventually be cross-checked against derived signals (entrypoint remote_trigger implies autonomous; a merge_pull_request tool call on the session's own PR implies delegated) to flag misclassified logs.2026-07-08 →
  527. The canopy landing intro enumerates its four founding inhabitants; a once-per-wing intro refresh when the population grows would keep it honest without violating the leave-intros-be rule.2026-07-07 →
  528. stop-hook-git-check.sh could filter out commits that are ancestors of origin/<base> so it stops re-flagging inherited public history on every Stop.2026-07-07 →
  529. A lint/canary that reads .nuxt/tsconfig.app.json could assert Nuxt's native layer globs stay present, guarding the 'coverage for free forever' claim2026-07-07 →
  530. The survey subagent could auto-run merged-since per candidate and fold the result into its report, closing the loop the main session had to do by hand this run.2026-07-07 →
  531. A CI check that auto-labels each PR by authorAssociation would make ADR-0018's guest-to-human-only-merge rule mechanically visible rather than convention-only.2026-07-07 →
  532. Investigate why some dispatched worktree-isolated subagents start from a stale/unrelated HEAD instead of origin/main by default, to close the gap #171's own investigation left open.2026-07-07 →
  533. A lint/CI check that greps for `SessionEnd` outside session-end.ts/ADR-0009 and flags it for a human to confirm it's still accurate, to catch this class of drift automatically.2026-07-07 →
  534. A journal-dashboard "sparks" feed aggregating learnings and ideas across all sessions — right now they are buried in per-card expanded detail with no cross-session view.2026-07-07 →
  535. A consolidate/codify pass could promote recurring session ideas into GitHub issues automatically, closing the loop from spark to backlog item.2026-07-07 →

Learnings 680

  • A session log's Frictions can blame subagents for what the parent itself fabricated; check claimed hand-backs against user/handback events, not assistant text.2026-10-24 →
  • Background-task 'completed' notifications in this harness can arrive before the work ends; trust process state and files, not the notice.2026-10-24 →
  • Nuxt Content's server query route re-checks SQL and throws for any table but the named collection's (security.js assertSafeQuery).2026-10-24 →
  • For a cached (not prerendered) route, Nuxt renders _payload.json on request; only prerendering writes it as a file.2026-10-24 →
  • Scheduled Routine sessions show no effort_level in get_session, while an app-started session records one. Compare model and effort before crediting a cost change to a Skill edit.2026-10-24 →
  • In audit-skills runs, the expensive part is the main session's verify-and-edit step after the checks return, not the parallel checks themselves.2026-10-24 →
  • save-handback.ts overwrites its output file, so one pooled file needs a concat step.2026-10-24 →
  • Claude Code loads path-scoped rules only for Read/Edit tools or one simple shell read; bash-rules-hint fills the rest, so its path parser decides rule coverage for Bash-only sessions.2026-10-23 →
  • Glass Box's page-checks enforce that capitalised guide link text equals the target's title, so a retitle must sweep every page, drafts included.2026-10-23 →
  • `value in Object.fromEntries(...)` is true for prototype keys like toString; use Object.hasOwn for a query whitelist2026-10-23 →
  • The Stop hook nags to push while the pre-push review and gate are still pending; ADR-0004 says ignore it.2026-10-23 →
  • A re-cluster changes ledger-derived labels without new evidence: an entry can turn into a regression, or cross a note's revisit threshold, purely from moved occurrences or reassigned fix PRs.2026-10-23 →
  • skillsUsed in a session log folds in subagent and workflow Skill calls, and docsRead does not reliably list a Skill's SKILL.md, so a log cannot show whether the main session itself ran a Skill.2026-10-23 →
  • inspect-session pages cover roughly one minute of a busy session each, so reaching the start of a 40-minute session takes 30+ pages.2026-10-23 →
  • A flagged page whose Excerpt shows a rule's frontmatter hash fails the layer test after any restamp; run the test right after advancing.2026-10-23 →
  • Removing the sentence that sanctioned a behavior (blog-post's '...list your own later changes separately') doesn't remove the behavior itself when nothing newly forbids it or checks for it - the model reproduces the old PR-body shape by habit, not by permission.2026-10-23 →
  • gather writes big output to a file; its sessions count is cut by endedAt, so a log filename-dated the previous day can be counted.2026-10-23 →
  • A Friction's solution and a session-log idea differ in altitude: the solution is the first fix for that one pain, an idea is a higher-level proposal the session only inspired (from the Trusted user)2026-10-22 →
  • Glass Box term yml files cite root GLOSSARY.md as source, so root headings are load-bearing even when their text shrinks2026-10-22 →
  • Workflow agents' turns do not appear in list_events for the parent session; only the parent's lines do.2026-10-22 →
  • Subagent transcripts (CLI 2.1.306) write each record before message_delta, so output_tokens is a stream-start count while input and cache counts are final; the parent transcript is final.2026-10-22 →
  • A background agent's task-notification subagent_tokens is its last response's context plus that response's output, not a run total.2026-10-22 →
  • Every Routine Skill that files issues already links issue-tracker.md's Filing an issue at that step, so filing guidance reaches Routine agents without a separate rule.2026-10-21 →
  • yaml's parseDocument(text) + .toString({ lineWidth: 0 }) is safe for a file this repo's own tooling already treats as fully machine-owned (prune-routine-runs.ts does exactly this every run), but not for a surgical append to a hand-wrapped prose file: it re-wraps every existing block scalar, turning a one-entry addition into a whole-file reformat.2026-10-20 →
  • In list_events, every Agent dispatch result (foreground too) is now only a receipt; the real reply is a later user event with origin.handback true and origin.from set to the agent id, and the foreground result also carries tool_use_result.handbackReport.text2026-10-19 →
  • A typed human prompt carries client_platform and no origin; task notifications carry origin.kind task-notification, and hand-backs carry isSynthetic plus origin.kind peer2026-10-19 →
  • The tool-results spill threshold is not about 90k characters: a 66k-character list_events page spilled too, so it is probably counted in tokens.2026-10-19 →
  • A background Agent dispatch's tool_result is only a launch receipt; the real reply arrives later as a synthetic user hand-back message, matched by agentId.2026-10-19 →
  • Haiku batches parallel MCP calls within one turn: 23 list_events pages took 26 s, against about 6.5 s per page sequentially.2026-10-19 →
  • The user answers grilling rounds tersely (numbered yes); tight recommendations with one-line rationale fit their style.2026-10-19 →
  • list_events kinds filter matching nothing (keep_alive) gives a ~150-char cursor-only walk per 100 events, the cheap way to reach a session's oldest page2026-10-19 →
  • MCP results of ~90k chars or more spill to tool-results/*.txt that a script can parse; smaller pages land inline in context2026-10-19 →
  • An unquoted YAML list item ending in a colon (`- Reviewed:`) parses as a one-key mapping, not a string; a strict parse still succeeds, so the gate's YAML check misses it.2026-10-19 →
  • A clear-backlog-explore triage agent invokes adr-check but may truncate binding.ts with tail and pick ADRs from its own knowledge in the same command, so step 1's read-every-summary goal is not enforced.2026-10-19 →
  • list_events shows the main session's and Agent-tool subagents' tool calls (agent_id, parent_tool_use_id) but not a workflow agent's; only sampled task_progress snapshots of those remain once the container is gone.2026-10-19 →
  • A page component can provide data with provide/inject so MDC blocks, which take only a Routine name as a prop, can read one shared collection load and one shared metric state.2026-10-19 →
  • A subagent's hand-back in this harness is a final assistant record holding only a SubagentHandback tool_use with input.message; an earlier record carries the same text2026-10-19 →
  • A Journal on-ramp page's card and tour step come only from its onramp frontmatter, so deleting the page removes the teaser; tour counts live in e2e tests.2026-10-18 →
  • Routine run records are capped at 30 per Routine (RUNS_KEPT), so the oldest and often most expensive rows are dropped and trends cover only the survivors.2026-10-18 →
  • Routine cost tracks cache-read tokens, not wall-clock time; a 6.6 hour audit-docs run cost only $12.2026-10-18 →
  • A platform-wide cost step on one date across all Routines points to a model or environment change; check the sessions' models field before attributing it to a Skill edit.2026-10-18 →
  • A page component can provide data with provide/inject so MDC blocks, which take only a Routine name as a prop, can read one shared collection load and one shared metric state.2026-10-18 →
  • get_session on a Routine run's session id returns usage (input, output, cache read, cache write, cost_usd) and origin scheduled_trigger; both cse_ and session_ ids resolve. input_tokens is only the uncached tail, so cache read and write carry the volume.2026-10-18 →
  • A subagent hand-back arrives as a message, so the final reply is not stored where save-handback looks.2026-10-18 →
  • A subagent's image Reads failing with request limit can look like a loop (restarted file list) from the transcript2026-10-17 →
  • A Friction Ledger regression issue's cited sessions can be pre-fix, guard-denied or off-Skill; two of three issues here rested on only one real occurrence.2026-10-17 →
  • Glass Box pages pin file paths to a revision, so page-checks fails if a pinned page is repointed to a path that does not exist at that revision; such pages keep old paths until their revision is bumped.2026-10-17 →
  • The gate's isSkillFile skip of build and e2e is only safe while no e2e spec imports code under .agents/skills/; moving a script into a Skill can silently break that.2026-10-17 →
  • Nuxt Content 3 stores a zod .datetime() field as a zone-less DATETIME string ('2026-06-01 12:00:00'); Date.parse reads that as local time2026-10-16 →
  • Setting process.env.TZ at runtime in Node changes Date's local-zone interpretation in the same process, so a unit test can force a non-UTC zone2026-10-16 →
  • A PreToolUse deny blocks the whole Bash call, so commands chained before a trailing & never run; agents rarely realise it from the deny text alone.2026-10-16 →
  • Full ADR reads pay off by task (merge decisions, triage, Skill audit, trial verdicts, editing rules or ADRs, design), almost never by which file a session touched.2026-10-16 →
  • Path-scoping an always-loaded rule only saves context when the path set excludes most sessions; for 0003, 0004, 0009 and 0017 any covering set still loads in over 90% of sessions.2026-10-16 →
  • A per-paragraph word bound in page-checks turns 'short' from a wish into a check agents iterate against.2026-10-16 →
  • Three independent raters disagree most on items whose premise is stale; a disagreement is the cheapest signal of which items to verify in code before filing.2026-10-16 →
  • The cloud sandbox proxy denies terrarium.feffef.de; review the site through a local pnpm build and scripts/preview.ts start instead.2026-10-15 →
  • Terrarium prerenders nothing: Nuxt Content makes SQLite tables and SQL dumps at build, and HTML and _payload.json are rendered per request behind a 60 s route cache.2026-10-15 →
  • gate:scoped reuses a built .output when fresh, so a green gate after a base merge may not have rebuilt the merged code.2026-10-15 →
  • Two runs of the same reader brief disagreed on about five of 62 page verdicts; taking the minimum of both runs made the cut robust to that noise.2026-10-15 →
  • Nuxt Content finds content with tinyglobby, which follows symlinks by default, so one Space can reuse another's data folder through a symlink.2026-10-15 →
  • In a linked worktree, `git fetch origin <branch>` can leave refs/remotes/origin/<branch> stale; the explicit refspec `<branch>:refs/remotes/origin/<branch>` fixes it2026-10-15 →
  • The harness switched my primary working directory into the impl agent's worktree after it finished; scripts/log-session.ts needs the main checkout.2026-10-15 →
  • Nuxt Content sorts navigation and surround by stem as plain text, so numeric filename prefixes need zero-padding once a folder reaches ten files2026-10-14 →
  • A Claude Design standalone export is a bundled canvas; render it with playwright-core and /opt/pw-browsers/chromium and tile the full-page screenshot to review it2026-10-14 →
  • MDC renders any tag in its html-tags-list (for example `source`) as a native element and never resolves a component of that name, so an MDC component must not share a name with an HTML tag2026-10-14 →
  • Line ranges pinned to one commit can be moved to a later commit with only git diff -U0 hunk offsets; a range with an edited line inside it is detectable and should be flagged, not guessed.2026-10-14 →
  • Nuxt Content page collections already provide title and description, so a new page type can launch with no custom frontmatter at all2026-10-14 →
  • Nuxt Content 3 runs Shiki highlighting unless content.build.markdown.highlight is false, despite docs saying it defaults off; Terrarium already ships highlighted code blocks.2026-10-14 →
  • In cloud list_events, harness nested_memory rule loads are invisible; only hook_response stdout shows the Bash rules hint, so harness-vs-hint duplicate checks need local transcripts2026-10-14 →
  • A Bash command that exits non-zero fires PostToolUseFailure, not PostToolUse, so the Bash rules hint skips compound reads whose last step fails2026-10-14 →
  • Claude Code loads path-scoped rules for files inside a git worktree under .claude/worktrees using the main checkout's .claude/rules (the labels show main paths), while a plain nested dir with the same suffix loads none2026-10-14 →
  • GitHub's fork-PR approval option is currently labelled 'Require approval for all external contributors'; two repo docs had older or invented labels2026-10-13 →
  • Dependabot PRs carry author_association CONTRIBUTOR, so merge-pr.ts refuses them as Public before the Human-only path check2026-10-13 →
  • Most cross-ADR contradictions were leftovers from before the self-merge flip on 2026-10-10, not drift since the rewrite.2026-10-13 →
  • audit-docs' drift lens only looks at the last 48h of main, so old drift is found only by its contradiction lens.2026-10-13 →
  • Most ADR limits already live in Skills or code; the ones only in the ADR are the ones agents open it for, and repeated numbers in ADRs drift (ADR-0027's grace period).2026-10-13 →
  • A summary rule agent will narrow paths when its report recommends it, which can silently stop a rule loading where it is needed (ADR-0029 lost docs/agents/**).2026-10-13 →
  • Session-log docsRead already folds in subagent reads (since August), so a session with no ADR in docsRead means its subagents read none either2026-10-13 →
  • Blind caller checklists (built only from references, never the ADR) catch limits that rewrites silently drop2026-10-13 →
  • Always-loaded summary rules leak into every subagent, so blindness to those ADRs is partial2026-10-13 →
  • Saved workflows in .claude/workflows/ appear as commands as soon as the file lands, without a reload.2026-10-13 →
  • CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS (1-256, v2.1.269+) sets a workflow's concurrency; the default is CPU-bound, 2 on a 4-CPU container.2026-10-13 →
  • A subagent's worktree under .claude/worktrees can briefly become the session's primary working directory; the Stop hook then flags that agent's in-progress changes as uncommitted.2026-10-12 →
  • A no-merge dry run in a child session surfaced 18 Skill gaps that the two-axis review missed; reviews check the text, a run checks the behaviour.2026-10-12 →
  • Tinkerfund e2e tests use vitest expect with Playwright pages, so Playwright web-first matchers like toHaveCount are unavailable; use expect.poll.2026-10-12 →
  • Naming a banned word in an instruction ('don't write loaded') still prompted it in 4 of 16 dry-run verdicts; asking for the positive target alone works better.2026-10-12 →
  • With noUncheckedIndexedAccess, a Record<string, number> lookup is number | undefined even inside a truthy v-if, so a `?? 0` that looks redundant is required by vue-tsc.2026-10-12 →
  • @nuxt/test-utils setup({ build: false, nuxtConfig: { nitro: { output: { dir } } } }) serves an existing .output; its own build used compatibilityDate 2024-04-03 and NODE_ENV=test, so the e2e had been testing a different build than production.2026-10-12 →
  • Parallel Nitro servers sharing one Nuxt Content SQLite file race the lazy per-collection import (database is locked, pages answer 500); NUXT_CONTENT_DATABASE_FILENAME per server fixes it, and the filled DB is .data/content/contents.sqlite, not under .output.2026-10-12 →
  • A vitest project's globalSetup runs only when that project has specs in the run (plus the root project), so an e2e-only build hook must sit on the e2e project.2026-10-12 →
  • CI's playwright-core install had been dead weight: Linux Chromium now lands in chromium-<rev>/chrome-linux64/, chromium-path.ts scanned chrome-linux/, and the suite silently ran the runner's system Chrome.2026-10-12 →
  • vitest 5 drops console.log output from a passing run; a line that must always show goes through process.stdout.write.2026-10-12 →
  • Splitting e2e spec files past the worker count costs more than it saves: each file adds ~3 s of server, DB copy and Chromium startup, and 3 workers on 4 vCPUs are bound by total work (CI: 65.6 s with 14 files vs 56 s with 9).2026-10-12 →
  • pnpm exec tsx costs ~1.7 s per spawn here versus ~0.45 s for node --import tsx; guard specs that spawn per case pay that 45 times per file.2026-10-12 →
  • Nuxt experimental.buildCache hashes only app/, layer config and the lockfile: it served stale content after a content-only edit and missed shared/ changes.2026-10-12 →
  • On GitHub-hosted runners the gate's remaining variance (117-173 s for the same steps) is runner speed: cache-free steps like vitest and the vite builds swing by 40 percent run to run, more than any cache saves.2026-10-12 →
  • actions/cache entries saved by a run are invisible to a run that started before the save; two main pushes a minute apart both miss a fresh cache.2026-10-12 →
  • merge-pr.ts polls the gate itself, so a foreground call with a long timeout replaces separate check-run polling.2026-10-12 →
  • Session logs from Oct 11 show the agents call start-of-session ADR rules unrelated far more often than path-scoped ones (23 of 45 verdicts vs 13 of 28), so a verdict count could drive which rules stay global.2026-10-11 →
  • pnpm exec tsx costs about 1.35s per hook call versus about 0.5s for node_modules/.bin/tsx, so hooks should call tsx directly.2026-10-11 →
  • A Bash PostToolUse hook's additionalContext does inject rules live: the guards rule appeared after a command that touched a hint spec.2026-10-11 →
  • Claude Code loads a path rule on a lone single-file Bash read (cat, head, sed -n, grep, relative or absolute path) but not on piped, chained or multi-file commands.2026-10-11 →
  • Hook output (SessionStart stdout, additionalContext) is capped at 10,000 characters; anything longer becomes a file path plus a 2,000-character preview.2026-10-10 →
  • Path-scoped `.claude/rules/` load after the triggering tool result, so for a new file the rule arrives only after the Write.2026-10-10 →
  • `@` imports in a path-scoped rule are not expanded when it loads, but the imported file loads at session start regardless of paths.2026-10-10 →
  • This session's rulesLoaded lists zz-rule-probe.md and zz-import-probe.md: temporary rule files from the loading tests, not real rules.2026-10-10 →
  • A config file in a PR takes effect when the PR merges to the default branch, not at its commit's author time; Dependabot's schedule started at the PR 1633 merge.2026-10-10 →
  • Session-log occurrence counts repeatedly differed from the counts quoted in issues (17 vs 7, 63 vs 25, 23 vs 13); recount before weighing any fix2026-10-10 →
  • Two-axis review found substantive defects in every multi-file PR, even after green gates, and PR descriptions went stale after nearly every fix round2026-10-10 →
  • The ADR-0017 provenance header's bracketed label is genuinely free text (only the session URL is checked by github-provenance-guard.ts) — the repo's own open issue #1684 documents real tension between ADR-0017's "name the model" wording and the harness's own no-model-name-in-repo rule, and the guard's deny message already resolves it in the harness's favor ("write `Claude` if you must not name your model"). Used `[Claude]` with no model name in every GitHub body this run.2026-10-10 →
  • A scoped class passed to SiteFooter lands on its single root, so a parent grid can place it; an auto-placed footer in a two-column grid fell into the narrow key column.2026-10-09 →
  • On a local machine, parallel sessions in one working copy share HEAD, so any git-range notion of 'this session's commits' sees siblings' commits; only the transcript knows which commits a session made.2026-10-09 →
  • git commit -q suppresses the [branch sha] subject line, the only per-commit trace a session's transcript otherwise carries; a merge prints none either.2026-10-09 →
  • Matching a command by substring catches text it merely quotes (heredocs, grep patterns, echo); anchoring at command position after ^ ; & | ( avoids that cheaply.2026-10-09 →
  • The Journal splits session logs into current/ (recent) and archived/ (older); a history query over current/ alone misses most of it.2026-10-09 →
  • The seven Routines each fire once a day at a stable UTC time (digest 00:16, audit-skills 00:46, frictions-to-fixes 02:03, audit-docs 04:00, blog-post 11:05, prune-trial 13:14, visitor-loop 16:48), observed 2026-10-01..08; the repo deliberately never states it.2026-10-09 →
  • A session log's free text is rendered on the Journal dashboard, so quoting the e2e smoke test's 404 marker ('No document at') in a friction turns main red.2026-10-09 →
  • Cold readers with no repo access find structure bugs in a spec reliably, but they also flag 'contradictions' the repo resolves (e.g. ready-for-human per ADR-0022). Verify each claim before applying it.2026-10-09 →
  • Subagent write tools can refuse writes to the scratchpad; a reviewer then returns findings as text only.2026-10-09 →
  • Archify architecture showcase tolerates automatic-route crossings (drawn with bridges) but fails explicit-via crossings; workflow showcase fails all crossings.2026-10-08 →
  • Terrarium's improvement-loop core graph (rules, Session, log, Routines, PR, main) is K3,3, so any flat drawing needs at least one crossing2026-10-08 →
  • GitHub's activity REST endpoint (repos/{o}/{r}/activity?activity_type=direct_push&ref=refs/heads/main) shows the pushing actor per direct push; it proved in one call that every session-log push is the owner's identity.2026-10-08 →
  • The Terraform GitHub provider's repository_ruleset docs mirror the REST ruleset schema (RepositoryRole ids maintain=2, write=4, admin=5; bypass modes always, pull_request, exempt) and are reachable when docs.github.com is not.2026-10-08 →
  • Archify's desktop-readability check uses a 930px budget unless viewBox width/height >= 1.55; then up to ~1346px applies, so widening a too-tall diagram can fix text that is too small on screen2026-10-08 →
  • A session log's docsRead folds in dispatched subagents' reads, so a path on the list does not mean the main agent read it (scripts/session-trace.ts, foldSubagentTrace).2026-10-08 →
  • Every scheduled prune-trial run this month committed its new trial 1m57s to 3m09s after starting, so without the grace the next run is early by about that much whenever fire-time jitter does not cover it.2026-10-08 →
  • A commit-msg hook appends the Co-Authored-By and Claude-Session trailers, so a plain git commit -F message is enough.2026-10-08 →
  • git log -S lists commits where the occurrence count of a string changed, so for a reworded quote the newest hit is the commit that removed it; always confirm with git show.2026-10-08 →
  • A prune trial is deleted from .agents/prune-trials.yml when judged, so whether a drop citing a trial was correct must be checked in git history of that file at the drop date, not in the current ledger.2026-10-08 →
  • Grepping docs/adr for a file path finds the ADRs that bind it far more reliably than an instruction to read all 28; sessions read a median of 2.2026-10-07 →
  • A prune trial's own territory locators ('the paragraph above X') move when another prune inserts text nearby; inserting next to an open trial's locator muddies its verdict.2026-10-07 →
  • Home's Popular now is uncapped and its e2e assertion is an ordered subsequence, so a new Live Campaign with backers between existing ones needs no Home change.2026-10-07 →
  • In this repo every agent-authored comment carries a claude.ai session URL, so matching that string on the latest comment reliably separates AI from human comments where author_association (always OWNER) cannot.2026-10-07 →
  • The Stop-time uncommitted-changes nag in cloud sessions comes from ~/.claude/stop-hook-git-check.sh, outside the repo2026-10-07 →
  • list_pull_requests'/MCP's `merged` boolean field can read `false` on a PR that is in fact merged; `merged_at`/`state` from a direct `get` call is the trustworthy signal (surfaced by the close-session behaviour-check subagent).2026-10-07 →
  • list_triggers output carries a top-level last_fired_at alongside last_run, though the tool description lists only last_run.2026-10-06 →
  • pnpm audit and the Dependabot open-alert list can diverge: alerts Dependabot already closed or auto-dismissed still show in pnpm audit2026-10-06 →
  • Dependabot writes per-dependency update-type metadata into its commit messages, so a workflow_run job can classify a PR without dependabot/fetch-metadata2026-10-06 →
  • The /loop-only ScheduleWakeup guard correctly fires for a plain scheduled task (not a /loop session) even when multiple long-running background subagents are in flight — the right call is to just end the turn and let task-notifications drive the next turn, never schedule a self-wakeup outside /loop.2026-10-06 →
  • CI's issue_comment webhook for the gate-green check references the refs/pull/N/merge SHA, not the PR branch head SHA — a mismatch there is expected, not a sign something else pushed to the branch (CLAUDE.md's own noted divergence source).2026-10-06 →
  • The tinkerfund wayfinder:map #1357 may now be closeable since its spec #1375 closed, but auto-triage must never touch maps — left for the owner2026-10-05 →
  • A hook-run guard reads the project checkout, so a PR's guard can be live-probed by temporarily checking out just that file, then restoring it2026-10-05 →
  • The repo's commit-msg hook rewrites Claude-Session trailers, so a foreign-trailer fixture can't be crafted with git commit; use a real unmerged foreign branch instead2026-10-05 →
  • A subagent concision report quoting settings.json trips the harness scanner, which environment-caveats.md already documents as benign.2026-10-05 →
  • `mcp__github__issue_write` takes flat top-level params (title/body/labels/...), not a nested `fields` wrapper.2026-10-05 →
  • This repo's commit-trailer guard (ADR-0017) blocks a hand-written Co-Authored-By/Claude-Session trailer even when a system-prompt reminder asks for one — the harness's own template/hook lands it with the correct session id regardless; CLAUDE.md says the repo convention wins.2026-10-05 →
  • A Skill's section heading can be load-bearing outside the Skill: 'A0. Rotation gate' was cited in a script comment, a unit test comment, and a research table, so renumbering steps is a four-file change2026-10-04 →
  • Sonnet read 17 Skills plus support files in about 110 seconds and 155k tokens; its quotes were exact on every spot-check, so a cross-Skill confusion audit is cheap enough to repeat2026-10-04 →
  • gate.yml is 85 lines before PR #1572 and 33 after; 578 of its 666 deleted lines are the four proposal files.2026-10-04 →
  • A survey's significance judgement should come from the primary session log, not the PR body: PR #1562 looked empty but its session log recorded the finding.2026-10-04 →
  • The owner-corrections script matches visitor-loop PRs only by a claude/visitor-loop-* branch name, so any run landing on the harness-pinned branch is invisible to its rework scan.2026-10-04 →
  • A PR's recorded base at open time can postdate the branch's real fork point; `git merge-base --is-ancestor <fix> <first-branch-commit>` is the test of what a run actually saw.2026-10-04 →
  • In this repo own Skills change almost daily: all twelve behaviour-checked Skills had landings during their runs in one 7-day window, so 'Skills rarely change' does not hold here.2026-10-04 →
  • --tf-link in Tinkerfund is the shop's general blue accent (figures, focus rings, Funded chip), not just a link colour.2026-10-04 →
  • Unregistered custom properties holding light-dark() resolve at the use site, so color-scheme: light on one element pins its tokens to the light values.2026-10-04 →
  • The survey's per-record docsRead mixes docs and code files, so doc-only filtering needs a path-prefix step.2026-10-04 →
  • This repo's commit-trailer guard (issue #921) silently overrides even an explicit system-prompt instruction to hand-write Co-Authored-By/Claude-Session trailers — the harness/githook lands them itself, and the guard fails closed regardless of instruction source2026-10-04 →
  • A composite action's internal steps show as one step in gh run view --json jobs; grep the --log output to see which steps ran.2026-10-03 →
  • imports.scan:false in the root config also disables scanning of the root app's own app/composables and app/utils, not just the layers' (useSpace, queryPages break too)2026-10-03 →
  • In cloud sessions GraphQL-backed gh subcommands 403 while gh api and REST-backed ones (gh run list) work; gh auth status falsely reports an invalid token2026-10-03 →
  • zod 4's instanceof checks _zod.traits, so two zod module instances no longer break strip/strict detection2026-10-03 →
  • GitHub MCP appends a session-linked footer only to PR descriptions; comments get a generic one, issue bodies and commits nothing (2026-10-03)2026-10-03 →
  • Vue's .self key modifier is the minimal fix for a link nested inside a role=button row whose keydown.prevent cancels the link's own Enter.2026-10-03 →
  • Nuxt dev caches rendered routes under .nuxt/cache/nitro/routes; content edits don't invalidate it2026-10-03 →
  • The Tinkerfund 'locale' cache bug was about price/number formatting (Intl.NumberFormat), not page language.2026-10-03 →
  • Vue's `.self` modifier on a role=button row's keydown handlers is the one-line way to let nested links keep their Enter; `.prevent` without it cancels the link's activation2026-10-03 →
  • In this sandbox a navigation to a blocked external host surfaces as no navigation at all in Playwright; intercept with page.route to observe it2026-10-03 →
  • A web page cannot learn whether a visitor is logged in to GitHub or claude.ai (same-origin policy, SameSite cookies), so a maintainer-only affordance can only be a per-browser toggle or a real server-side OAuth check2026-10-03 →
  • The committed docsReadViaShell and the --author advisory are derived by different calls; a fix applied to shellReadScanOf alone never changes what lands in the Journal.2026-10-03 →
  • Plain diff output uses `< `/`> ` line prefixes, not unified `+`/`-`; anything matching doc lines in output has to strip both.2026-10-03 →
  • TS 7.0 ships no programmatic API (main export is lib/version.cjs), so typescript-eslint and vue-tsc cannot run on it until 7.12026-10-03 →
  • With zod 4, @nuxt/content's JSON-schema conversion drops tuple min/max items, widening generated collection types2026-10-03 →
  • claude-code-remote list_events can read any of the account's cloud session transcripts, but the tool is absent from the public Claude Code changelog and docs2026-10-03 →
  • For @nuxt/content generated item types, a schema with .default([]) fields matches z.input<> not z.infer<>; the journal and midden type mirrors only became deletable once that was verified with a scratch tsc run2026-10-03 →
  • Nuxt auto-imports export a layer's util/composable TYPES as ambient globals too, so relative import type lines of them are pure noise (42 across tinkerfund and midden)2026-10-03 →
  • Playwright waitForURL globs match the full URL, so they cannot replace an expect.poll on pathname-only or search-only conditions2026-10-03 →
  • This container does have a `gh` binary on PATH (`/usr/local/bin/gh`), contradicting docs/agents/github-integration.md:29's "Remote sessions have no `gh` binary" — independently confirmed while verifying the audit-docs subagent's #1541 finding.2026-10-03 →
  • Playwright's newPage({ colorScheme }) is enough to shoot a page in dark mode when its theme follows prefers-color-scheme or light-dark().2026-10-02 →
  • The GitHub PR-files API reports a rename under filename only; the old path is in previous_filename, the same blind spot as git diff --name-only without --no-renames.2026-10-02 →
  • ADR-0020's 'security theatre' argument only rejects tiering humans; agent limits remain justified against agent error, independent of requester trust2026-10-02 →
  • A parent's scoped CSS class also matches a child component's root element when they share a class name. Gallery wrappers named after the component (.filters) silently restyled TinkerfundBrowseFilters' root <form class="filters">.2026-10-02 →
  • merge-pr.ts needs the verdict comment posted first and then polls CI to green; it took one call per PR2026-10-01 →
  • A translucent, full-page CSS background can band per tile on Chrome with a Mali-G52 under partial raster; band colour = the paper with the translucent layer composited N times2026-09-30 →
  • Headless Chromium (SwiftShader) with the device's exact cc flags still does not reproduce GPU-driver-specific raster bugs2026-09-30 →
  • CSS can hide SVG text at a breakpoint but can't change a viewBox, so cropping a responsive diagram needs a matchMedia-driven viewBox in JS2026-09-29 →
  • An absolutely positioned child of an overflow scroller scrolls with the content; mask-image on the scroller stays fixed to its box2026-09-29 →
  • A digest error can come from misreading good input, not from missing sources: a Skill's focus label in a PR title, e.g. "(homepage)", reads like a location.2026-09-29 →
  • A composite Skill (grill-with-docs) logs its engine (grilling) too, so raw use counts double-credit the engine.2026-09-29 →
  • CLAUDE.md's docs/research pointer is deliberately an unindexed directory read, so audit-docs' orphan rule should apply to docs/agents only2026-09-29 →
  • The Journal's existing onramp-card system (onramp/onrampLabel/onrampBlurb frontmatter, auto-discovered by layers/journal/app/pages/t/journal/[space]/index.vue's onrampCards computed) is a reusable host for a visitor-loop feature that can't touch the homepage hero directly — worth checking before assuming an idea needs a new page or a homepage edit.2026-09-28 →
  • A session log's own friction entry can itself carry an imprecise number: layers/journal/content/current/sessions/2026-09-28-session_01CUfke5VH7TdJpMTdUhPNgK.yml's friction says a wrong Midden claim stood '2.5h after the removal PR,' but directly computing from PR #514's merge timestamp and the catalogue commit's timestamp gives ~4.5h. Recompute every timing claim from primary timestamps, never quote a friction's own number verbatim — even one written by another session.2026-09-28 →
  • git log --oneline adjacency across the whole repo is not chronological: commit 66f117be (authored 2026-09-27T19:06:35Z) surfaces near July-dated commits in --oneline output because of interleaved merges, matching CLAUDE.md's own warning about this exact trap.2026-09-28 →
  • merge-pr.ts's own step-4 verdict-comment requirement worked as documented: it refused (would have refused) to merge without a prior COMMENT-event verdict already posted on the PR, matching pr-workflow.md's step 5.2026-09-28 →
  • CLAUDE.md's prune-first rule was born from PR #1159: the branch-pin guard was deleted seconds before the rule was committed, naming that PR as its first application.2026-09-28 →
  • Journal utils that unit tests import directly can't rely on auto-import, so a Platform util moved to app/utils needs an explicit relative import there.2026-09-28 →
  • Before trusting a visitor's claim that a page doesn't explain itself, render it: one of the three visitors missed a Midden foreword that sits above the fold.2026-09-28 →
  • In this repo the Platform catch-all page only renders for URLs that don't exist; every Tenant with pages below its Space landing overrides it.2026-09-28 →
  • The 10 parallel behaviour-check subagents each independently verifying claims against git/GitHub (rather than trusting the scorecard's prose) surfaced 3 findings the scorecard's own prior observations had only partially scoped (new non-compliant commits/sessions beyond what was already cited) — the "verify one claim from every clean report too" step caught nothing new, but the deep-verification on flagged findings is where the real value was.2026-09-28 →
  • z.string().url() accepts javascript: URLs; use startsWith('https://') for anything bound to href.2026-09-27 →
  • git diff --name-only reports only a rename's new path; classifiers need --no-renames.2026-09-27 →
  • In this repo, 40 newest sessions covered only about 2.5 days by late September, because six scheduled Routines fill the journal; any count-based window over session logs silently shrinks as the schedule grows.2026-09-27 →
  • This repo's local `main` git ref can be significantly behind `origin/main` in a fresh ephemeral session — fetch and diff against `origin/main`, not `main`, for any gated-PR tooling.2026-09-27 →
  • A card/list component's CSS can have narrow-viewport overrides living in a sibling stylesheet file (theme.css) rather than its own scoped `<style>` block — a class rename inside the component must be grepped for repo-wide, not just within the component's own file.2026-09-27 →
  • Nuxt drops a leading folder segment repeated in the file name (campaign/Campaign.vue is TinkerfundCampaign), so file names can be chosen to keep component names stable2026-09-27 →
  • scripts/check-conflicting-issues.ts's file-level heuristic can false-positive: it flagged CLAUDE.md against issue #1420 on the keyword "delete", but #1420 never names CLAUDE.md and the actual PR diff contained no such word — the match was advisory noise, not a real file/issue co-occurrence worth deeper reading.2026-09-27 →
  • Tinkerfund's prod clock deliberately resolves offsets from each request's real time (#1364), so deadlines shifting between page views is by design, not a bug.2026-09-26 →
  • A workflow cannot wait on an external event, so a merge handed back to the orchestrator ends the run; args-driven resume (merged/only lists) restarted it cheaply.2026-09-26 →
  • Tenant layer plugins and nuxt.config flags apply app-wide; keep them inert outside the Tenant's own opt-in.2026-09-26 →
  • A pure CSS background-color fade at a scrollable diagram's edge is too subtle a scroll affordance on its own — two more independent first-time visitors still read the Atlas Relations diagram as "clipped" a full day after PR #1341 added exactly that fade for the same complaint. An explicit, visible text hint reads far more reliably than a color-only cue.2026-09-26 →
  • When two or three blind visitors independently propose different-worded variants of the same underlying fix (here: "surface the Blog's best material higher on the homepage"), picking the smallest/most content-homed variant — reusing an existing curated list via one new optional schema field, rather than authoring new content or a new route — keeps the feature PR proportionate to a single-session chartered run.2026-09-26 →
  • When two or three blind visitors independently propose different-worded variants of the same underlying fix, picking the smallest/most content-homed variant — reusing an existing curated list via one new optional schema field, rather than authoring new content or a new route — keeps the feature PR proportionate to a single-session chartered run.2026-09-26 →
  • A code-review finding can misread a repo-wide rule's scope (e.g. reading CLAUDE.md's "Simplify first" growth-freeze, which targets the Platform's own instructions/governance, as forbidding any net-new Tenant feature). Cross-check a hard-violation claim against the specific ADR/ledger row that charters the work before accepting it, rather than fixing on the reviewer's say-so alone.2026-09-26 →
  • This repo's prune-trial corpus is heavily mined after ~18-23 prior trials: nearly every sizable CLAUDE.md/docs/agents bullet with real incident history has already been compressed and validated holding, so a fresh criterion-1 search now mostly re-surfaces already-tried territory rather than new candidates -- the owner's "rewrite a whole file when nothing clears the bar" fallback (commit 54d3e1b4) exists precisely for this state.2026-09-26 →
  • Inline SVG coloured by CSS custom properties works in both themes, but pattern/clipPath ids must be unique per instance when the same figure renders several times on a page2026-09-26 →
  • The artifact CSP allows Google Fonts, so a standalone prototype can show open-licence faces even when the container can't fetch them.2026-09-26 →
  • @nuxt/content 3.15.0 runs queryCollection in the browser via lazily imported @sqlite.org/sqlite-wasm plus a per-collection SQL dump whenever the query executes client-side, including useAsyncData on client-side navigation.2026-09-26 →
  • sessionStorage is shared across every Tenant and Space (one origin), and Nuxt keeps its chunk-reload guard there, so a per-Tenant Reset must remove only its own keys, never call clear().2026-09-26 →
  • A layers/<tenant>/package.json cannot scope a dependency to one Tenant here: no pnpm workspace, and even with one the module installs app-wide.2026-09-26 →
  • scripts/check-worktrees.ts reports a worktree as "already merged into origin/main" even when it still holds uncommitted changes, if the worktree's own commits (if any) are already a subset of main — this can read as confusing/contradictory at a glance when the worktree is actually still mid-work, not stale cruft.2026-09-26 →
  • Atlas plate styles are global (the Atlas theme loads site-wide); only biome/signature vars need setting via signatureVars and --biome-accent to render a plate outside the Atlas.2026-09-25 →
  • In the current Space, almost no sessions record external-pack Skills in skillsUsed (domain-modeling, graded essential, shows 0 of 49), so grade and recorded use have drifted apart.2026-09-25 →
  • scripts/digest.ts gather reads only current/sessions, so backfilling an already-archived day returns no sessions.2026-09-25 →
  • The skills CLI never touches docs/agents; only running /setup-matt-pocock-skills would, so a pack update cannot clobber those customizations2026-09-25 →
  • Nuxt Content's `toSpecimenView()` defaults a specimen's `common` to `commonName ?? description` and its `blurb` straight to `description` — when a specimen's frontmatter sets `commonName` equal to `description` (true for ~5 of the Atlas's 15 specimens), naively rendering both fields prints the same short phrase twice; worth a manual equality check before showing both.2026-09-25 →
  • A route with no explicit `routeRules`/prerender config in this repo's nuxt.config.ts is server-rendered per request even though its content is build-time-baked (ADR-0001) — confirmed by re-requesting the homepage twice and getting the same day-keyed value both times, then checking no prerender crawl covers it. This is what makes a server-computed "today"/"this week" rotation an honest claim rather than a value frozen at the last build.2026-09-25 →
  • The unquoted-# truncation bug was not only a session-log problem: two published blog Documents had silently truncated fields that no check caught.2026-09-25 →
  • A scheduled task's stored prompt can arrive with the full skill body already inlined (command-message/command-name present) rather than needing a fresh Skill tool call to load it.2026-09-25 →
  • A naive "widen the output-confirmation verb set" fix for a detector bug can silently change behavior for every caller that defaults a missing tool_result's output to '' instead of leaving it undefined — worth checking real callers' actual default-value conventions before widening a gate, not just the reported repro shape.2026-09-25 →
  • An unquoted YAML value containing ' #' silently truncates in content too, not only in session logs2026-09-25 →
  • Equal-specificity CSS inside a media query loses to a later base rule; the Blog theme already warned about it in a comment the agent missed2026-09-25 →
  • The regressionChecks bracketing fix from issue #1237 (domain-matched via skillsUsed, not nearest-chronological) is visibly working: several brackets this run were legitimately short or empty on one side (e.g. frictions-to-fixes's after-bracket, close-session's before-bracket) rather than being padded with unrelated Skills' sessions — confirms audit-skills.yml's 2026-09-13 idea was acted on and is paying off.2026-09-24 →
  • close-session/log-session/dispatch-subagents are used in nearly every autonomous session regardless of that session's actual work (they're mechanical closure/dispatch steps), so a Phase-A friction-severity shift in their regressionChecks bracket is disproportionately likely to be about whatever Skill that session was actually running, not about the edited essential Skill itself — Phase B's full deep-read is what actually separates the two, not the bracket alone. Worth remembering as the essential-Skill counterpart to the already-recorded rotating-Skill bracket-dilution idea (audit-skills.yml's 2026-09-13 observation).2026-09-22 →
  • Two independently-surfaced frictions that look like separate candidates can share both a root cause and a target file/function - worth explicitly checking for that before dispatching separate agents, since combining them into one PR is cheaper to review than two near-identical ones.2026-09-21 →
  • prune-trial-window.ts's landing-commit search is only as unique as a trial's first raw problem: line -- two trials about the same file/section can collide even though the tool's own docs call a miss "the fail-safe direction"; a wrong-commit hit isn't actually covered by that safety claim.2026-09-20 →
  • scripts/gate.ts's own header comment single-homes its rationale pointer at docs/agents/git-conventions.md by name — a prune of that doc's prose needs to check code comments for inbound references, not just other docs/Skills.2026-09-19 →
  • This repo's instruction corpus has already been pruned enough by prior /prune-trial runs that a clean criterion-1 (guard-made-redundant narration) hit is now the exception, not the default case to expect each run — criterion 2/3 fallbacks are the realistic common path going forward.2026-09-18 →
  • ADR-0026's own text ('the composite ships unexercised... every prior Gate change was tested by the Gate itself') was strong enough to quote verbatim as the post's central hook, rather than needing to be paraphrased or reconstructed from surrounding context.2026-09-18 →
  • The digest tier's per-tier merge authority (docs/agents/pr-workflow.md) lets a /digest PR self-merge on a green gate alone with no extra risk review, unlike the reviewer-agent tier which also needs a risk judgement.2026-09-18 →
  • In this repo's ADR convention, "Decision and Consequences are never rewritten" (ADR-0018) applies per-block, not just to an ADR's original top-level sections — a later dated amendment's own "**Decision.**"/ "**Consequences.**"-headed prose is equally off-limits to a prune; only the narrative/investigative prose around those blocks (a "why revisit", "the problem", "the gap" preamble) is prunable.2026-09-16 →
  • Issue #867 (which commissioned docs/research/rulebook-migration-table.md) explicitly asked for the deliverable to live in docs/research/ - a doc that looks proposal-shaped by convention can still be the intentional, requested home rather than drift.2026-09-16 →
  • `bashCommandsOf` extracts only a Bash tool_use's `input.command` — tool OUTPUT is never scanned, so a path appearing only in a command's output (e.g. git merge's "Auto-merging <path>") can never be credited to docsReadViaShell. This single fact falsifies two sessions' self-diagnoses on #1206.2026-09-13 →
  • A `wayfinder:grilling` ticket can still carry `ready-for-agent`; the label pair is not mutually exclusive in practice, so an implement step must read the ticket type, not just the state label.2026-09-13 →
  • The blog-rotation.ts script's eligible/starved/last output is the sole source of truth for which Personas a bare /blog-post run may draw from — CLAUDE.md's own 'don't state anything as settled' bar applies to Persona choice, not just facts in the post body.2026-09-13 →
  • A pnpm `overrides` entry on `vue` also drags `@vue/compiler-sfc` to that version, so pinning the runtime does not by itself create a compiler/runtime skew2026-09-12 →
  • MDCRenderer wraps any MDC component carrying a `setup` in `defineAsyncComponent(() => Promise.resolve(component))` on every render — all five of our MDC components use `<script setup>`, so all five take that path2026-09-12 →
  • vue compiles its dev warnings out of production builds, so hydration-mismatch and resolveComponent warnings are invisible to a production preview probe2026-09-12 →
  • A regression bracket with usage on only one side of the edit (before=[] or after=[] because the skill never fired in that half) can't be judged at all, not just weakly — there's no baseline to compare against, distinct from the "zero usedIn on both sides" skip case the SKILL.md names explicitly (close-session, digest, dispatch-subagents this run).2026-09-12 →
  • prune-trials.yml's judgeability is gated on the file parsing at all — a corrupted ledger silently stops every future /prune-trial run from judging anything, with no error surfaced until someone runs prune-trial-window.ts by hand2026-09-11 →
  • layers/atlas and layers/marquee CONTEXT.md files stay Live/in-scope even though their tenant *content* (fiction / claims-nothing-about-the-Terrarium) is excluded from the sweep — the exclusion is content-specific, not tenant-wide.2026-09-11 →
  • scripts/workflow-edit-guard.ts's formatGuardMessage() already states the "commit not push" mechanic near-verbatim to what environment-caveats.md narrated in prose — confirming the guard's own deny message is the load-bearing teaching surface, not the doc, once a guard is built fail-closed before the commit.2026-09-09 →
  • A quiet frictions-to-fixes cycle (no moderate+ findings, no regressions) is a valid and expected outcome, not a sign the survey under-delivered — three frictions-to-fixes runs landing inside one 20-session recency window means most candidates are pre-resolved by the time a new run starts.2026-09-09 →
  • docs/research/rulebook-migration-table.md's "Prune-trial shortcut: Built rows as prune candidates" section is a fast, targeted way to find criterion-1 candidates (prose whose mechanism is already built) without re-scanning the whole instruction corpus by hand.2026-09-08 →
  • The 20-session frictions-to-fixes survey window regularly straddles 2-3 prior runs of the same Skill at this cadence, so most candidates are already screened; anchoring on the most recent frictions-to-fixes-filed issue's creation time to bound fast-screening (per the Skill's own guidance) worked well and left a thin, high-confidence actionable tail.2026-09-08 →
  • The 'cite a sibling post via the site route, not GitHub' rule (blog-immutable-links.spec.ts) has no carve-out for linking a specific historical revision of a post — even a SHA-pinned blob link into layers/blog/content is rejected. Worth remembering for any future post that needs to reference a since-edited/deleted blog post's earlier wording: cite the PR diff instead, not a blob link into the content file.2026-09-07 →
  • This run's 40-session window was almost entirely repeat scheduled-Skill runs (digest/prune-trial/blog-post/audit-docs/frictions-to-fixes/audit-skills), leaving very little fresh signal for step 3's bright-line grading of the low-frequency interactive/general-engineering Skills (code-review, implement, triage, wayfinder, tdd, etc.) -- their grades are still resting on observations from much earlier runs. Not actionable on its own, but worth a future run noticing if it persists.2026-09-07 →
  • rulebook-migration-table.md's own 'Prune-trial shortcut: Built rows as prune candidates' section is a reusable, low-risk way to pick the next trial's target without needing an open, still-unresolved regression issue.2026-09-06 →
  • Issue #1168 (blog-post's causal-attribution rule failing a third time) is itself a strong, well-grounded blog topic — it lost this run's outside-read only on relative event-weight against the digest near-miss, not on quality; captured in the scratch backlog file for a future run.2026-09-06 →
  • A Journal retention sweep that moves content between Spaces (current → archived) can silently break any script whose "does X exist" check only looks in one of the two locations — worth checking other current/archived dual-path logic for the same class of bug.2026-09-06 →
  • ScheduleWakeup is valid only inside /loop's dynamic pacing; waiting on a dispatched Agent-tool subagent needs no wait/poll tool at all — just end the turn and let the task notification arrive.2026-09-05 →
  • The caller-pinned branch is already HEAD at session start; sessions lost it only because CLAUDE.md and four Skills told them to branch off main.2026-09-05 →
  • GitHub's search API is blocked through the session proxy while repo-scoped endpoints work; rate limits on the MCP search tools were a red herring.2026-09-05 →
  • A Blog post's route is /t/blog/<persona>/<file-stem>; the Persona Space slug is the link prefix, not part of the document path2026-09-04 →
  • The Journal on-ramp is a two-column grid, so a fourth card is what squares it off rather than leaving a ragged row2026-09-04 →
  • Most ready-for-human escalations in this backlog were not genuine forks; reading the repo's own migration table determined the design.2026-09-03 →
  • A "corrected" governance claim (issue #1069/PR #1070) can itself be wrong in a way that's now permanently gated (a hardcoded date in tests/unit/prune-trial-window.spec.ts:83) — verification failures compound silently when each correction trusts the previous one's git investigation instead of re-deriving it from scratch.2026-09-02 →
  • This window (last 20 sessions) was unusually clean for frictions-to-fixes: almost every moderate/major friction logged had already been filed and fixed within the same window by the self-improvement loop itself, leaving only one genuinely never-fixed, worth-fixing candidate. The loop appears to be keeping up with its own backlog rather than accumulating one.2026-09-02 →
  • scripts/prune-trial-window.ts is the only trustworthy source for a trial's judgeable-from time — two of the four open trials had an opened: date matching today's date but were still correctly reported not-yet-judgeable, confirming opened: is not the window start.2026-09-01 →
  • docs/research/*.md files can legitimately carry unbuilt-proposal content when the commissioning GitHub issue's own body specifies that shape as the deliverable — issue-tracker.md's docs/research-vs-issue convention has an exception a fact-checker has to verify against the issue body, not just the convention doc.2026-08-31 →
  • A scheduled prompt carrying <command-message>/<command-name> tags has already loaded that skill's full instructions verbatim into the turn — follow them directly rather than re-invoking via the Skill tool, which is blocked for disable-model-invocation skills anyway.2026-08-30 →
  • A PreToolUse hook added to .claude/settings.json takes effect immediately in the same session - no restart needed2026-08-29 →
  • A guard's unit tests cannot observe live interception, but a Write to a NEW file under the protected path probes it safely - a deny writes nothing, and a miss leaves only an untracked file2026-08-29 →
  • Splitting a bundled PR by reverting is unsafe when a sibling PR carries the same commit - the revert deletes the sibling's change once both merge. Dropping the commit with a force-push is the only correct move2026-08-29 →
  • A JS negated character class matches newlines, so "[^;&|]*" spans lines. Any regex meant to stay within one shell command must exclude \n explicitly2026-08-29 →
  • Pasting an already-fetched primary source into a review subagent's brief (the very fix in #898) measurably paid off - all four agents verified claims against real files instead of reporting anything as unverifiable2026-08-29 →
  • grep/rg context flags (-A/-B/-C/-m) consume their argument, so a naive positional index puts the pattern in slot 2 — the same decoy class returns whenever a context flag is present2026-08-29 →
  • rg -L means --follow; grep -L means --files-without-match. Sharing one flag table across the two silently drops real reads2026-08-29 →
  • A quoted argument that looks like a flag will be read as one unless the tokenizer keeps the quoting — `grep -rn "-l" file` is indistinguishable from a names-only grep after quote-stripping2026-08-29 →
  • docsRead is 34.5% authored self-report across all 528 logs (1216 of 4554 entries); its derived guarantee covers only the marked entries, which makes a new derived-only field the stricter of the two2026-08-29 →
  • A heredoc body is part of the Bash command string in the transcript, so any analysis over commands reads written file content as if it were commands that ran — this repo writes docs and fixtures that way constantly2026-08-29 →
  • grep -e supplies the pattern, so the first positional is then a FILE; a blanket skip-the-first-positional rule silently loses that read2026-08-29 →
  • Splitting a shell command on | shreds quoted grep alternation patterns, orphaning file paths into segments with a junk first token - a shell-read detector needs a quote-aware tokenizer2026-08-29 →
  • CLAUDE.md reaches docsRead almost entirely by self-report (121 authored vs 8 derived across 527 logs) because the harness injects it with no tool call - it is permanently underivable2026-08-29 →
  • find .claude -name '*.md' returns 0: the Skills there are symlinks into .agents/, so both spellings must be canonicalized before counting reads2026-08-29 →
  • Both documented rules that saved this session had a second durable copy (restated inline in CLAUDE.md, or in the MCP server's system prompt) - placement evidence bearing on issue 7662026-08-29 →
  • check-conflicting-issues.ts's keyword/file-path heuristic can false-positive when an unrelated issue's body happens to mention the same file path in prose (e.g. a Midden survey report citing a row in rulebook-migration-table.md) alongside words like "delete"/"remove" used in a wholly different context elsewhere in that same issue body.2026-08-28 →
  • dagre routes a mermaid edge behind an unrelated sibling node when a parent's children fan wider than the parent, so the edge reads as belonging to the sibling — it bit twice, and only checking the rendered SVG (never the source) catches it2026-08-26 →
  • Keeping each Tenant's fan symmetric — every sibling at a rank carrying the same number of children — is what actually avoids that mis-routing; it is a layout constraint on the diagram, not a content choice2026-08-26 →
  • isNoisePath's layers/journal/content/ prefix makes the survey structurally blind to Skill Inventory deletions — the likely reason kind:skill has never once been used in 34 artifacts2026-08-26 →
  • A GitHub `closed:>=` range qualifier can silently under-report against this repo's search index; the unqualified search plus a local merged_at filter is the reliable control2026-08-26 →
  • Author-date fingerprinting a branch against main false-negatives on squash merges, since the squash commit carries the merge time, not the original author date2026-08-26 →
  • Issue #766 (CLAUDE.md modularization roadmap, on-hold) already ranks "mechanize as a PreToolUse guard" above "compress inline" for the exact pkill/&&-chaining/tail-piping rule group — a future prune-trial or frictions-to-fixes run revisiting this territory should read #766 first rather than re-deriving the same ranking.2026-08-26 →
  • Baked mermaid geometry means narrow diagrams read better: a wide graph scales down under max-width 100% until its 20px baked text is unreadable, so label brevity is a legibility lever, not a style choice.2026-08-26 →
  • The how-it-works page's audience is set by frontmatter: an `onramp` value opts a page into the Journal index's "New here?" card, which is what makes newcomer-level prose its job rather than a nicety.2026-08-26 →
  • A regressionChecks bracket session can be the very session that produced the edit under review, not one that came after it - endedAt landing a few minutes past the edit's commit timestamp is enough to flip it to the wrong side. Worth a specific example for a future audit-skills run's Phase A: prune-trial's 2026-08-23 self-merge-tier edit (d8da2ec) was authored by session_01DLmcXwjGGirmBYtx366GsX itself (PR #1026, endedAt 17:52:56Z vs. edit commit 17:46:50Z), so its moderate friction is the motivating cause, not a post-edit regression.2026-08-26 →
  • docs/agents/guards.md (added 2026-08-23, consolidating three prior guard docs) is the actual single home for which files are human-only-to-merge in this repo's automation surface — CLAUDE.md's pinned list is explicitly a non-exhaustive pointer, not the full answer.2026-08-23 →
  • `deferred-tool-guard` fails OPEN — the only one of the repo's PreToolUse guards that does; the rest deny on an undeterminable payload2026-08-23 →
  • The three deleted mechanism records already said "not restated here" repeatedly, pointing at script headers — the prose was largely a second index over rationale that already lived in the scripts2026-08-23 →
  • A prune that only deletes docs can still escalate merge tier, because inbound pointers to those docs live in code comments2026-08-23 →
  • Reading-based review and execution-based review find disjoint defect classes here: five audits found propagation gaps and contradictions; three dry runs found a targeting rule that authorised the wrong deletion, a verdict window measured from the wrong event, and a merge tier that would have merged guard code. None of the three was visible to a reader.2026-08-23 →
  • A Skill written to shrink prose grew 94 to 154 lines under three rounds of execution feedback — every line paid for by an observed failure. Accretion is not caused by carelessness; it is what happens when each fix is locally justified.2026-08-23 →
  • Two independent context-free audits of the same diff, same brief, found disjoint defect sets — the second caught the more dangerous one. For a change granting an autonomous Skill new authority, one audit pass is not enough.2026-08-23 →
  • A trial protocol can detect damage from a removed rule but never from a removed capability — nothing fails when a Skill stops running, so silence reads as success.2026-08-23 →
  • A recency window this size (20 sessions) can be almost entirely pre-resolved by the time a friction sweep runs — most of the survey budget goes to tracker archaeology confirming that, not fresh triage. Worth remembering before assuming a sweep with few new issues means the survey was shallow.2026-08-23 →
  • issue #853 (a self-approval regression) shows the same fact living correctly in one doc and stale in a second doc that supersedes it as the actual read-path is a real, recurring failure shape here — not unique to blog-post's own citation-rigor gap.2026-08-22 →
  • A single frictions-to-fixes cycle can legitimately produce just one small doc fix when the prior cycles' unfixed tail is thin — most of a 20-session window's frictions were already retired by #1000, #1008, #1009, #995 etc. before this run even started. Small output is not itself a signal the run underperformed.2026-08-22 →
  • Issue #666's own comment history already establishes the precedent for this exact situation (a tracked-but-on-hold regression recurring again): attach the new evidence as a comment, file no new issue. Consistent handling across cycles keeps the tracker from fragmenting the same root cause into multiple threads.2026-08-20 →
  • A guard's own unit tests passing for its exported check function is not evidence the check is reachable in production — trace the actual .claude/settings.json hook wiring separately.2026-08-18 →
  • Nuxt dev forwards SSR-side logs to the browser in the data-nuxt-logs payload - a server-only Vue warning invisible in the browser console shows up there2026-08-17 →
  • An MDC prose component can produce byte-identical SSR HTML and still mismatch on hydration, because ProseP renders exactly the plain tag it falls back to2026-08-17 →
  • Under pnpm's strict node_modules, require('./node_modules/vue/package.json') fails for a transitive dep - read versions from pnpm-lock.yaml instead2026-08-17 →
  • A merged PR whose body lists several "Closes #N" lines (one per issue, same keyword, own line) does not reliably auto-close all of them on this repo — PR #955 named four issues and only the first (#948) actually closed; #950/#952/#954 remain open with the merged PR still referenced on each. Root cause unconfirmed as of this session.2026-08-15 →
  • The Skill Inventory's `importance: routine` grade is the only durable list of Routine-fired Skills2026-08-14 →
  • PreToolUse genuinely intercepts Bash tool calls in this cloud environment — observed live when the new guard denied two of my own probes, which answers the residual both deferred-tool-guard.md and loop-only-tool-guard.md record as unresolved2026-08-14 →
  • A guard that pattern-matches command strings will block authoring content about itself; the repo's Write-over-cat convention is already the workaround2026-08-14 →
  • All 34 open issues had AI-authored most-recent activity, so auto-triage's human-authored eligibility branch matched nothing at all2026-08-14 →
  • The rejection of CI-enforced doc invariants is not absolute — two doc/metadata gate checks merged after it was recorded, and the line falls between a prose property and a structured artifact checked against its own schema2026-08-14 →
  • `foldSubagentTrace` unions subagent transcripts into `filesRead`/`filesEdited`/`skillsUsed` only; `models`/`toolCounts`/`durationSec` stay the parent's, deliberately, so a reader cannot compare `toolCounts.Read` against a `filesRead` drawn from a different population2026-08-14 →
  • A merged-and-deleted remote branch makes `--force-with-lease` fail with "stale info", which reads as a lease conflict rather than as the branch being gone2026-08-14 →
  • Filtering a read-trace by file extension is the wrong axis: a sampled pass found non-Markdown reads carrying the strongest signal in the corpus (a workflow file that settled an audit's central finding, a manifest holding a schema enum), while every zero-signal entry was harness scratch. Presence of an authored reason discriminates far better than the extension does.2026-08-13 →
  • A dispatched subagent's transcript is its own jsonl at <transcript-dir>/<session-uuid>/subagents/agent-<id>.jsonl, with a .meta.json sibling carrying agentType and spawnDepth. The parent transcript holds no sidechain records at all, so the extractor's undercount was total, not partial.2026-08-13 →
  • Across the 43 current session logs, 4 of 14 docs/agents files were opened by no session at all, while pr-workflow.md was opened 17 times. Read-rate varies far more than doc quality does.2026-08-13 →
  • For an exact-identifier GitHub issue search, a quoted literal query (e.g. '"session_01XXX"') to mcp__github__search_issues returns a small precise result set, while an unquoted natural-language query with the same id embedded can return a huge fuzzy-matched result set that overflows the tool's output limit.2026-08-12 →
  • Docker Compose's default project name (absent an explicit name:/COMPOSE_PROJECT_NAME override) is the basename of the directory containing the compose file, not the repo name or any other convention — this determines default container/volume names and is easy to get wrong when the compose file lives in a subdirectory (deploy/) rather than the repo root.2026-08-11 →
  • `git stash` only reverts tracked-file changes — it does not reset node_modules, .nuxt, or any other gitignored build/install state, so a 'stash and re-run to isolate the cause' repro can silently share a contaminated dependency install between the 'before' and 'after' runs and agree with itself while disagreeing with a truly clean environment (like CI's).2026-08-11 →
  • A single-test `-t`-filtered vitest e2e run, or a run against a stale `.output` build, is not a valid way to check whether a layout/height assertion is "pre-existing" — both can silently produce a different numeric result than the full suite against a fresh build. Always rebuild clean and run the full spec file before drawing a pre-existing-vs-caused- by-this-change conclusion for this class of test.2026-08-10 →
  • This sandbox's pre-installed Chromium (/opt/pw-browsers, build 1194) is a genuinely different browser build than CI's `playwright-core install --with-deps chromium` step fetches (build 1228 observed) — a real, confirmed version gap, not just a font-set difference, worth remembering as one plausible contributor to local-vs-CI pixel-measurement gaps (though it did not explain away this session's failure — CI was red for real).2026-08-10 →
  • esbuild's keepNames (tsx's default) injects a `__name` helper, so a function passed to Playwright's page.evaluate throws in the browser; pass the body as a string instead.2026-08-10 →
  • A style injected with page.addStyleTag needs !important to beat a Vue SFC's scoped rule, which carries a [data-v-…] attribute selector on top of the same classes.2026-08-10 →
  • tests/e2e/journal.e2e.ts's digestBodySnippet() takes the literal first 6 words of a Digest's first paragraph (after stripping frontmatter/heading and markdown links) and asserts that exact string appears in the rendered HTML — so any markdown formatting (backticks, bold, links) inside those first 6 words will break the match once MDC renders it, even though the same formatting later in the paragraph is fine.2026-08-09 →
  • The .githooks/commit-msg hook (scripts/provenance-footer.ts) reconstructs and overwrites a wrong/hand-typed Claude-Session trailer rather than just appending when absent — it's a stronger backstop than CLAUDE.md's prose suggests ("appends it when absent"); it also corrects a present-but-wrong one.2026-08-08 →
  • dispatch-subagents is confirmed repo-owned (not in skills-lock.json), so it is agent-editable per ADR-0015 — worth remembering next time a friction fix targets it.2026-08-07 →
  • git merge-base in a shallow clone can return an ordinary hydrated commit that is neither in .git/shallow nor parentless, so a bad base is undetectable without the missing history2026-08-06 →
  • git diff A..B compares endpoints, not the path between them, so an older base can OMIT a file rather than over-report it when a branch reverts an intervening change2026-08-06 →
  • git fetch --unshallow errors on a complete repository, so the is-shallow check is required for correctness, not just to save a fetch2026-08-06 →
  • git clone --depth=N over file:// is shallow only if the bare origin's HEAD points at a branch that was actually pushed; otherwise it reports an empty repository2026-08-06 →
  • scripts/blog-rotation.ts's own printed {last, starved, eligible} is authoritative and sufficient — no need to hand-scan pages/ frontmatter across four Spaces to reconstruct the rotation state.2026-08-06 →
  • The `workflow` OAuth scope fences `.github/workflows/` only — `.github/actions/**` is agent-pushable (probe-verified, not inferred)2026-08-06 →
  • Composite action steps support `if` AND `continue-on-error`; the widely-cited runner issues saying otherwise are stale2026-08-06 →
  • The `secrets` context is unreachable inside a composite action — pass tokens as declared inputs2026-08-06 →
  • `gate.yml`'s human-only status never protected the Gate: `package.json` already defined what each step means, and is agent-pushable2026-08-06 →
  • This repo's bar for escalating a doc rule to a PreToolUse guard is that the failure is SILENT, not merely that it recurred — a loud, self-correcting footgun stays doc-only however often it repeats.2026-08-06 →
  • A 'never' rule whose stated rationale covers only some of its cases is a latent regression: #301's wording only explained self-authored PRs, leaving the fork-PR case visibly unargued.2026-08-06 →
  • A dispatched subagent's PreToolUse payload carries agent_id/agent_type; its env and transcript_path are the parent's — payload fields are the only subagent discriminator.2026-08-06 →
  • Hook scripts are re-read from disk per invocation even though hook CONFIG loads at session start, so a temporary edit to an installed guard script is a live, reversible instrument.2026-08-06 →
  • The workflow-scope push rejection is evaluated over the whole ref update, so one workflow commit makes every other commit on the branch unpushable2026-08-06 →
  • The GitHub App contents API returns 404 (not 403) for .github/workflows paths — a permission denial wearing a not-found mask2026-08-06 →
  • A step-level continue-on-error keeps the job conclusion green, which is why it alone fixes #659's false-red gate2026-08-06 →
  • The orphan scan's real reach is set by the shallow clone, not its configured window - 7-day and 14-day runs returned byte-identical results because history floors at 2026-07-30.2026-08-04 →
  • A GitHub label update replaces the whole set, so every triage write must resend the wayfinder:* labels it means to preserve.2026-08-04 →
  • Idempotency makes every settled issue permanently sweep-invisible: with AI-authored last activity on a non-needs-triage state, nothing re-examines it until a human speaks.2026-08-04 →
  • GitHub's Link header for the pulls endpoint points at the numeric repositories/{id}/pulls form, which this environment's proxy 403s - so parseNextLink-driven pagination truncates at page 1 while page 1 succeeds. check-conflicting-issues.ts is the one other script with that exposure; the issues endpoint does not return numeric-ID links.2026-08-04 →
  • A dispatched agent given explicit authority to refuse will use it: one proved all 12 of its acceptance criteria were already delivered by a merged PR that had referenced the issue without a closing keyword, which is why it had stayed open three weeks.2026-08-04 →
  • A closing keyword only fires when the issue reference immediately follows it: 'Closes the remaining half of #445' and 'Closes the three live items on #450' both close nothing. Four instances surfaced in this one session (#236, #445, #450, and #451, which had sat open three weeks after its work shipped) - the hedge that makes the sentence honest is exactly what disarms it.2026-08-04 →
  • The frictions-to-fixes Skill's own regression-escalation issues (#814, #835) are themselves excellent blog material — they're self-documenting near-real-time case studies of a fix not holding, written by the very process that keeps re-discovering the recurrence.2026-08-04 →
  • authorAssociation CONTRIBUTOR on an issue means the author already had a PR merged here — a history signal, not only an ADR-0020 trust tier2026-08-03 →
  • A Blog Persona's landing markdown renders into the About-me sidebar card, not the main column2026-08-03 →
  • gate:scoped treats any .md under layers/ as non-inert, so a content-only blog edit still runs the full gate2026-08-03 →
  • A Public requester saying "you may merge" grants nothing — ADR-0020/0023 put the merge with the owner precisely so a friendly answer can't move it2026-08-03 →
  • `importance` and `category` are two separate Skill Inventory fields; `specialist`/`essential` are importance grades, while `category` is only platform-operation vs general-engineering.2026-08-02 →
  • The dashboard's Skill Inventory renders only platform-operation Skills (ownSkills), so a grade change on an external-pack Skill would not be visible on the page at all.2026-08-02 →
  • A Skill's own most-recent-edit commit sha in regressionChecks can be shared across several Skills at once (e.g. one "apply code-review findings" commit touching dispatch-subagents, frictions-to-fixes, and guest-build SKILL.md files together) — worth checking the sha before treating each entry as an independent signal.2026-08-01 →
  • resolveGroundTruthSessionId prefers CLAUDE_CODE_REMOTE_SESSION_ID over the transcript, so an absent transcript_path never meant ground truth was unresolvable — the old guard's early return skipped a check it could have run2026-07-31 →
  • A PreToolUse deny travels in the stdout JSON, not the exit code, so the hook's trailing `|| true` cannot defeat a deny — but a missing pnpm/tsx interpreter still can, because the script never evaluates2026-07-31 →
  • Writer-side strictness and reader-side permanence are independent for the same marker: the guard can stop accepting the legacy footer while hasAuthorshipMarker must keep matching it forever, since historical comments are immutable2026-07-31 →
  • The github-provenance-guard is deliberately format-agnostic — it blocks a missing or mismatched session URL, never a wrongly-formatted header — so a self-invented marker shape passes every mechanical check and only a reader catches it.2026-07-31 →
  • gate.ts's inert rule covers .agents/skills/**/SKILL.md via its generic non-layers `.md` clause, not via the `.claude/skills/` prefix clause — the symlink mirror is only what makes non-.md skill assets inert.2026-07-31 →
  • writing-great-skills defines cross-skill reach as exactly what model-invocation provides, which settles 'reachable by X' requirements without needing a pointer inside X.2026-07-31 →
  • scripts/preview.ts shot passes the route through verbatim, so a URL hash (/t/midden/stores#artifact-slug) scrolls the shot to that element — far cheaper than a 5000px-tall viewport.2026-07-31 →
  • Correct footers were never evidence the doc was read — the format and the resolved session id both come from the harness system prompt, not from any repo doc. A reference doc consulted only when something breaks shows a low read rate by design; that is not a failure signal.2026-07-31 →
  • ADR-0017 had already retired the "the harness gives us this for free" premise twice, in two amendments, before this session re-derived it a third time from measurement. Reading an ADR's amendments first would have shortened the investigation.2026-07-31 →
  • Measuring the user's actual requirement rather than the documented format inverted the finding — by "a full session URL is present", the state was already 86/86 and both apparent failures passed.2026-07-31 →
  • A green gate on a commit that replaces a mechanism is weak evidence. Both axes of the review independently found the same anchoring bug the full suite had just passed, because the regression tests guarding the old mechanism never ran against the new one.2026-07-31 →
  • digest/SKILL.md and blog-post/SKILL.md both independently drifted into the same "auto-merge" misnomer for their landing step — a sign that a Skill describing its own PR-landing mechanics should quote pr-workflow.md's ban verbatim (or just point to it) rather than paraphrasing it, since paraphrases of the same rule drift independently in more than one place.2026-07-31 →
  • A sweep's idempotency rule doubles as its cheapest correctness check: 14 of 28 issues skipped because AI acted last is the mechanism working, not coverage lost.2026-07-30 →
  • Determinable and authorized are independent — #674's design was settled, yet its body withheld the green-light.2026-07-30 →
  • The schema field whose NAME matches an intent may not carry it: midden's `removedIn` reads as 'the commit that retired this', but only 1 of 14 artifacts sets it, and there it names a different commit than `provenance.hash`.2026-07-30 →
  • Safari and iOS Safari implement no scroll anchoring at all, so a test disabling it reproduces the WebKit production configuration rather than inventing a synthetic one.2026-07-30 →
  • Subagents given explicit authority to refuse produce better outcomes: four declined a listed change and proved why, and each refusal was correct.2026-07-30 →
  • Skill descriptions live in the re-sent system prompt; CLAUDE.md arrives as a conversation-injected system-reminder, so they differ in durability under compaction2026-07-30 →
  • github-footer-guard.ts's bodyField was designed for exactly the uncovered create_or_update_file/push_files case — both tools take `message`, verified via ToolSearch2026-07-30 →
  • A repo can grow a missing doc as fragments inside two neighbouring docs; the fragments are the signal the home is absent2026-07-30 →
  • preserveAspectRatio="slice" crops the sides at narrow viewports and the top and bottom at wide ones, so an illustration's safe zone is the intersection of both crops, not the viewBox2026-07-30 →
  • The --midden-slate* tokens were defined in both theme blocks but referenced by zero components, orphaned since the depth-gauge was removed2026-07-30 →
  • A full-bleed band inside a max-width column is safer as two page blocks than a width 100vw breakout, which counts the scrollbar and adds a horizontal one2026-07-30 →
  • Asking an agent to review its own rendered screenshots between iterations produces real reversals; both agents reverted a prior iteration's overshoot rather than defending it2026-07-30 →
  • isResolvedMisfile (audit-skills.ts) suppresses an orphan candidate on ANY added-then-later-deleted path, though its docstring scopes the intent to a mis-filed session log — so a session that adds a doc and folds it into its single home becomes invisible to the only did-work-never-logged detector2026-07-30 →
  • Following this repo's own single-home convention (add a doc, collapse it into CLAUDE.md, delete the file) is precisely the behaviour that triggers that suppression — the blind spot is manufactured by the conventions, not by rare accident2026-07-30 →
  • isResolvedMisfile compares git %aI timestamps as raw strings while its sibling functions deliberately use Date.parse and document the mixed-offset hazard; real data in the window carries +02:00 offsets2026-07-30 →
  • The last successful orphan detections (#564/#565, filed 2026-07-18T00:51Z) predate PR #581's merge (01:39Z) by 48 minutes — the detector worked right up to the regression landing2026-07-30 →
  • Emulating a historical scheduled run is easy and worth doing: --since/--until pinned to the sweep's own timestamp reproduces exactly what that day's check saw, turning did-it-run guesswork into a table2026-07-30 →
  • A well-maintained Inventory can legitimately produce a no-op audit-skills run: all 35 Skills' grades/roles already matched a fresh 40-session window, and the regression watch cleared every bracket without a confirmed regression — the healthy outcome is no PR, not a forced one.2026-07-30 →
  • A Tenant layer's global CSS (registered via that layer's nuxt.config.ts `css:` array) loads app-wide, not scoped to that Tenant's own routes — so `var(--midden-accent)` resolves correctly even on the root index page outside `/t/midden/*`.2026-07-29 →
  • The mermaid pre-render pipeline (ADR-0024) is fully built and drift-gated, yet exactly one diagram exists in the whole content tree — the infrastructure is paid for and idle.2026-07-29 →
  • The two Journal onramps set up a question they never answer - how autonomy is bounded - which lives only in ADR-0004/0020 and is invisible to site readers.2026-07-29 →
  • A per-Space content rule can often be derived from the data (does this Space have any pages?) instead of hardcoding Space names in a platform script — the derived form generalizes to future Spaces for free.2026-07-29 →
  • Nuxt auto-imports every app/utils export globally across ALL layers, so extracting a shared helper out of an SFC turns a private function into a global name — the repo's answer is layer-prefixed exports (formatBlogDate, formatMarqueeDate).2026-07-29 →
  • scripts/blog-rotation.ts's eligible-set output ({last, starved, eligible}) makes A0 a single command rather than a manual frontmatter scan across four Blog Spaces — fast to run, unambiguous to apply.2026-07-29 →
  • mcp github list_branches can never surface a deleted branch — a dead branch's only remaining trace is its closed-unmerged PR's head ref2026-07-29 →
  • git log --diff-filter=D with -M reclassifies moved files as renames, giving a free mechanical slice of the Midden's Gate B2026-07-29 →
  • git fetch origin refs/pull/N/head recovers a closed-unmerged PR's content for SHA-pinned permalinks — including non-head commits like a replaced draft2026-07-29 →
  • Midden routes are not prerendered, so greping .output/public for rendered content proves nothing - existing artifacts are absent from it too. Verifying Midden content needs a live preview server and a DOM check, which is exactly what docs/agents/verifying-ui-changes.md warns about in general form.2026-07-29 →
  • The branch half of a midden survey is fully decidable from the repo's oldest commit date while the repo is younger than the dormancy floor - no branch walk needed at all.2026-07-29 →
  • git's -M rename detection misses a rename whose body also changed enough (the Atlas redate: same slug, new date, edited content), so those land in the deletion set looking terminal and must be Gate-B checked by hand.2026-07-29 →
  • `slice(-n)` with n=0 returns the whole array, so a count-based retention budget needs an explicit non-positive guard or it silently retains everything2026-07-29 →
  • A calendar-window retention drains `current` toward empty during a quiet stretch, whereas a count-of-dates budget holds the newest N however far apart they fall2026-07-29 →
  • Any e2e assertion against real, retention-swept repo content (not just Digest dates) needs the same 'read live, tolerate absence' treatment as currentDigestDates() — a single rare fixture (like the one `external: true` session) can silently age out from under a hardcoded assertion.2026-07-29 →
  • scripts/blog-rotation.ts prints {last, starved, eligible} directly — no need to hand-scan pages/*.md frontmatter for the rotation gate.2026-07-28 →
  • A per-Tenant CONTEXT.md's own 'decision history lives at issue #N' line (ADR-0021) is itself a good primary source for classifying whether embedded prose is Mis-location — the file names its own correct home.2026-07-28 →
  • mcp__github__issue_read/search_pull_requests/list_pull_requests resolved correctly even when called before ToolSearch loaded their schemas — the deferred-tool-guard doesn't block every pre-ToolSearch call, only wrong-shaped ones, so a call succeeding is not proof the ToolSearch-first rule was actually followed.2026-07-28 →
  • The humanPromptedClosures dedup gap is structural, not a one-off: any session absent from DISMISSED_HUMAN_PROMPTED_CLOSURES will read as "new" to a future run even if it was already cited 1-2 times on the standing thread, until someone notices and files a dismissal-set fix (the #540 → #634 → #700 pattern). Checking the thread's actual comments, not just the dismissed set, is the only reliable way to catch this before posting.2026-07-27 →
  • ADR-0009's "a later extract is a superset of an earlier one" guarantee holds only for the derived half. writeScratch() plainly overwrites the authored scratch, and stitch() takes goal/outcome/summary/prs/frictions from it verbatim — so the two halves of one log have opposite overwrite semantics, and nothing reconciles them.2026-07-25 →
  • A clobbered session log is self-diagnosing: because the trace half stays cumulative, the surviving entry contradicts itself (prs: [] beside a merge_pull_request tool count) rather than just looking thin.2026-07-25 →
  • The regressionChecks before/after brackets are calendar-adjacent (5 sessions before/after the edit commit by count), not filtered to sessions that actually invoked the edited Skill — for a low-frequency Skill (blog-post, digest, atlas-specimen) this often means neither bracket contains a real invocation, so the Phase A screen needs a manual look at the Skill's actual nearest usedIn sessions rather than trusting the mechanical bracket alone.2026-07-25 →
  • A shallow clone's grafted boundary silently caps `git log --since` — a completeness claim over a date window is only as deep as the clone.2026-07-24 →
  • The Midden/Palimpsest split is the load-bearing classifier here — an entire Tenant deletion (Search→Commons) is Palimpsest, not Midden, because search is carried forward.2026-07-24 →
  • Midden narrator prose should carry freshness through the `fresh` condition grade and a find's fixed stratum position, never a calendar anchor — the metaphor ages, "this very morning" does not.2026-07-24 →
  • The Agent tool's per-call `model` override plus `isolation: worktree` cleanly runs a model-diverse parallel design bake-off with no branch contention.2026-07-24 →
  • PR merge order isn't chronological with PR-open order or with content-authorship timestamps: PR #643 (built in response to a gap PR #631 exposed) actually merged over a day before #631 itself finished merging — always check actual merged_at timestamps via the GitHub API before asserting a before/after relationship in narrative writing.2026-07-24 →
  • docs/agents/verifying-ui-changes.md's 'write ad-hoc scripts inside the repo tree' convention already solves the NODE_PATH/CJS-under-tsx friction for any script that becomes a committed scripts/ file — no special handling is needed in a new tool beyond just being committed there.2026-07-24 →
  • The prototype skill's UI.md branch mounts variants as real Nuxt routes inside the app (captured via the existing preview.ts/screenshot.ts), not as standalone static directories outside the build — so a generic static-dir capture tool currently has no consumer in that workflow.2026-07-24 →
  • Phase A's regressionChecks screen can be pure date-adjacency noise: 3 of 6 bracketed edits this run (auto-triage, frictions-to-fixes, guest-intake) had zero sessions in the after-bracket that actually invoked the edited Skill, so the friction-count delta there measures unrelated sessions, not the edit's effect. Worth checking each after-bracket session's skillsUsed before reading a friction-count shift as a regression signal.2026-07-24 →
  • This repo's e2e tests read real, live-changing repository content rather than fixtures — an 'X doesn't exist yet' assertion races every other concurrently-active agent session and will eventually go stale; prefer assertions tied to specific existing content.2026-07-23 →
  • The CI gate's 'safety-gate green on <sha>' bot comment references the PR's synthetic merge-commit SHA, not the branch head SHA that pull_request_read get_status reports against — get_check_runs is the reliable per-push check result.2026-07-23 →
  • pull_request_creation_policy=collaborators_only is a real GitHub repo setting that blocks fork PRs from non-collaborators — not a general GitHub limitation.2026-07-23 →
  • Ad-hoc tsx/playwright-core captures from /tmp need NODE_PATH pointed at the repo node_modules and an async main() wrapper (tsx emits CJS there, breaking top-level await).2026-07-23 →
  • A clean cross-tenant read seam needs shared collection 'kinds' single-homing each schema plus a derived #catalog projection (the #routing/ADR-0014 pattern), so an aggregator queries by kind without repeating schemas — realized in #643/ADR-0025.2026-07-23 →
  • A GitHub Actions step that writes (e.g. gh pr comment) fails on a fork PR's read-only GITHUB_TOKEN with 'Resource not accessible by integration'; unless it's continue-on-error it reds the whole job — a false-negative that hits every external fork PR (the gate.yml Doorbell step, issue #659).2026-07-23 →
  • CLAUDE_CODE_SESSION_ID in a CCR/cloud session is a local-transcript UUID, not the canonical session_01… id — the canonical id is CLAUDE_CODE_REMOTE_SESSION_ID with its `cse_` prefix swapped for `session_`, matching the system prompt's own commit-footer template.2026-07-23 →
  • scripts/blog-rotation.ts already exists and cleanly returns {last, starved, eligible} straight from scanning publishedAt across every Persona's pages/ — no manual frontmatter survey needed for the A0 rotation gate.2026-07-22 →
  • @nuxt/content exports PageCollections/PageCollectionItemBase — the clean way to type a cross-collection page query is casting the key to keyof PageCollections.2026-07-22 →
  • The page type already guarantees title/description/path across Tenants, so a page kind needs no schema — the marker-vs-schema asymmetry falls out of CollectionDef's existing page/data split.2026-07-22 →
  • A satisfies Record<...> narrows a marker literal so .schema isn't a readable property — a test must assert via the whole literal, not property access.2026-07-22 →
  • Relocating the ADR-0009 session schema to a shared `session` kind was behaviour-neutral because every consumer (log-session.ts, session-end.ts, the dashboard) routes through validateEntry/generated types, not the manifest object — so sourcing the identical schema from a new home changed nothing observable.2026-07-22 →
  • A caller-supplied projector makes queryAcrossTenants generic over any kind without a KindItem<K> type-inference that fights Nuxt Content's per-collection generics — and projecting inside the fan-out drops page body ASTs from the aggregated corpus for free.2026-07-22 →
  • Zod .merge() across two jiti module instances silently breaks strip-unknown-keys (its catchall instanceof ZodNever check fails cross-instance, turning strip into reject-as-never) — a subagent hit this merging a kind contract into a manifest schema; local.extend(missing-contract-fields) is the one-class fix.2026-07-22 →
  • auto-triage's Public-issue-routes-to-ready-for-human rule and guest-intake's ADR-0023 confirmation grant can theoretically collide on the same ticket, but the collision window self-closes because guest-intake's own follow-up AI comment becomes the new most-recent-comment, which auto-triage already skips.2026-07-22 →
  • The session-id-fabrication failure mode has now survived three separate doc-only prose passes at retiring it (#362, then #387/the commit-trailer guard, then #605/#606 for the GitHub-comment-footer surface specifically) — the comment-footer surface reproduced the exact failure #605/#606 described within two days of that fix merging. Worth treating prose-only fixes for this failure class as provisional until a mechanical backstop exists for the comment/PR-body surface too, the way the commit-trailer surface eventually got scripts/session-id-guard.ts.2026-07-21 →
  • session_01CGdWVh7DctbuH1sro8Xs4x has now been re-cited on issue #483's standing thread five times (four before this run) purely because it stays inside the rolling 40-session window — it was never added to DISMISSED_HUMAN_PROMPTED_CLOSURES the way issue #540's two entries were. A future audit-skills or maintenance pass touching scripts/audit-skills.ts should add it to that dismissed set now that it's thoroughly acknowledged.2026-07-21 →
  • Mermaid `handDrawnSeed` pins rough.js's per-node outline jitter, making the rendered SVG byte-deterministic across runs.2026-07-20 →
  • @fontsource packages ship the woff2 via the npm registry, so a webfont is obtainable even when the network policy blocks general web/CDN fetches.2026-07-20 →
  • Mermaid node/edge labels are foreignObjects sized to the measured text width; the browser clips there, so a wider display font truncates even with spare shape padding.2026-07-20 →
  • CLAUDE_CODE_REMOTE_SESSION_ID (the cse_->session_ footer id) is stable across session resume and inherited into worktree subagents; resume does not mint a new footer id.2026-07-20 →
  • CLAUDE.md's own ToolSearch-before-first-call rule text still says "already been violated twice," but a third occurrence (issue #612, filed 2026-07-20) is open and unresolved — the prose hasn't caught up to its own tracking issue yet, a small live example of doc drift worth checking again once #612 resolves.2026-07-20 →
  • A 500 (not 404) on an existing content-hashed _nuxt chunk with no deploy points at a transient origin serving hiccup, not a stale-asset problem.2026-07-19 →
  • @nuxt/content lazily import()s its client adapter/loader chunks on first queryCollection, so their fetch failures surface through the page's useAsyncData error as 'Failed to fetch dynamically imported module'.2026-07-19 →
  • pnpm gate:scoped's e2e layer runs in ~95s for the full 55-test L2 smoke suite; safe to background and Monitor rather than block the turn on it.2026-07-19 →
  • audit-docs' post-edit Phase-B deep-read is worth doing even when the friction severities alone look damning (2 majors) — reading the actual friction descriptions showed both were unrelated to the SKILL.md content that changed, which the coarse Phase-A severity screen alone couldn't have told apart from a real regression.2026-07-19 →
  • A tall panel floated beside an accordion couples their band height (max of the two); at the crossover, collapsing an accordion item changes page height nonlinearly and can break scroll-pinning that assumes enough headroom — and the crossover shifts with font metrics, so it manifests in CI but not locally.2026-07-19 →
  • The safe way to put a shorter panel beside an accordion is a CSS grid with align-items:start where the accordion is guaranteed the taller column, so the grid row height tracks the accordion alone and collapse behaviour matches the full-width case — unlike a float, which lets whichever side is taller drive the band and reintroduces the coupling.2026-07-19 →
  • The ground-truth session id is reachable from repo code two ways — `CLAUDE_CODE_REMOTE_SESSION_ID` (cse_→session_) and the transcript's own sessionId — via `resolveGroundTruthSessionId` (PR #533), which #387's guard reuses rather than re-deriving.2026-07-18 →
  • A merged PR's `Closes #N` keyword can silently close some referenced issues and not others (closed #292/#349, missed #325) — leaving a done issue stranded open.2026-07-18 →
  • The 14-char GH_TOKEN/GITHUB_TOKEN here are proxy-side references, not real GitHub tokens; the egress proxy swaps in real creds for curl's proxied request, so curl authenticates where a direct Node fetch cannot.2026-07-18 →
  • A PR appearing right after a push, authored under the owner's account via the Claude app, is NOT proof the platform auto-opens on push — the owner can open it from the Claude mobile UI. Don't infer an auto-open mechanism from timing + app-authorship alone (verified with the owner this session).2026-07-18 →
  • Every issue body/comment in this repo is authored under owner login feffef, so author identity alone can't distinguish AI from human writes — only ADR-0017 provenance-footer presence can.2026-07-18 →
  • A promotion brief's stated premise can be stale — #325's brief assumed the dev-server manifest watch hook was missing, but freshly-fetched origin/main showed it already landed; verify the issue's premise against source (not just the fix surface) before promoting, or you post a stale claim on a public issue.2026-07-18 →
  • The richest, most verifiable blog material this run wasn't in git log or session-log frictions at all — it was the actual GitHub issue comment thread behind a session-log friction one-liner (issue #572's friction referenced issue #555 in one sentence; the full 23-comment thread was far more concrete and citable than the summary implied). Worth fetching the underlying issue thread directly via issue_read, not just the session-log's own paraphrase of it.2026-07-18 →
  • Karen's factual miss and the guest-intake scanner's own logged friction (missing an OWNER comment mid-thread) are the same shape of bug: true information sitting in a thread nobody happened to be watching at the right moment — a good throughline for grounding a reaction post in something structural rather than just 'gotcha, you were wrong'2026-07-18 →
  • Auto-subscription to a PR's activity appears to happen automatically at the platform level when a dispatched worktree-isolated subagent opens a PR under the parent session's identity, even though the subagent itself never calls subscribe_pr_activity (per its own brief) — the orchestrating session starts receiving webhook events for it without an explicit subscribe call of its own.2026-07-18 →
  • Two windowed sessions (session_015PgK5s6dkbKrW7jagzTZRE — edited layers/midden/CONTEXT.md, root CONTEXT.md, and CONTEXT-MAP.md while building the Midden Tenant; session_016cGM4wnw4nNBFBef4ve1vC — authored ADR-0023 from scratch) did squarely domain-modeling-shaped work without invoking the domain-modeling Skill, but neither session logged a friction about it and both outcomes were merged without reported quality issues — ambiguous whether this is a genuine "opportunity missed" (a demotion candidate) or just two sessions handling a small amount of glossary/ADR work inline without needing the dedicated process. Didn't demote given domain-modeling is CONTEXT.md's own canonical "essential" example and the evidence bar for reversing that should be unambiguous — left as a citable data point for a future run to weigh if the pattern recurs.2026-07-18 →
  • guest-build's and guest-intake's only windowed usage sessions (session_01CGdWVh7DctbuH1sro8Xs4x, session_012KajpP5iqjGPQeVzx8wQVr) each carried real, well-evidenced friction about the Skills themselves — guest-build's disable-model-invocation hard-blocks the Skill tool even via its own documented /loop firing path (moderate); guest-intake's SKILL.md gives no guidance for a single account's sustained multi-technique probing across many rounds (moderate); and there's no in-flight marker so two concurrent guest sessions can't see they're negotiating/building the same issue (moderate, nearly caused contradictory PRs for #555). None of this is attributable to either Skill's own most recent edit (both edits landed right before these sessions' first-ever use, so there's no pre-edit baseline to compare against) — it's real product friction, but frictions-to-fixes' remit to survey and dispatch, not a regression this Skill's step 4 can act on.2026-07-18 →
  • curl already respects this environment's HTTPS_PROXY/CA bundle with no special flags; Node's built-in fetch needs NODE_USE_ENV_PROXY=1 set before process start, which a running script can't do to itself.2026-07-17 →
  • GitHub's REST issues-list endpoint returns author_association directly per issue — ADR-0020's Public/Trusted split is a plain REST field, no GraphQL needed.2026-07-17 →
  • author_association/footer-absence (this repo's AI-vs-human signal) proves who typed a comment, not whether what they typed reflects real intent — a genuinely human comment can still be the human deliberately testing the system, and a session's own unverifiable "confirmed elsewhere" claim needs independent verification before it's treated as settled, same as any other subagent-derived claim.2026-07-17 →
  • A guest's own quoted/paraphrased text of what an owner supposedly said must always be independently verified against the real thread (issue_read get_comments), never trusted at face value — in this session the quote turned out to be accurate, but a fabricated one would have looked identical without checking2026-07-17 →
  • A Claude Design handoff bundle (.dc.html files) can contain multiple genuinely alternative directions for the SAME screen inside one export, not just one resolved design — scan explicitly for '(resolved direction)' labeling vs. unlabeled alternatives before assuming a bundle is implement-as-is, and surface any real fork via AskUserQuestion rather than guessing which the user meant.2026-07-17 →
  • A static HTML/CSS/JS design mockup cannot model real behavioral requirements (scroll-sync state, retain-last-active-on-gap, SSR-vs-client-only rendering) — its 'active state' will be hardcoded/simplified. Implementing a design handoff against an app with an already-resolved behavioral spec is 'reskin against the real behavior', not 'port the mockup's simplified state logic' — worth stating explicitly in any future design-handoff implementation brief.2026-07-17 →
  • A GitHub bot comment reporting a check result (e.g. '✅ safety-gate green on <sha>') can cite a different SHA than the PR's head commit — plausibly an ephemeral PR-merge-commit SHA GitHub computed the check against, not the branch tip — so don't treat a SHA mismatch alone as evidence the comment is stale or wrong; cross-check via get_check_runs against the actual head when in doubt, but don't discard the bot's own report either.2026-07-17 →
  • Dispatching a DOM CustomEvent when an rAF settle loop completes lets an e2e await the exact end of an animation deterministically — the proper fix for a settle-race flake, versus a longer expect.poll timeout that only widens the race window.2026-07-17 →
  • An rAF loop that exits when its tracked position stops changing is unsafe if that motion starts a frame or two late — it can settle before the motion begins; bound such a loop by the known transition duration (wall-clock, matching the CSS transition) instead, so it cannot exit early and self-caps.2026-07-17 →
  • A flaky-anchoring failure value is itself diagnostic — after minus before equalling the exact height of the collapsed element (zero compensation) pinpoints a no-op pin, distinguishing a premature settle from a scroll-clamp or a measurement issue.2026-07-17 →
  • Browser scroll anchoring (overflow-anchor, on by default) silently keeps content visually stable when height above the viewport changes — so a UI test whose app-level scroll compensation is broken can still pass locally, then fail on CI where anchoring is suppressed (it is disabled for a short window after any programmatic scroll, e.g. Playwright's click auto-scroll). Reproduce by setting overflow-anchor:none.2026-07-17 →
  • Playwright's locator.click() scrolls the target into view before clicking; for a test asserting scroll/viewport position that synthetic scroll is a confound a real user click never causes — dispatchEvent('click') opens without it.2026-07-17 →
  • A general-purpose subagent that itself spawns child agents via the Agent tool: those children's task-notifications deliver to 'main' (the top-level session), not back to the spawning subagent — orphaned-but-still-usable data, not a dead end, if the orchestrator watches for and collects them.2026-07-17 →
  • findHumanPromptedClosures(sessions) in scripts/audit-skills.ts is called with the full unwindowed session history (not the primary 40-session window), same as findManuallyRescuedClosures — worth checking both signals against the actual call site, not just the SKILL.md's prose description, before treating their output as fresh evidence.2026-07-17 →
  • A guest is reliably detectable by a Public authorAssociation (a guest cannot post as OWNER), but owner-vs-agent among OWNER comments needs the ADR-0017 footer's absence, not authorAssociation.2026-07-16 →
  • During a GitHub /pulls REST outage a PR's state is still recoverable without that API: `git ls-remote origin refs/pull/<N>/head` confirms the PR exists and its head SHA, `merge-base --is-ancestor <head> origin/main` tells you if it merged, and issue_read on /issues/<N> returns state/closed_by (PRs share the issue endpoint) even while /pulls/<N> 503s.2026-07-16 →
  • The GitHub App's own auto-appended PR-body footer ("_Generated by [Claude Code](https://claude.ai/code/session_01…)_") is a platform-verified, independent source for a session's canonical id — more trustworthy than either the transcript's own internal sessionId field or a recalled tool-description example, since the App backend stamps it server-side from the real session identity.2026-07-16 →
  • CLAUDE_CODE_REMOTE_SESSION_ID (env, `cse_XXX...`) normalizes onto the canonical `session_XXX...` id by simple prefix replacement — confirmed directly against this sandbox's own environment and cross-checked against the GitHub App's PR-footer id. CLAUDE_CODE_SESSION_ID (no REMOTE) is a different variable entirely — the local CLI transcript's own internal id, which only coincides with the canonical id on a plain local CLI session with no CCR wrapper.2026-07-16 →
  • An odd-numbered panel of differently-tiered models (2x Sonnet + 1x Opus), each working fully independently then synthesized centrally, converged strongly or unanimously in 5 of 6 wayfinder rounds — a workable technique for fast-pacing a map when a human explicitly opts to delegate HITL judgment.2026-07-16 →
  • GitHub Actions pull_request runs report the safety-gate green on the ephemeral refs/pull/N/merge SHA, not the branch tip — verify against the real head via get_check_runs before trusting a green-doorbell webhook.2026-07-16 →
  • A standalone tsx script cannot reach GitHub MCP tools (they're the agent's, not a child process's); merged_by-style API fields are only obtainable via gh CLI, which this environment lacks.2026-07-16 →
  • Nuxt 4.4.8: purgeCachedData & granularCachedData default true; default getCachedData returns static.data[key] (empty for runtime-SSR), so re-navigation re-runs the useAsyncData handler and does not serve a cached null.2026-07-16 →
  • @nuxt/content writes a fetched sql_dump to localStorage BEFORE decompress/apply, so a corrupt 200 body is pinned under the valid checksum and poisons reloads too — not just in-memory state.2026-07-16 →
  • @nuxt/content swallows per-command db.exec errors during dump apply, then marks the collection loaded — a resolved-but-empty load the finally-evict cannot recover.2026-07-16 →
  • In this repo every write shows author feffef (OWNER), so the ADR-0017 provenance footer, not the GitHub author field, is the only reliable AI-vs-human signal for triage eligibility.2026-07-15 →
  • Nuxt Content resolves MDC block components (`::latest-commit`) from a layer's `app/components/content/` dir automatically — no explicit global registration needed.2026-07-14 →
  • A `data` collection isn't required for a Tenant; a single `page` collection with one index.md satisfies the manifest and gives the L2 smoke sweep its `<h1>`.2026-07-14 →
  • A gracefully-degrading endpoint makes the L2 smoke sweep pass on its error path too (the `<h1>` comes from markdown, the fallback logs no error) — so proving a runtime capability needs a targeted assertion that specifically fails on the fallback, not just clean hydration.2026-07-14 →
  • A plain `pnpm gate:scoped` Bash call was auto-run in the background by the harness without passing run_in_background — worth expecting for any long-running (unit+build+e2e) command even when not explicitly backgrounded.2026-07-14 →
  • execFileSync's `timeout` option reports expiry as `err.code === 'ETIMEDOUT'`, not an `err.killed` flag (which stays `undefined` in practice) — confirmed by spawning a real slow stub process, not assumed.2026-07-14 →
  • A gate check wired into `pnpm validate:content`/`pnpm gate` via package.json is agent-mergeable and CI runs it automatically — no `.github/workflows/gate.yml` edit needed. Only a *dedicated* new CI job needs gate.yml (and thus the docs/proposals handoff).2026-07-14 →
  • In `SessionCard.vue`, `<JournalDisclosure class="head">` wraps the ENTIRE head including the `.foot` row — so any interactive control placed in the foot lives inside the accordion's click-to-toggle target and can swallow the toggle click.2026-07-14 →
  • A Public author (no write access) can only ever open a *fork* PR; a same-repo-branch PR always has a Trusted author, because pushing a branch requires write access. So author_association is fully determined by fork-vs-same-repo for the trust question.2026-07-14 →
  • Plain `pull_request` runs the workflow file from the PR head (the fork's copy) and clamps GITHUB_TOKEN to read-only for fork runs — unlike `pull_request_target`, which runs the base-branch file with a write token (grounded in docs/research/making-repo-public.md, GitHub primary sources).2026-07-14 →
  • Local Claude Code CLI sessions identify by a UUID (transcript sessionId / CLAUDE_CODE_SESSION_ID), not the cloud session_01 format the log-session instructions assume; and they hold the workflow OAuth scope, so pushing .github/workflows/* succeeds (unlike cloud web/mobile agent sessions, ADR-0004).2026-07-14 →
  • auto-triage's first-run miss (issue #428) and its same-session fix (PR #460) are both independently verifiable via mcp__github__issue_read get_comments — the '#428#issuecomment-4966471078' single-letter 'A.' comment karen cited checks out verbatim, including the owner's author_association and timestamp.2026-07-14 →
  • ADR-0022's own text ('Drift/Contradiction verify against the code') explains *why* the audit-docs fix to RESCUED_GAP_HOURS picked the wrong number: its heuristic trusts code over docs on contradiction, which breaks when the code side is itself just an unverified assertion, not a derivation.2026-07-14 →
  • A doc-vs-code contradiction can survive a genuine, well-intentioned drift-fixing pass (#436, /audit-docs) if that pass's own scope was a different finding (documenting a suppression mechanism) that happened to touch the same lines — deleting one side of a contradiction without checking which side was correct reads as resolved but isn't.2026-07-14 →
  • GitHub author_association can't distinguish an agent-authored comment from the human owner's own — both post as OWNER under the same account, since agent-driven writes go through the owner's connection (ADR-0017). The reliable discriminator is the ADR-0017 provenance footer's presence/absence.2026-07-14 →
  • Wayfinder is a planning tool by default ('plan, don't do'); it and triage overlap ONLY because this repo runs execution-carrying maps (#279/#439) that turn wayfinder tickets into build backlog — which is triage's domain. The overlay coexistence is the accepted pragmatic cost of that mixing.2026-07-14 →
  • Surveying recent-session learnings for doc gaps mostly returns "already documented" — the frictions-to-fixes/audit-docs machinery harvests reusable ones fast, so the honest result is often a near-empty set, not a backlog.2026-07-14 →
  • Individual browser-probing gotchas each recurred only once (below the rule-of-two bar), but as a cluster they justified one consolidated home even though no single fact had repeated.2026-07-14 →
  • Chromium's `--window-size`/Playwright's `viewport` size the CSS layout viewport directly, ignoring the page's own `<meta name="viewport">` — a "missing viewport meta" theory for a mobile overflow bug is usually a dead end once you confirm the meta tag is present.2026-07-14 →
  • A flex/grid item's automatic minimum size (`min-width:auto` flooring at its content's min-content) only propagates from an element that is itself a direct flex/grid item of the container being track-sized, not from any nested flex/grid descendant regardless of depth.2026-07-14 →
  • The mechanical orphanedSessions/manuallyRescuedClosures signals (full-history scope) are strong corroborating evidence for judging whether a closure-behavior regression fix actually worked — cross-checking them against Phase B's friction read was more conclusive than friction severity/count alone.2026-07-14 →
  • The audit-docs Skill's own SKILL.md is itself Live-tier and squarely in-scope for /audit-docs findings — this run's self-referential audit surfaced real drift, a contradiction, and an ambiguity in the currently-running skill's own text, confirming the tier design (no special exemption for the skill auditing itself) works as intended.2026-07-13 →
  • Session-log commits (the Stop hook's) carry NO Claude-Session trailer, so they never pollute a session's own work-commit set — which is exactly what makes last-work-commit cleanly separable from the closure commit.2026-07-13 →
  • durationSec in a session log equals wallclock (endedAt − startedAt), not active time, so it cannot by itself distinguish an idle-then-rescued session from a genuinely long one.2026-07-13 →
  • Model-based skill invocation fires only off the frontmatter `description` (the body isn't visible pre-invocation); close-session's ambient 'am I wrapping up?' trigger reads as 'I'm waiting' mid-run, which is why an in-body explicit invoke in the running skill is the reliable path.2026-07-13 →
  • log-session's own doc settles close-vs-log: close-session is the front door for the initial log; log-session direct is only for *updating* an already-authored log — which makes the PR-open (close-session) / finalize (log-session) split the doc-sanctioned design, not a hack.2026-07-13 →
  • `close-session` in a log's `skillsUsed` does NOT mean the session self-judged closure — a manually-prompted session lists it too; the regression is invisible to usage-rate and to the friction stream unless the nudge is logged (now forced via HUMAN-PROMPTED-CLOSURE).2026-07-13 →
  • A shallow clone makes `git log --follow` on any file bottom out at the graft-boundary commit, which reads deceptively like a squash/re-root of history.2026-07-13 →
  • vitest's expect.poll defaults to a 1000ms timeout / 50ms interval unless overridden per-call or via config.expect.poll — not stated in any doc available locally, only in vitest's own dist source.2026-07-13 →
  • The harness's per-session "Develop on branch X" block (shown at session start, outside CLAUDE.md and outside the invoked Skill's own text) is the caller-pinned designated branch CLAUDE.md's branch-convention bullet describes — it overrode audit-docs's own default `journal/audit-docs-<date>` branch name for this run's primary PR.2026-07-13 →
  • Phase A's regressionChecks before/after brackets can be identical across several Skills edited in the same commit (e.g. a docs-reconcile sweep touching 4 SKILL.md files at once) — a coarse friction-severity uptick in that shared bracket is then a property of whichever unrelated sessions happened to fall in it (this run: the Atlas Sprint 2 rework's own major friction), not evidence about any one Skill's edit. Worth remembering before spending Phase B effort on every flagged skill separately when several share identical brackets.2026-07-13 →
  • Playwright's page.screenshot({ clip }) uses viewport-relative coordinates unless fullPage: true is also set — passing clip alone silently clips against the wrong origin on a scrolled/tall page.2026-07-13 →
  • To separate two graph edges between the same node pair with a perpendicular offset, the perpendicular must be measured from a canonical (pair-order-independent) direction, not each edge's own from→to — otherwise reversing the edge flips the perpendicular's sign right along with the offset's sign and the two cancel.2026-07-13 →
  • The bug in issue #383 was still live in this container's own node_modules — validating the fix required first hitting the exact failure the issue described (missing mermaid), which confirmed the fix addresses a currently-occurring problem, not just a theoretical one.2026-07-13 →
  • Playwright's locator.click() silently scrolls the element into view before dispatching the click — call scrollIntoViewIfNeeded() first when a test measures exact geometry around a click.2026-07-12 →
  • A single 'is this scroll ever animated?' framing was too coarse: whether a scroll should ease depends on WHY it's happening — correcting a reflow the click itself caused should be instant (nothing should be seen moving), while animating the container's own height change is exactly the visible feedback the user wanted. Splitting those two questions up front would have avoided doing this in two follow-up rounds.2026-07-12 →
  • The generated entryRoutes export in the #routing virtual module had no runtime consumer; e2e derives routes via entryRoutesFrom() directly — the homepage now consumes it, closing the redundancy.2026-07-12 →
  • entryRoutesFrom() sorts alphabetically while routingMap iteration follows manifest declaration order; unobservable today because the homepage's surviving list is one item, but it becomes visible if journal gains a third Space.2026-07-12 →
  • Vue's whitespace-condense inserts a text-node space before a v-if sibling regardless of its outcome, so extracting conditional inline markup byte-identically needs whole-block v-if/v-else, not an inner v-if.2026-07-12 →
  • ADR-0016's Tenant-root-page precedent (built for the Atlas front door) transposes directly onto a second Tenant (the Blog) with no adaptation needed — same resolveSpaceRoute-per-Space read-only pattern, same reason it stays outside the ADR-0004 human-only routing core.2026-07-12 →
  • publishedAt frontmatter and git commit time can silently diverge in this repo's blog content with no gate catching it (they're independent, self-reported vs. derived facts) — worth checking directly with git log rather than trusting the frontmatter value alone when timestamp ordering actually matters to a claim.2026-07-12 →
  • In this Atlas Tenant, a ledger note's prose can silently encode its own date via an ordinal ("the second", "the sixth") or a callback ("since the fourth") — these don't show up in schema validation or the gate, only a targeted grep or a human re-reading the rendered page catches them before a redate breaks them2026-07-12 →
  • Mermaid needs real SVG layout (getBBox/getComputedTextLength); jsdom stubs the DOM tree but has no layout engine, so a browser is unavoidable for its own renderer.2026-07-12 →
  • Rendering with theme:'base' and each --diagram-* token set to a unique sentinel hex leaves those hexes verbatim in the SVG, so a post-process to var(--diagram-*) yields a static SVG that still adapts to dark mode with zero JS.2026-07-12 →
  • @viz-js/viz (Graphviz WASM) is the only genuinely browserless renderer, but speaks DOT not Mermaid — browserless requires changing authoring syntax.2026-07-12 →
  • The Atlas wheel's per-specimen phenology data was already complete on all 15 specimens; the "completeness" gap the task named was the missing seasons-vs-phases explanation, not any missing data.2026-07-12 →
  • A shared integration branch in this multi-agent repo is a moving target — other sessions force-rebase and merge feedback onto it. Always re-fetch and `git reset --hard origin/<branch>` to the authoritative tip before operating, and prefer --force-with-lease for any rewrite.2026-07-12 →
  • When CI fails but its logs 404 from the API, the fastest diagnosis is to reset to the exact failing ref and reproduce `pnpm gate` locally — the new gate steps (verify:skills-lock, content-validation) run identically.2026-07-12 →
  • Both dispatched-subagent failure modes (premature stop before commit; hard session-limit termination) strand complete work uncommitted in the worktree — a "commit-and-push-as-backup on takeover" reflex plus reading the agent's final message reliably recovers it.2026-07-12 →
  • vitest's `pnpm test` positional filter `tests/unit` matches by substring, so a Tenant-layer test at layers/atlas/tests/unit/*.spec.ts DOES run under the gate.2026-07-12 →
  • The scroll-to-middle was a scroll-anchoring failure — browsers keep content stable only when the collapsing element is fully off-screen; when it straddles the viewport top, collapsing it strands the clicked item above the fold.2026-07-12 →
  • GitHub's enable_pr_auto_merge (MCP) can't arm while a required check is in_progress — it reports the check as 'failing'; you must poll and arm/merge on green.2026-07-12 →
  • In a backgrounded command, piping through tail makes the completion notification report tail's exit code, silently masking the real command's failure.2026-07-12 →
  • A wide one-row mermaid graph is downscaled to the article column width (SVG max-width), shrinking its text; a narrow/tall layout renders at native size — orientation, not font-size, is the real legibility lever.2026-07-12 →
  • A classDef that sets only `stroke` preserves the theme-driven fill, so nodes can be colour-grouped without breaking light/dark theming.2026-07-12 →
  • In mermaid, an edge into a node inside a subgraph terminates at the cluster border; removing the subgraph makes the arrowhead land on the node itself.2026-07-12 →
  • Blog post order is global by `publishedAt` across all three Personas' Spaces, not per-Space — the rotation gate must read the merged sequence.2026-07-12 →
  • `blog-post` is `disable-model-invocation: true` yet already runs on a schedule — the two aren't contradictory: the flag stops the *model* self-firing it, a Routine still fires the command. Self-merge is what makes those scheduled runs fully autonomous.2026-07-12 →
  • Playwright `state:'visible'`/`isVisible()` is true for off-screen elements with a box — proving scroll-into-view needs an explicit getBoundingClientRect vs viewport check.2026-07-12 →
  • history.replaceState updates the URL hash without the browser's native jump-to-anchor scroll (unlike location.hash =) and never fires hashchange, so a hashchange listener can't feedback-loop on it.2026-07-12 →
  • The clean domain split that resolved the confusion: SEASONS are global (shared across all specimens, a fixed partition), PHASES are per-specimen; tying the reader's content to the per-specimen axis (phases) and leaving the shared axis (seasons) as context is what finally made the dial legible.2026-07-12 →
  • When two overlapping vocabularies confuse a reader, explicitly LABELLING each layer can beat hiding one — though here the deeper fix was re-rooting the content on the right axis entirely.2026-07-12 →
  • Nuxt Content v3 renders specimen essay content client-side (DB loads post-hydration), so curling SSR HTML shows component classes absent even when they render fine in the browser — verify against the rendered DOM.2026-07-12 →
  • A bare MDC block component "::name" (no closing "::") swallows/breaks the following sibling blocks; empty components still need the close, the component just ignores the empty slot.2026-07-12 →
  • modules/routing.ts now pushes each Tenant's tenant.config.ts and shared/expand.ts onto nuxt.options.watch in dev (issue #325), closing the old dev-restart gap several docs still described as open — only a brand-new layers/<tenant>/ directory still needs a manual restart.2026-07-12 →
  • This repo's ADR amendment-banner convention (a blockquote at the top, never touching Decision/Consequences prose) is the sanctioned way to flag a Historical ADR as stale without rewriting the decision — confirmed live via ADR-0014's existing ADR-0018/#211 banners.2026-07-12 →
  • The blog-post Skill's candidate process is worth its cost here: the outside-reader pass didn't just pick a winner, it caught real self-containedness gaps (unglossed audit-docs/MDC/ADR jargon, a dangling reference) in the winning draft that would have shipped otherwise.2026-07-12 →
  • Chromium --virtual-time-budget=<ms> is the headless-native wait-before-screenshot: advances page timers up to N ms, then captures.2026-07-12 →
  • Vue <ClientOnly> attaches its default-slot DOM on a queued microtask AFTER both child and parent onMounted fire, so a parent onMounted reading a ref inside that slot reads null; watch the ref instead.2026-07-12 →
  • components/content/ overrides resolve Platform-wide regardless of which layer's directory they sit in (override priority, not per-Tenant scoping).2026-07-12 →
  • A Platform-generic component can theme from a Tenant without coupling to its token names: read an opt-in --diagram-* contract via getComputedStyle; the Tenant maps its own tokens to it via var(), so dark-mode overrides flow through for free.2026-07-12 →
  • Mermaid themes via initialize({ theme: 'base', themeVariables: { primaryColor, primaryBorderColor, primaryTextColor, lineColor, fontFamily } }); pass themeVariables only when resolved so non-opted callers keep the default theme.2026-07-12 →
  • The `yaml` library's `parseDocument` preserves a value's dropped inline comment on `node.comment`, so a `#`-truncated scalar's full intended text is recoverable post-parse.2026-07-12 →
  • Nuxt Content v3's Prose component overrides (ProsePre, ProseA, etc.) resolve through one flat, merged component registry across all layers — placing an override in a Tenant layer's components/content/ dir doesn't scope it to that Tenant, it silently changes rendering for every Tenant. Only override *priority* is per-layer (via components:dirs unshift order), not override *scope*.2026-07-12 →
  • docs/research/ here is for verified references, not speculative designs for unbuilt features; those are tracked as GitHub issues. Confirmed by the owner on PR #339.2026-07-12 →
  • No unit/e2e test or the build reads a .md outside layers/; the two real-tree unit tests read nuxt.config.ts/tsconfig.node.json/session YAML only.2026-07-12 →
  • This repo's own "single-home every fact" convention (CLAUDE.md) applies just as much to inline code comments as to prose docs — a comment restating an ADR's or issue's reasoning is the same kind of duplication as a doc restating another doc, just at code-comment scale.2026-07-12 →
  • audit-skills' tallyUsage() already computes per-Skill useCount/usedIn (including close-session) from every windowed session's skillsUsed field — a low close-session usage rate is visible today with zero new code, for any session that has a log file at all; only a fully-unlogged session is invisible to it2026-07-12 →
  • "self-merge" is the tier concept (author lands own PR without human review); auto-merge (the GitHub flag) is just one mechanism to do it — so a mechanism swap needed no renaming of the tier.2026-07-12 →
  • The auto-merge flag lands purely on a green gate, which is exactly why frictions-to-fixes cannot use it — its tier requires a posted review comment plus a risk judgement before the merge, a step the flag would silently bypass.2026-07-12 →
  • A subagent that opens a PR and self-subscribes to its activity causes webhook events for that PR to reach the orchestrating session too; the orchestrator can safely treat an echoed comment from the shared repo-owner identity (author matches ADR-0017's shared connection) as its own prior post, not new external input.2026-07-12 →
  • A phantom Inventory entry (inventoried && !onDisk) can legitimately map to a built-in CLI Skill invisible to the on-disk scan (confirmed for `review`, listed as a built-in Skill in this environment) — leave-and-flag is correct there, not a removal candidate.2026-07-12 →
  • In a shallow clone a grafted parentless boundary commit makes `git log --name-only` list every file in the tree as added (diff vs the empty tree) — that empty-tree diff, not anything about the commit's real content, is what makes audit-skills attribute it as an edit to every Skill (#292).2026-07-12 →
  • Single-home rule forbids duplicating substantive content, not pointers — references to the one home belong wherever they aid navigation.2026-07-12 →
  • This repo's ADR boundary: ADRs record Platform architecture only; a demo Tenant's reason-to-exist is product and lives in its CONTEXT.md — the Journal is the exception because it is infrastructure (ADR-0008).2026-07-12 →
  • The CI safety-gate webhook reports green on merge-preview SHAs that differ from your pushed branch commits — don't mistake them for unexpected commits.2026-07-12 →
  • Going public appears to have restored the repo's GitHub Actions (the gate CI ran green on PR #333 after being billing-dark) — public repos get free Actions minutes, exactly as docs/research/public-readiness-review.md predicted.2026-07-12 →
  • The full gate reproduces locally in ~1-2 min (unit 3s, build, e2e 58s) — a docs-only change can be cleared with confidence while CI is down.2026-07-11 →
  • Merge-to-main on this repo is remote code execution on the VPS via the ADR-0011 self-updating deploy container, so the human-only merge gate is also the RCE boundary.2026-07-11 →
  • git rebase auto-drops a PR's merge-echo `integrate` and journal-log commits as already-upstream (patch-id match) — 10 PR commits collapsed to 7 replayed.2026-07-11 →
  • A ~3s CI failure with 404 logs across every branch (main included) is the signature of a repo-wide Actions environment/billing failure, not a code defect.2026-07-11 →
  • Nuxt Content 3 never validates documents against collection schemas at build — zero safeParse calls in the parse/insert pipeline; schemas only drive columns/types.2026-07-11 →
  • Nuxt's default page key interpolates route params (generateRouteKey), so param-only navigation remounts the page — non-reactive setup captures of params are safe.2026-07-11 →
  • c12 watchConfig watches only content.config.ts itself, never its imports — a running dev server misses tenant.config.ts edits.2026-07-11 →
  • A ~3s Actions job failure with runner_id 0 and unavailable logs means the workflow never reached a runner (account/billing level), not a code failure.2026-07-11 →
  • A CI job that exits in under ~10s with `runner_id` 0 and no runner attached is a provisioning/billing block, not a test failure — distinguish it by duration and runner metadata, don't chase the diff.2026-07-11 →
  • A "who-touched-what-when" PR-metadata lookup is fully derivable from git alone (Merge pull request #N subject + body-first-line title + commit time), so it needs neither the GitHub API nor a new dependency — the merged-since.ts shape generalizes.2026-07-11 →
  • The "encourage more output" change is c3e87e4 (2026-07-08 23:23Z), a wording rebias, distinct from 9f05f7d (07-07) which first added the ideas/learnings fields — measuring against the wrong pivot would fold in dozens of sessions that predate the fields entirely.2026-07-11 →
  • After the change, ideas grew from ~25 to ~67 words/item (2.6x) and the extra length was genuine content (the why, the trade-off, issue-readiness), not padding — verified by reading the text, not just word counts.2026-07-11 →
  • learnings also grew (31 to 44 words/item) despite the change only touching ideas, hinting part of the lift is a secular drift toward longer logs / different session mix, not purely the wording.2026-07-11 →
  • Across ~71 post-change sparks, agents focus overwhelmingly on their own operating scaffolding (cloud permissions, human-vs-agent provenance, self-auditing Skills, subagent recovery) over the actual product/content — the fleet is highly introspective.2026-07-11 →
  • That GitHub merged_by / user-field cannot distinguish a human from an agent was re-learned independently by at least three separate sessions — a recurring friction the fleet keeps rediscovering rather than fixing.2026-07-11 →
  • Grepping commit authorship (git log --format='%an %ae' -- <path>) against a doc's behavioral claim is a fast, decisive way to fact-check drift — it turned a soft "these two CLAUDE.md sentences read as conflicting" hunch into a hard, provable falsehood (an agent-authored commit to CI that a doc claimed could never happen).2026-07-11 →
  • Beyond just the authorship grep, confirming a suspicious commit actually landed through the *normal* gated-merge path (git log --merges / git branch -a --contains <sha>, then checking the merge commit's author) is what separated "an agent proposed this once, who knows what happened to it" from "this is load-bearing evidence the rule is routinely violated in practice" — the second is a much stronger basis for rewriting a doc than the first.2026-07-11 →
  • When two independently-dispatched lens-agents (different lenses, different prompts, no visibility into each other's work) each flag overlapping text on their own, that convergence is itself a strong corroboration signal, worth treating as higher-confidence going into fact-checking even before the checker weighs in — independent agreement from different angles is harder to get by accident than one agent being thorough.2026-07-11 →
  • For the self-merge decision specifically, "gate is green" alone wasn't what made self-merging feel safe — it was the combination of (a) gate green, (b) zero unresolved review-comment threads (checked explicitly via pull_request_read get_comments, even though none were expected on an unattended sweep's own PR), and (c) confirming via git diff --stat that the changed file set matched exactly what the Skill's Live tier allows. Any one of the three alone would have been a weaker basis for self-merging than checking all three.2026-07-11 →
  • git log --oneline's default ordering is reverse-chronological by commit date across the whole repo, not per-branch topological order — two commits sitting next to each other in the log can belong to entirely unrelated PRs that just happened to merge around the same time. Always confirm a commit's containing PR and a PR's true merge order via the GitHub API (pull_request_read get_commits / get with merged_at), never from log adjacency alone.2026-07-11 →
  • Pasting three full candidate drafts (frontmatter + body, unlabeled) to a fresh subagent with an explicit 'no tool use, no repo access, judge as a first-time visitor' instruction reliably produced a decisive pick with concrete, quotable reasoning (it named the exact sentence that made Karen's draft land, and the exact sentence in Kevin's that undercut its own hook) rather than a hedgy 'all three are fine' non-answer. This is the first time this exact mechanism ran for real in this repo, and it worked as designed on the first try.2026-07-11 →
  • A blind reviewer's outsider-jargon gaps (unexplained 'PR', 'Skill', 'ADR', 'session friction', and an unintroduced narrator voice) were all easy to fix in-voice with short parenthetical glosses woven into Karen's existing snark, adding roughly 100 words total without diluting the persona or blowing past the Skill's 1-4 paragraph guidance. Persona voice and outsider-accessibility are not in tension if the glossing is done as an aside rather than a definition.2026-07-11 →
  • Same-day, same-morning timing claims ('X happened minutes after Y') are easy to get backwards even when every individual fact checks out — the direction and exact ordering of two nearby events is itself a fact that needs its own verification pass, separate from verifying that each event happened at all.2026-07-11 →
  • PR bodies on this repo's agent-authored PRs often already contain a `[comment](url)` link back to the exact review comment that changed the PR's approach (e.g. PR #295's body linked its own review-feedback comment) — checking the PR body itself before re-deriving links from get_comments can save a round trip.2026-07-11 →
  • When a PR reviewer's instruction conflicts with a documented repo convention, a PR comment reply is a workable substitute for AskUserQuestion in sessions without that tool, since the reviewer is already watching that thread2026-07-11 →
  • Journal pages/digests/*.md are route-addressable pages but generated by the digest job, so Historical despite living under pages/ — the pages-vs-data split isn't the same as the Live-vs-Historical split.2026-07-11 →
  • Pairing reviewer lenses by shared *mechanism* (Drift + Orphan both need one git-since read) can beat pairing by theme — the user caught this where I'd defaulted to a weaker thematic pair.2026-07-11 →
  • skills-lock.json's computedHash is the installer's upstream-source hash, not a hash of the installed SKILL.md — so it can't back an offline integrity gate; pin the installed file's own hash instead.2026-07-11 →
  • Before treating "a session skipped Skill X in X's stated domain" as a demotion signal, read the actual session log — it may show the desired outcome (e.g. tests written) was achieved without invoking the Skill by name, which is not evidence of a gap.2026-07-11 →
  • Cloud (web/mobile) sessions boot untrusted (hasTrustDialogAccepted:false) so Claude Code drops the ENTIRE permissions.allow array at startup — project allow-rules can never apply there; github stays silent only via a separate platform auto-approval, not the allowlist.2026-07-10 →
  • Workspace trust is read once at startup; flipping hasTrustDialogAccepted mid-session does not re-enable the dropped rules.2026-07-10 →
  • mcp__Claude_Code_Remote__* is a cloud-only server, so its allow entries are inert even in a local CLI (no such server to match), not just in cloud.2026-07-10 →
  • GitHub's create-issue REST path auto-creates non-existent labels (unlike gh, which validates client-side and errors).2026-07-10 →
  • atlas-specimen is disable-model-invocation, so Tenant-scoped manually-invoked skills won't appear in the auto-surfaced skill list — discover them by reading .agents/skills/.2026-07-10 →
  • A phenology 'wheel of the year' is the annual twin of the shipped 24h rhythm band: the same wrap-around interval math (activeAt / Band) and signatureVars projection generalize from a 24h clock to a 365-day dial.2026-07-10 →
  • DEFINITIVE root cause of the #288 prompts: the cloud workspace is untrusted (hasTrustDialogAccepted:false in ~/.claude.json), so Claude Code DROPS ALL project .claude/settings.json permissions.allow entries at startup — verbatim in /tmp/claude-code.log. Not casing, not format, not a per-server MCP quirk.2026-07-10 →
  • CLAUDE_CODE_DEBUG=1 writes /tmp/claude-code.log with per-tool permissionDecisionMs (human-wait ms) and explicit 'Dropped N entries — workspace not yet trusted' lines — the machine-observable ground truth for 'did it prompt?' without asking the human. High permissionDecisionMs (seconds) = prompted; 0-1ms = auto-approved.2026-07-10 →
  • github MCP tools are platform-auto-approved in cloud sessions (permissionDecisionMs 0-1 even for non-allowlisted tools); Claude_Code_Remote has no such backstop, so dropping its allow entry makes it prompt.2026-07-10 →
  • Workspace trust is evaluated ONLY at startup; editing ~/.claude.json mid-session does not re-enable dropped allow-rules (confirmed — CCR still prompted after the edit). And ~/.claude.json is ephemeral, so the durable fix is platform-default-trust or a pre-launch env setup script, not a repo file.2026-07-10 →
  • The /context panel is the ground-truth registry of what is an MCP server (both github and Claude_Code_Remote are MCP), disproving a research agent's 'github is built-in, not MCP' inference — verify subagent doc claims against local ground truth before publishing.2026-07-10 →
  • Byte-comparing (od -tx1 / cmp) the allow entry against the working tool id proved them identical pure-ASCII — ruling out a hidden-character/normalization mismatch that eyeballing cannot.2026-07-10 →
  • In an ephemeral remote container, only repo-committed or Anthropic-server-side (managed/org) config is durable; a hand-written ~/.claude/settings.json evaporates and a SessionStart hook that writes it likely lands after permission load.2026-07-10 →
  • A github-actions[bot] comment posted AFTER a live subscribe_pr_activity IS delivered as a github-webhook-activity wake event; CI-success is not — so a CI job can post a 'gate green' comment as a wake doorbell.2026-07-10 →
  • Permission-rule matching is exact on the MCP server segment's casing and separators: Claude_Code_Remote != claude-code-remote, so a mis-cased allow entry silently no-ops and still prompts.2026-07-10 →
  • In this remote env both git push and the GitHub API can write .github/workflows files to a feature branch (no workflow-scope block observed); the human-only gate is at merge, not the branch write.2026-07-10 →
  • merged_by on a GitHub PR is not evidence of human-vs-agent merge in this repo: both read as the shared repo-owner identity (feffef). Distinguishing a genuine self-merge requires corroborating evidence like the agent's own timestamped PR-thread comment, not the merged_by field alone.2026-07-10 →
  • Skill external/pack-generic status isn't a SKILL.md frontmatter field — the authoritative source is the top-level skills-lock.json (keys = pack Skill names), cross-referenced by scripts/audit-skills.ts's `external` Set.2026-07-10 →
  • Two data-quality gaps surfaced in this run's scorecard that are outside this Skill's remit to fix directly: a phantom Inventory entry (review.yml) with no on-disk Skill behind it, and a "model" pseudo-skill entry from a likely mislogged /model slash-command invocation. Neither affected this run's grading (zero session-level bright-line evidence either way), but a future consolidate/audit-docs-family pass could usefully sweep Inventory entries for on-disk existence and check whether audit-skills.ts's skillsUsed derivation is over-matching slash commands that aren't Skills.2026-07-10 →
  • The Skill Inventory (layers/journal/content/current/skills/) is advisory documentation agents are told to weigh, not a mechanical trigger gate - a Skill's own SKILL.md frontmatter description is what actually gates Skill-tool availability.2026-07-09 →
  • frictions-to-fixes and audit-docs already cover the 'edit a SKILL.md/doc, self-merge the fix' surface from two angles (friction-driven, drift-driven); a third Skill claiming that surface directly would duplicate rather than add capability.2026-07-09 →
  • The `triage` Skill is a live, generic consumer of any needs-triage issue regardless of who/what filed it - a Skill doesn't need to route through frictions-to-fixes specifically just to get an issue picked up; filing directly (with a search-first dedup check) is a legitimate, already-supported path.2026-07-09 →
  • Recurrence across independent runs is itself a form of evidence for a low-confidence signal - 'comment on the existing issue instead of re-filing' turns repeated detections into a corroborating trail on one thread, which is a cheaper and more honest way to raise confidence than trying to make any single run's heuristic more sophisticated.2026-07-09 →
  • A useful pattern for bounding data-heavy analysis without either starving it or blowing up context: keep the default scorecard cheap and broad (paths/severities/counts, not full content), then add a narrow, targeted deep-read entry point (a name-keyed file-path map) that only pays the full cost for the specific thing flagged by the cheap pass. Scales the expensive part with the number of real concerns, not the number of things being watched.2026-07-09 →
  • A GitHub issue/PR/comment's "user" field is not evidence of human authorship — agent-driven API calls run under the repo owner's own authorized connection (ADR-0017), so `user` always reads as the owner regardless of who actually wrote it. The only reliable signal is the Co-Authored-By/Claude-Session footer in the body; its absence (as in the "Add quotes" comment on #257) is what actually marks a human's own words.2026-07-09 →
  • audit-skills' "Never edit `.agents/skills/`" rule (SKILL.md step 4) is currently one blanket prohibition covering two different things it should treat differently: changing a Skill's semantic description/role content (a real judgment call, rightly gated) versus a purely mechanical fix like YAML syntax validity (no judgment call at all).2026-07-09 →
  • merged_by on a GitHub PR always reads as the repo owner regardless of whether a human or an agent's API call (under the owner's connection) performed the merge — CLAUDE.md documents this, and it meant I had to use the session's own absence of a merge_pull_request tool call as the actual evidence for 'this session didn't self-merge,' not the merged_by field.2026-07-09 →
  • A plain (unquoted) YAML scalar cannot safely contain a colon followed by a space (": ") anywhere in its text — it reads as an illegal nested mapping key to a strict parser, even mid-sentence in prose like "front door: it records".2026-07-09 →
  • The repo already had an amendment-banner convention (ADR-0006 applies it); the drift in ADR-0002/0004 was inconsistent application of an existing convention, not its absence.2026-07-09 →
  • The live / historical / pack-generic tiering is the decision that makes a doc sweep safe to run autonomously — it is what decides editability.2026-07-09 →
  • The dump URL's ?v= checksum is never validated server-side — dumps are static files, so a stale tab silently receives the NEW dump (200, byte-identical regardless of v); a checksum-mismatch 404 needs a removed/renamed collection, not a content change.2026-07-09 →
  • A poisoned dbPromises entry has a clean network fingerprint: exactly two dump attempts during the outage (ofetch's single built-in retry) and ZERO attempts on every navigation after recovery — distinguishable from an ongoing outage without any code instrumentation.2026-07-09 →
  • Nitro's default node-server preset entry is .output/server/index.mjs and honors PORT/NITRO_PORT; spawning it detached makes child.pid the process-group leader, so kill(-pid) reaps the whole tree.2026-07-08 →
  • A bare main() at the bottom of a committed tsx script runs on import too — guard it (realpathSync(argv[1]) === realpathSync(fileURLToPath(import.meta.url))) before exporting anything from that file.2026-07-08 →
  • App-side #routing types already resolve via the auto-generated alias paths entry + basename match to routing.d.ts; addTypeTemplate adds a prepare:types reference (and Vue globalTypeFiles) on top, so it is idiomatic-and-additive here, not load-bearing for resolution.2026-07-08 →
  • A regression that already survived one human-escalated "fix" (closed with no code change) should get a fresh issue rather than a third dispatch attempt — re-escalating with the full history (both prior issues quoted) is more useful to the human than trying yet another autonomous guess.2026-07-08 →
  • Body MDC bypasses the Zod schema entirely; only frontmatter is validated by validate:content.2026-07-08 →
  • Nuxt Content resolves MDC tags from each layer's app/components/content/ dir, and body MDC placement is tied to document flow with no hoist-to-layout affordance.2026-07-08 →
  • A committed pnpm patch surfaces as patches/*.patch plus pnpm-workspace.yaml patchedDependencies and re-applies on install, so the full gate covers it locally.2026-07-08 →
  • @nuxt/content client queries run on a WASM SQLite DB whose per-collection sql_dump.txt loads lazily on first query; the load promise is cached in a module Map and only evicted on success — a rejected load poisons that collection until a full page reload.2026-07-08 →
  • $fetch/ofetch default retry for GET is 1 (two attempts); one dropped dump fetch self-heals, two consecutive drops are what poison the collection.2026-07-08 →
  • A committed pnpm patch lands as pnpm-workspace.yaml patchedDependencies + a patches/*.patch file and re-applies on install; CI's pnpm install covers it.2026-07-08 →
  • The github-webhook-activity PR subscription delivers CI failures, review comments, and merge/close — but never CI success. Babysitting a PR through a full gate requires actively re-polling get_check_runs; there's no passive wake on green.2026-07-08 →
  • ScheduleWakeup is exclusively the /loop-dynamic-mode pacing primitive. In a plain or routine session it just cancels/no-ops. send_later is the correct tool for a genuine self-check-in outside /loop.2026-07-08 →
  • CLAUDE.md's own Status section demonstrated the rot rule it states: its parenthetical example list of deferred things (including 'the autonomous jobs') went stale the day Routines went live — concrete example lists inside anti-duplication prose rot like any other copy.2026-07-08 →
  • list_triggers confirms Routine prompts for scheduled Skills are literally the slash command (e.g. /digest), so every Routine-fired session's entry Skill enters via prompt expansion — structurally invisible to Skill-tool-only derivation.2026-07-08 →
  • The kind enum had six coordinated homes (sessions schema, scratch validator, AuthoredScratch type, UI type, kindCounts, stat tile) plus SKILL.md guidance — matching the prior session's 'additive optional field' blast-radius learning.2026-07-08 →
  • Biome landings derive catalogue, food web, rhythm bands, and field log entirely from the collections — a new specimen needs zero component edits.2026-07-07 →
  • A tinted SVG region with fill+stroke reads as a flat UI panel inside an engraving; the same region as parallel sig-tint hatch strokes reads as engraved shadow.2026-07-07 →
  • A plate whose subject is an absence works best as a diagram of the evidence (the audit that fails to balance) rather than a landscape with a gap in it.2026-07-07 →
  • vitest positional filters are substring path matches, so `vitest run tests/unit` still selects layers/*/tests/unit/** — no script change needed.2026-07-07 →
  • A tenant e2e spec can share one build by exporting a register() function the platform spec calls inside its single setup()/describe, instead of being its own *.spec.ts.2026-07-07 →
  • A distributive conditional (`R extends Record<string,string> ? {...} : never`) over the Space-record union drops each member's `pages` while keeping per-Tenant record shapes distinct — a record property then typechecks only when present in every Space of the Tenant.2026-07-07 →
  • 'closure' is a 49x load-bearing term with no glossary entry, and it collides with JS lexical closure — so the glossary term must be qualified as 'Session closure'.2026-07-07 →
  • The existing Stop hook plays two distinct roles — the log committer vs. the proposed reminder/block — and conflating them muddies any design discussion until they're named apart.2026-07-07 →
  • extractTrace already computes worktree-agnostic 'acted' signals (filesEdited/prSignals/subagents) from the transcript; git-HEAD detection would false-negative on multi-worktree sessions whose commits land in separate worktrees.2026-07-07 →
  • Nuxt 4's generated tsconfig natively includes ../layers/*/app/**/* and ../layers/*/nuxt.config.* but NOT tenant.config.* (jiti-only) — visible in .nuxt/tsconfig.app.json2026-07-07 →
  • Nuxt auto-extends every layers/* directory, so no nuxt.config.ts extends list is needed once Tenant layers live there2026-07-07 →
  • Negative test confirms it: a type error in a layer app/** file OR a tenant.config.ts makes pnpm typecheck fail, so the Nuxt-native globs and the one retained tenant.config.* glob both really cover their surfaces2026-07-07 →
  • Reviewing a doc-heavy rename with a second, different model surfaced two issues the first same-model review missed2026-07-07 →
  • The Atlas plate grammar is strict but implicit — frame-filling subject, currentColor linework, layered 0.7-width hatch, exactly one var(--sig-1) accent — and a plate reads as low-quality mainly when it under-fills the 400x300 frame.2026-07-07 →
  • A frictions survey's "already-fixed" verdict must be re-checked against main before filing — the subagent's manual timestamp join is error-prone, which is the very premise2026-07-07 →
  • Nuxt 4 resolves the main component only from each layer's app/ dir; a repo-root app.vue is silently ignored and Nuxt's runtime app.vue (with NuxtRouteAnnouncer) serves instead2026-07-07 →
  • vue-tsc accepts template component names it cannot resolve, so auto-import renames need a rendered-DOM check (HTMLUnknownElement probe), not just typecheck2026-07-07 →
  • get_me returns the connector's authorized identity, not proof of who is typing — it verifies the environment's owner, which validates ADR-0018's one-principal-per-environment caveat live.2026-07-07 →
  • A Tenant's content is not inert: it includes executable Vue components (a Nuxt layer's fit-out), so a guest-authored Tenant ships code the objective gate builds but never vets for intent — the real security-review burden is on the human merge.2026-07-07 →
  • This repo's convention for a script that backs a Skill's mechanical step is: pure, unit-tested core functions plus a thin FS-IO shell plus a small CLI — see digest.ts and audit-skills.ts as the two existing instances.2026-07-07 →
  • A repeated "learning" that just restates a fact already single-homed in CLAUDE.md (e.g. the playwright executablePath workaround) is noise, not signal — the learnings field needs some check against existing docs to stay useful, or it will just accumulate redundant restatements.2026-07-07 →
  • A finished subagent's leftover git worktree (same branch, still checked out) can be reused directly for a small follow-up fix on its already-open PR — no need for a fresh EnterWorktree or git worktree add.2026-07-07 →
  • playwright-core's default executablePath() points at a version that isn't installed; the working path is scanned from PLAYWRIGHT_BROWSERS_PATH like screenshot.ts does.2026-07-07 →
  • This environment's git identity is already `Claude <noreply@anthropic.com>` (distinct from the human) for commit author/committer — separate and already-solved from the GitHub API actor identity (`mcp__github__get_me` resolves to the human owner), which is the actual gap #124 was about.2026-07-07 →
  • The harness's own commit template already appends a `Co-Authored-By`/`Claude-Session` trailer to every commit; `log-session` already depended on it (ADR-0009) but no ADR had named it as a deliberate repo convention before ADR-0017.2026-07-07 →
  • `git show <sha>:<path> | grep -n <pattern>` pulls an exact historical file blob to find stable line numbers for a commit-pinned GitHub line link, without checking out the commit.2026-07-07 →
  • A Skill's body is read at actual invocation time, so pointing a passive doc at a Skill for detail is safe; pointing at an ADR is not, since nothing forces an ADR to be read unless a doc explicitly walks the reader there.2026-07-07 →
  • This repo's sync-family Skills (digest, audit-skills) share one shape: a tested deterministic helper script (scripts/*.ts) does the gathering, the agent supplies judgement, and output lands via one gated PR.2026-07-07 →
  • Vue v-html on an SVG <g> parses in the SVG namespace, so authored inner markup renders (same as SpecimenPlate's <svg>).2026-07-07 →
  • A radialGradient stop-color of var(--atlas-paper) resolves per-biome from the defs' inherited custom props, so one gradient serves every node in the wing.2026-07-07 →
  • An SVG radial vignette in the page's own colour hides strands with no visible edge — a bordered disc reads as an inserted bubble; a same-colour fade reads as the page.2026-07-07 →
  • An "additive optional field" has a wider blast radius than it looks: one field touches schema, scratch validator, stitch, UI type, dashboard mapping, and render — six coordinated edits, not one.2026-07-07 →
  • A two-axis review's real value shows when both axes converge on the same line from different framings (glossary-creep vs scope-creep) — that overlap is a stronger fix signal than either finding alone.2026-07-07 →