fix: honor deferred_until and route guidelines by declared category - #264
Draft
jlevy wants to merge 1 commit into
Draft
fix: honor deferred_until and route guidelines by declared category#264jlevy wants to merge 1 commit into
jlevy wants to merge 1 commit into
Conversation
Three defects found by reviewing the open bug beads against the code. Each is verified live before the fix and pinned by a test that fails against the old behavior. deferred_until was recorded and then ignored (tbd-5av0). `tbd ready` offered a bead deferred to 2027 as available work today, so the field read as scheduling while scheduling nothing. readyIssueIds now treats a future deferral as the hold it already documents for `blocked` and `paused`. The cutoff is a parameter, not a clock read inside the filter: issue-changes.ts computes the set twice to diff two snapshots, and two reads could report a deferral that merely elapsed between them as a ready transition no edit caused. planMirror keeps its documented purity via an explicit readyAt. tbd list --defer-before was declared in the option table and help text but never read by any filter (tbd-v8lv), so it returned the same rows as no flag at all. It now filters, and an unusable date is rejected at the CLI boundary rather than degrading into a filter that matches everything — the same silent-no-op failure in a new place. parseDateOption moves to the shared validation helper so every date flag fails the same way. Guideline grouping matched filename prefixes while every bundled doc already declares a category, and doc-categories.ts calls name inference retired (tbd-dado). The two disagreed: electron- matched the TypeScript prefix while its siblings electrobun- and tauri- matched nothing and fell into the catch-all, where an agent looking for desktop guidance would not find them. Grouping now reads the declared field, the three frameworks share a heading, and a test asserts every declared category routes out of the catch-all so the next one added cannot land there unnoticed. release-notes-guidelines joins the cross-cutting group beside release-engineering-rules, which its own description tells the reader to load with it. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013eaEeT9CYT5TDyNGAw95t9
|
|
Overall Grade |
Security Reliability Complexity Hygiene |
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| Secrets | Aug 26, 2026 6:14p.m. | Review ↗ |
Important
AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.
Coverage Report for packages/tbd
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three defects from the open bug beads, each verified live against the code before
fixing and pinned by a test that fails against the old behavior. No release in this PR —
packages/tbd/package.jsonstays at0.8.1.tbd-5av0 —
deferred_untilwas recorded and then ignored--deferwrote the field andtbd readywent on offering the bead. Verified on the0.8.1 build before the fix: a bead deferred to
2027-01-01appeared intbd readytoday, so the field read as scheduling while scheduling nothing. The bead reports this
found during a real triage — 21 beads deferred to 2027 all stayed in
readyuntil eachwas separately set to
--status deferred.readyIssueIdsnow treats a future deferral as the hold it already documents forblockedandpaused. A deferral exactly atnowcounts as arrived.The cutoff is a parameter, not a
Date.now()read inside the filter.issue-changes.tscomputes this set twice to diff two snapshots; two independent clockreads could report a deferral that merely elapsed between them as a ready transition no
edit caused. That path now passes one instant to both calls.
planMirroris documentedas
Pure., so it takes an explicitreadyAtrather than quietly acquiring a clockdependency.
This changes readiness everywhere it is computed —
ready,web, and the Linearmirror — which is the point:
issue-query.tsexists so two surfaces answering the samequestion cannot disagree.
tbd-v8lv —
--defer-beforewas a silent no-opListOptionsdeclareddeferBeforeand the flag appeared in--help, but no filterever read it. Verified before the fix:
tbd list --defer-before 2020-01-01returned abead whose
deferred_untilwas 2027.It now filters. A bead with no
deferred_untilis not "deferred before" any date, so itis excluded whenever the flag is set, rather than treated as deferred since the
beginning of time.
An unusable date is now rejected at the CLI boundary instead of degrading into a
filter that matches everything — that would be the same silent-no-op failure in a new
place:
parseDateOptionmoves fromupdate.tsintocli/lib/issue-input-validation.tsso--due,--defer, and--defer-beforeall fail the same way.tbd-dado — guidelines routed by filename prefix, not declared category
Every bundled guideline declares a
category, anddoc-categories.tsstates plainlythat "the old name-based inference is retired in favor of the declared field." Grouping
was still matching name prefixes, and the two disagreed:
electron-app-development-patternsdesktopelectrobun-app-development-patternsdesktoptauri-app-development-patternsdesktopn.startsWith('electron-')is false forelectrobun-, andtauri-had no matcher atall — so an agent asked to work on a Tauri app would not find the guidance under any
framework heading. Tauri's core is Rust, so widening the TypeScript matcher would have
been wrong in the other direction.
Grouping now reads the declared field. The three frameworks share a Desktop app
frameworks heading, and the catch-all is left holding only genuinely miscellaneous
docs.
The regression guard is the general one, not a spot check: every declared category
with bundled documents must route out of the catch-all, so the next category added
cannot land there unnoticed — which is exactly how this shipped.
Also moved
release-notes-guidelinesinto the cross-cutting group besiderelease-engineering-rules, whose own description tells the reader to load the twotogether. Flagging it separately since the bead only called it "arguably" misfiled —
easy to drop if you disagree.
Verification
pnpm testpnpm lint:checkpnpm format:checkRed-green on all three: the 9 new assertions were confirmed failing against the old code
before any fix, reproducing each reported symptom. Then re-verified through the built
CLI end to end —
readyexcludes the deferred bead,--defer-beforefilters andrejects a bad date with exit 2.
Beads
Closes tbd-5av0, tbd-v8lv, tbd-dado. Separately verified tbd-az97 as already fixed
(a single-branch clone now discovers the remote sync branch, shares its history, and
converges) — not closed here since it is unrelated to this diff.
Left open deliberately: tbd-pht1 / tbd-iiys, which are live. An orphaned
data-sync.lockblocks every bead write andtbd doctorreports the repositoryhealthy; I reproduced a
tbd createhanging until killed. The 30-minutestaleMsis adeliberate safety contract (
lockfile.tssays so in as many words), so the fix isobservability — doctor flagging the lock, and the blocked command saying what it waits
on — not a timing change. Worth its own PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_013eaEeT9CYT5TDyNGAw95t9