Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .claudinite/local/packs/canon-curation/item-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ The corpus is read read-only by every consuming repo, so a **duplicative** item
- **Distilled.** It is a single tight rule in the imperative, not a story, a log, or a restatement of a generic truism.
- **Portable — would a *future* project benefit?** Not "useful to every project today." An item can help only **one** project right now and still belong here, so long as another project — **especially one with a similar tech stack or process** — would benefit when it arrives. Being specific to a technology or a process is **not** disqualifying: generalize it and route it to that technology's or practice's home. What disqualifies is leaning on *this* project's non-transferable particulars — a product requirement, or a one-off incident in how it happened to call some API. The test, a genuinely hard one: *if another project with a similar tech stack came along, would it benefit from this?* Yes → portable; only-ever-this-product → local.
- **Durable and reusable.** It will still apply on a future, unseen task — not a one-off, not a situational detail, not something already implied by an existing rule.
- **Readable through the channel it lands in.** A rule whose premise is that the delivery channel
itself failed cannot be carried by that channel. Promote #497 admitted "the tell that the SessionStart
hook did not fire" as pack prose — and pack prose is what that hook delivers, so in the one situation
the rule describes it is not in context to be read. Detecting a channel's own failure belongs in code,
not in the payload the channel carries; reject such an item here rather than rewording it.
- **Not already covered.** The insight does not already exist **anywhere** in the corpus, even worded differently or owned by a different file. This is checked against the *entire* corpus, not just the file it would land in — see [Dedupe against the whole corpus](#dedupe-against-the-whole-corpus).

Reject on any miss — but the misses that matter are *undistilled*, *already-covered*, or *genuinely one-off*, not merely *narrow*. When you're torn over a real, non-duplicate rule, lean toward **keeping** it — the goal is a broad library. When you're torn over whether something is a duplicate, or a rule at all, leave it out. The failure to avoid is padding the canon with restatements of what's already there; admitting a narrow-but-reusable rule is not that failure.
Expand Down
17 changes: 17 additions & 0 deletions .claudinite/local/packs/claudinite/RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,23 @@ prose below).
`workflow_dispatch` run outside the slot's window succeeds, prints `- no tasks due`, and
does nothing. It looks like a healthy run. To exercise a task Action-side, invoke its
worker directly, or move the slot hour in `taskScheduler` and wait for the cron.
- **A scheduled task is gated twice — prove a change through `planRun`, never through its own
precondition.** `planRun` computes the due list *before* any precondition runs, so a task whose
most-recent slot has already been run is never evaluated and never reads its signals at all. #513's
forced-run override landed with every test driving the precondition (or the signal collector) directly
and was inert on exactly the run it existed for — the mid-day manual trigger — because the due-list
gate it never touched had already dropped the task (`evaluations: []`; fixed in #516). A test that
starts *inside* the gate proves only "works once evaluated" and says nothing about whether the task
ever gets there. Drive the real `planRun` from a deliberately **non-due** slot: that is the only shape
that catches it.
- **Every due task in a run shares ONE checkout — an agentless worker must not touch it.** The
scheduler runs the whole due list in a single working tree, so a worker that checks out a branch or
leaves an index behind hands the next task a tree it did not expect, and a run that dies leaves the
mess for whatever follows. A task whose output is a regenerated file lands it through
`engine/scheduler/deliver-generated.mjs` — git plumbing against the fetched base tip, with HEAD, the
index and the working tree untouched — and reads its prior state from that base rather than local
HEAD, so stacked runs stay idempotent. (`basics/baselining`'s own deliver is the deliberate
exception: it commits a whole working tree under the member's delivery preference.)
- **A code-search hit is evidence; a code-search miss is not — survey by reading each file.**
- **Derive the test file list from the tree — every hand-written glob here under-runs the suite.**
There is no `package.json` and no test script, so each session invents its own incantation and
Expand Down
Loading