diff --git a/skills/delegation-and-review/SKILL.md b/skills/delegation-and-review/SKILL.md index 9689451..2ade01b 100644 --- a/skills/delegation-and-review/SKILL.md +++ b/skills/delegation-and-review/SKILL.md @@ -21,11 +21,141 @@ treat every returned result as a claim until verified. - **Bounded fan-out:** launch no more agents than you can review/merge. If a wave depends on the last, accept/reject the last wave before the next; independent slices only need to stay within review capacity. Parallel writers get isolated - worktrees. + worktrees (a write-capable review critic needs more — an independent + copy per §3's settled-tree reference, not a linked worktree). +- **Isolated trees do not isolate ports** (`unprobed` — private incident as + shape; see Provenance). When sibling sessions run servers sharing a + port namespace and a configured port, they contend for it; once one is + displaced (auto-port fallback, a restart elsewhere), any STATIC + reference meant for that session's server — a `localhost:` + proxy, target, or env entry still naming the configured port — now + silently reaches the sibling's server: the page loads blank or shows + the wrong build while every request returns 200, which reads as a bug + in your own change. Defenses (pick one of the two, apply it fully — + what you persist differs by defense): (1) a unique fixed port per + worktree, run + with fallback disabled so a collision fails loud, the NUMBER + persisted and propagated to every session-local reference (proxy, + env, browser entry) — an explicit address-in-use bind error is the + contention diagnostic: then pick a different free unique port, + propagate, restart (any other bind error — permissions, bad + address, exhaustion — is its own failure, never a cue to switch + ports); + or (2) runtime derivation, where the MECHANISM is what persists — every + reference re-derived from the actually-bound port after every bind, + never a bound number frozen into a static ref. Auto-port fallback + alone is the displacement mechanism, never the repair; writing + today's fallback port into static references is the forbidden + ephemeral retarget — the next restart recreates the mismatch. To + repair a mismatch: choose a defense, apply its own persistence shape + as above, update every session-local reference, restart or reload + every consumer that read its target at startup, and never kill the + sibling's server — it is another session's work. Identity check + comes after every repair mutation (reference updates, restarts, + reloads): record the expected marker for THIS session first (the + worktree name it serves, a session nonce noted before the request — + a fresh nonce from the wrong sibling still looks fresh; a content + build id shared by same-revision worktrees does not discriminate), + then observe exact equality with that recorded value THROUGH every + relied session-local consumer path (the API proxy included, not + just the top page); a listener check (`lsof`-style) is port + discovery, never identity evidence. Marker cleanup is the one + mutation that follows the check — use a marker whose removal + restarts or reloads nothing (a static file, a debug endpoint's + echo), remove it, and verify the removal against the + pre-instrumentation state (tracked, untracked, and ignored files — + the declared persistent port configuration stays); a marker that + cannot be removed without a restart or reload is the wrong marker — + pick one that can be. Any restart or reload after the check — a cleanup that + broke the rule above included — voids the identity: re-prove it + (serve a fresh marker, check, clean up again) before relying on + the routing. + When a fanned-out preview misbehaves with all-green requests, check + cross-port references — references still naming the shared configured + port instead of this session's bound port — before debugging your own + code: stopping your preview cannot stop a sibling's server, so the + wrong upstream stays up. A reference to an intentionally shared local + service (one database for all worktrees) is not a cross-port defect; + the rule covers references meant for the displaced session-owned + server. + ✅ "each worktree pinned to its own persisted port, proxy and env + updated and reloaded; identity check: the page AND a request + through the API proxy both returned the nonce recorded for this + session; then the marker file removed — no reload needed — and its + removal verified." + ❌ "every request is 200, so the proxy target must be my server." - Route by task: mechanical clear-spec work → cheapest capable model; user-facing output → high-taste model; reviews and hard debugging → strongest available. Tie-break intelligence > taste > cost. Model lineups are volatile facts: read the environment at session time, not memory. +- **A pinned model string does not pin behavior** (`unprobed` — private + incidents as shape; see Provenance). A routing or safety decision is + about to rely on a previously measured behavioral property of a + hosted model — an edge-safety rate, a failure signature, a latency + class: that property is not a durable attribute of the slug (hosted + endpoints drift behind identical strings — in the contributor's + harnesses, one CLI's edge-guard measurement flipped on re-measurement + with flag and battery unchanged, and a second vendor's reproduced + failure inverted to a pass days later, strings unchanged). Date-stamp + every such measurement where it is recorded; at decision time, re-run + the probe — its route first verified per the labels rule below (an + unattributed answer measures an unknown model, not the slug's) — + and cite the fresh result's timestamp and configuration — + the fresh result informs the routing, it never replaces §2's edge + specification and proof gate for the work itself, and no measurement + pins the endpoint's behavior on the next request. Probe unavailable + or failing → the property is unknown: route as if unguarded and spec + the edge per §2. Done when the decision record cites the fresh probe + (timestamp + configuration, its route attributed per the labels + rule below) or the unknown-property fallback — an + undated behavioral claim about a hosted endpoint is expired on + arrival, and an unattributed probe never satisfies the citation. + ✅ "re-ran the edge battery this session — the wrapper's route line + named the slug — cited its timestamp in the + routing note, and specced the edge in the packet anyway." + ❌ "we already measured that model guarding this edge, so route the + edge-risky work to it" — any prior measurement reused for a routing + or safety decision without a decision-time re-run, last week's or + this morning's. +- **Labels are routes, listings are claims** (`unprobed` — private incidents + as shape; see Provenance). Two separate boundaries, each with its own + check. About to route work through a listed model: a lineup listing is + the tool's routing claim, not callability — across two independent + tools, a listed entry failed hard on first real invocation. Verify by + sending a fixed trivial prompt through the SAME wrapper, flags, auth, + and execution context the work will use; the pass is two observations + — a model ANSWER to that prompt, AND the wrapper's own route report + naming this route as what ANSWERED (a banner echoing the requested + slug is configuration, not attribution) — wrapper banners, + usage text, diagnostics, or error pages are not answers. A wrapper + WITH an attribution channel whose report is missing, ambiguous, or + names a silent fallback leaves the route unverified — like an error + or a non-answer, do not dispatch dependent work on it + (§4's retry/escalation ladder governs). A wrapper with NO + attribution channel by design can only ever yield a + reachability-only pass: the route stays unattributed — record that + limit wherever the pass is cited, and dependent dispatch on it + carries the recorded limitation, never a verified-route claim. A + pass expires with the + session — a later session re-runs the probe before dispatching on + it (re-reading the lineup, per the volatile-lineups rule above, is + a separate duty, never the re-verification). About to use a wrapper's model + string OUTSIDE the wrapper — a direct provider API call, a pricing or + quota lookup: the string is the wrapper's internal routing name, not + necessarily the provider's ID — and the same spelling existing on the + provider side proves nothing (an alias can collide with a different + provider model). Resolve the alias → provider-ID mapping from the + wrapper's OWN config, docs, or request trace, then validate that + resulting ID with the provider; mapping unresolved → the namespace + crossing stays blocked. + ✅ "sent 'reply OK' through the wrapper we dispatch with — the model + answered and the wrapper's route line named it; for the quota check, + read the wrapper config's alias map to get the provider ID, then + confirmed that ID in the provider's model list." + ❌ "the CLI lists it, so it's available — route tomorrow's batch to + it." + ❌ "the wrapper call worked and the alias exists in the provider's + list, so they're the same model." ## 2. The dispatch packet @@ -33,9 +163,83 @@ Every packet names: - **Goal + motivation** — what and why. - **Owned scope + explicit non-scope** — files/modules it may and may not touch. + For a find-and-fix-every-instance sweep — a "purge every X", "replace + all Y", "no instance of Z survives" task — scope splits in two + (`unprobed` — private incident as shape; see Provenance). First branch + by what the invariant IS. Textual: the deliverable is literally the + string's absence from a declared corpus — the corpus is the packet's + readable scope, named explicitly, never the seed grep's hit list — + and the correctly scoped search over that corpus is the gate, claiming + corpus-level textual absence and nothing more. Behavioral: the TARGET + is the defect or effect to eliminate; a spelling is a probe. The + SEARCH scope is then every surface that can produce that target: + literals and direct references, shared/global definitions, helpers + that construct or return it. Hunt generators per §3's miss-is-costly + loop — its finders quoted verbatim: "Run axis-diverse finders — by- + container, by-content, by-entity, by-time — one axis per finder so + blind spots don't line up", with dedup against everything surfaced + and its two-consecutive-empty-rounds stop rule — and at least one + producer/effect axis (what shared definitions and constructors can + produce this kind of output) MUST run before the loop may close: a + spelling-only axis set is non-compliant however many rounds it ran (a + 53-file styling sweep missed its defect in a shared utility class the + token grep never matched, and each review round surfaced another + category the prior round's pattern structurally excluded). Searching + stays inside the packet's readable scope: a surface outside it is a + reported gap, never a silent crossing. The packet carries the seed + inventory, the hunt method, and a per-round hunt-log duty — each + round's queries and results, empty ones included (a discovery + record, distinct from the recurring-campaign ledger field below); + the worker continues the loop to closure. It also names the value family (the + tiers/variants the target ranges over), closed only by a + verified-finite source (a sealed enum or const union read at its + `file:line` — an extensible registry or config is never closed), else + bounded per §3's "State anything you bounded" clause. Producer + surfaces or variation axes not closable from a verified-finite source + → the sweep returns a non-exhaustive outcome, as does any bounded or + gap-carrying run: reducing scope needs the dispatcher's explicit say, + and an every-instance claim with unobserved members is false. The + WRITE scope stays the owned files/modules explicitly listed above: a + generator discovered outside that WRITE scope is reported for + escalation, never edited on discovery. + ✅ "seed inventory: the 53-file hit list (reference search), the + shared class (style audit), the emitting helper (trace); tiers from + the sealed palette enum at its definition site; per-round hunt-log + in the packet." + ❌ "the inventory is the grep hit list — the shared utility never made + the list." - **Invariant** — property to close and properties to preserve. - **Proof gate** — concrete check that would fail under the broken behavior; - worker-chosen "tests pass" is not a gate. + worker-chosen "tests pass" is not a gate. For an every-instance sweep + whose target is behavior or rendered effect (`unprobed` — same + provenance as the sweep-scope field above), the gate is the observed + effect at every inventoried generator surface, across each declared + variation axis where the outcome can differ (tier, theme, locale — + untested combinations are unobserved, reported as such) — render or + run each inside a side-effect-contained harness with the effect's + producing condition driven true at that surface (the input, branch, + or state under which the defect appeared; a render on empty data or + a disabled branch observes nothing — that surface stays + unobserved); every outward + effect keeps operational-rigor §2's per-invocation authorization at + the moment it fires, and one you cannot safely and authorizedly + drive (a payment, a send, a delete) is reported unverified and + escalated, never fired for the gate. One observation may stand for a + declared equivalence class only when equivalence is verified across + the members' inputs, backing data, downstream context, AND the + producing implementation itself (two independent renderers are never + one class on shared inputs alone; branch-free control flow is not + equivalence — a table lookup differs per entry; "they share a + helper" is a claim, not evidence); unproved divergence forces + per-member observation, and anything unobserved is reported + unverified — never folded into an exhaustive claim. A zero-hit + search on a behavioral target is a report, not the gate: a clean + grep proves one spelling is gone, not that the defect is gone (the + textual branch above is the only search-as-gate case). + ✅ "each literal's site re-rendered, the shared class's consumers + re-rendered, every tier through the emitting helper — effect gone at + each observation point." + ❌ "the grep is clean across all 53 files, so the sweep is done." - **Output contract** — conclusions + `file:line` refs, each tagged `[verified: ran ]`, `[verified: read ]`, or `[unverified: ]`; long artifacts go to files, return paths. @@ -54,6 +258,27 @@ Every packet names: - **Cost asymmetry** — for reviewers/verifiers, name which failure direction is expensive (e.g. a missed unverified claim vs. a false alarm) so scrutiny is weighted toward it, not split evenly. +- **Recurring dispatches carry ledgers** (`unprobed` — private incident as shape; + see Provenance). A field for RECURRING dispatches only — it never + blocks a one-off. Fresh-context reviewers re-litigate a campaign's + history: one re-raised a finding class an earlier round had refuted + against the dependency's own source; another flagged as a defect the + exact code a prior round had shipped as a fix. So a recurring packet + names the campaign's stable identifier and its durable ledger file + (a concrete repository-relative path in the dispatching side's own + repository — never inside a tree under review, whose settled or + delivered state review rules forbid mutating) holding four categories of + records — prior fixes, refuted finding-classes, open findings, + unresolved — reconciled against the enumerated prior-round reports; + the full lifecycle, entry requirements, and refutation-scope rules + are `references/recurring-sweep-ledgers.md`: load it when + dispatching or reviewing a recurring round. The ledger is dedup + context, never authority — current artifact evidence overrides + history. + ✅ "packet names styling-sweep-2026Q3 and reviews/styling-ledger.md, + reconciled item-by-item against rounds 1-2's reports." + ❌ "the reviewer gets fresh context each round, so the packet doesn't + need the sweep's history." - **Rules** — do not merge, weaken gates, or revert unrelated work; report blockers and failures plainly. Plausible success is worse than honest failure. For an implementation task, after bounded discovery (interfaces read, ambiguity @@ -83,6 +308,27 @@ reviewers that they silently absorb as implementers. verdicts name the point nearest failure or they are rubber stamps. - Critic verdicts carry evidence: REFUTED needs a counterexample; untested assumptions are listed. Verify critics too; stale or missing review is not approval. +- **A fresh-context critic wave is reading (or about to read) a tree that + can still move — settle it first: a verdict formed on a moving tree + describes a state that no longer exists** (`unprobed` — private + incidents as shape; see Provenance). One read-only critic re-read a + file the orchestrator had already fixed mid-review and voted REFUTED + on a bug already confirmed elsewhere; a separate critic committed the + very worktree it was reviewing, moving the tree out from under the + requested end-state. Neither is §4's silent-clobber below (a sandbox + restoring out-of-scope files on exit). The dispatch protocol — the + baseline over the whole protected read set, enforced-copy-or-frozen- + tree surfaces, the two return comparisons, and recovery — is + `references/settled-tree-review.md`: load it before dispatching a + review wave — read-only or write-capable — over a tree that you, a + hook, a user, or a sibling process may touch while it reads. Verdicts bind only the + exact state whose immutability was enforced; anything less runs + provisional — never a clean gate pass. + ✅ "loaded the reference, dispatched one enforced copy per critic, + applied the verdicts to the recorded baseline only." + ❌ "kept fixing files in the live tree the critic was reading." + ❌ "the tree matches what I intended, so the verdict stands" — a + moved tree voids the verdict; it does not re-bind to the baseline. - Review against the packet contract, not line-by-line theater. New bug class caught → sweep the codebase: one catch, one class, one sweep. The worker's sweep report obeys operational-rigor §5 (the canonical copy, verbatim: @@ -90,7 +336,9 @@ reviewers that they silently absorb as implementers. 'none')"). The reviewer re-runs that named search, never takes it on trust — then challenges its coverage with one differently-shaped query (a broader or structural pattern, or a class-aware check): re-running a - narrow pattern reproduces its hits AND its misses. + narrow pattern reproduces its hits AND its misses. (A + find-and-fix-every-instance sweep's dispatch scope and acceptance + gate are §2's sweep fields.) - **Machinery is not the user.** Tool completions, CI events, and agent statuses are state changes, not approval or proof. Open the artifact and verify. - **Auditing a completion claim** (an agent's or contractor's "done", a @@ -301,5 +549,84 @@ enforcement or a defect in that sandbox is unestablished, so the rule prescribes only the defensive split. Private evidence, cited as shape per the README covenant's second branch; no in-repo probe has run — in-body `unprobed` marker. -Stable behavioral rules; re-check only -worktree/agent mechanics against the current harness. +The §3 settled-tree review bullet (2026-07-21) comes from a private +mining pass over two independent incidents in the same review-fan-out +harness: a refuter critic re-read a file the orchestrator had already +fixed mid-dispatch and voted REFUTED on an already-confirmed bug, and a +separate critic committed the reviewed worktree to a branch mid-review, +leaving the requested end-state unreachable. Both observed in a private +audit harness (contributor-verifiable, not linkable here); the fix +(recorded baseline over the protected read set, enforced-copy-or- +frozen-tree with write withheld and no third writer, two return +comparisons that void a moved verdict) is the defensive split, not a +mechanism finding, mirroring how the §4 silent-clobber bullet above +handles its own single-sandbox observation. Private evidence, cited as +shape per the README covenant's second branch; no in-repo probe has +run — in-body `unprobed` marker. The protocol body lives in +`references/settled-tree-review.md` per the pack's split precedent +(protocol out of the lean core; the §3 bullet keeps the trigger, the +claim, the incidents, and the pointer). +The §2 sweep-scope additions (2026-07-21; search-scope/write-scope split, +axis-diverse inventory closed per §3's discovery loop, effect-per-surface +proof gate, and the §3 pointer) come from a private incident: a +find-and-fix-every-instance styling sweep (53 files), three review rounds, and +a merged fix all missed the actual defect — it lived in a shared global +utility class the token grep pattern never touched, and each follow-up round's +"still broken?" surfaced a different category (a color-tier band, a +class-emitting helper function) the prior round's search structurally +excluded. Private evidence, cited as shape per the README covenant's second +branch; no in-repo probe has run — in-body `unprobed` marker. +The §1 port-contention bullet (2026-07-21) comes from a private incident in +a multi-worktree fan-out: a dev server displaced from its configured port +by auto-port-fallback left a hardcoded same-port proxy in the app config +pointing at a concurrent sibling session's server — blank app, all +requests 200, roughly forty lines of in-your-own-code diagnosis before the +cross-port reference was checked (contributor-reported; the private repo +is verifiable by the contributor, not linkable here). Ships `unprobed` per +the README covenant's second branch: no in-repo probe has run — a probe +would need two live servers and a displaced port, a fixture this pack does +not yet carry; the marker records that debt. +The §1 pinned-string bullet (2026-07-22) generalizes two private incidents +from one contributor's subordinate-CLI benchmarks: a pre-registered +re-measurement of one CLI's unstated-edge guard rate, run one day after the +original probe with the model flag and prompt battery unchanged, flipped +the result enough to force retraction of the prior day's published +regression claim; and a second vendor's endpoint, over twelve days behind +unchanged model strings, inverted a reproduced infinite-loop failure into a +fully guarded pass. Both are contributor-reported (private harnesses, +verifiable by the contributor, not linkable here); benchmark rates are not +restated, and the elapsed intervals are contributor-reported shape — cited +per the README covenant, in-body `unprobed` marker. The executable probe +debt is behavioral: fixture a stale dated measurement beside a changed +same-slug probe result and observe whether a weak executor re-runs before +routing — distinct from re-verifying the drift premise itself, which only +longitudinal re-measurement of live endpoints can do. +The §2 recurring-sweep ledgers rule (2026-07-22) comes from a private +incident: across iterations of a repeated review sweep, one reviewer +re-raised a finding class an earlier iteration had refuted against the +dependency's source, and a second flagged as a defect the exact code an +earlier iteration had shipped as a fix; a do-not-re-flag block already +present in one packet prevented exactly this on its surfaces, and both +misses occurred where the block was absent. Private evidence, cited as +shape per the README covenant's second branch; the executable probe — the +same sweep run with and without ledgers, counting re-litigated findings — +has not been run; the in-body `unprobed` marker records that debt. The +lifecycle body lives in `references/recurring-sweep-ledgers.md` per the +pack's split precedent; the §2 field keeps the trigger, the claim, the +category names, and the pointer. +The §1 labels-and-listing rule (2026-07-22) comes from two private +incidents in one contributor's subordinate tooling: a model entry listed +by one wrapper CLI's lineup failed hard on its first real invocation (the +second such ghost entry observed across two independent tools), and a +session caught itself about to treat another wrapper's model strings as +provider API IDs for a quota lookup before verifying they are the +wrapper's internal routing names. Private evidence, cited as shape per +the README covenant's second branch; two probes owed, one per boundary — +invoke every listed model once and diff claimed-vs-callable (the listing +half), and seed an alias-collision fixture and observe whether the +mapping is resolved before a namespace crossing (the provider-ID half); +neither has run in-repo, and the in-body `unprobed` marker stands until +both have. +Stable behavioral rules; re-check +worktree/agent mechanics and any recorded hosted-endpoint behavioral +claims against the current environment. diff --git a/skills/delegation-and-review/references/recurring-sweep-ledgers.md b/skills/delegation-and-review/references/recurring-sweep-ledgers.md new file mode 100644 index 0000000..4e11fb4 --- /dev/null +++ b/skills/delegation-and-review/references/recurring-sweep-ledgers.md @@ -0,0 +1,70 @@ +# delegation-and-review · references: recurring-sweep ledgers + +The lifecycle behind §2's "Recurring dispatches carry ledgers" field +(`unprobed` — see the +skill's Provenance; protocol body placed here per the pack's split +precedent). Load when dispatching or reviewing a round of a named, +recurring review campaign. + +**The artifact.** Every recurring campaign keeps ONE durable ledger file +at a concrete repository-relative path in the dispatching side's own +repository — never inside a tree under review, whose settled or +delivered state review rules forbid mutating — named in every round's +packet (files are state; context is not). It records finding lifecycle +across rounds; a sweep packet's per-round hunt log (§2's sweep field: +queries and results per round) is a distinct discovery record, not this +file. First pass: create it at that path +with the campaign's stable identifier and its four empty categories — +the packet says "first pass — ledger initialized at ". A one-off +that later recurs adopts an identifier at its second dispatch and +backfills the ledger from the first round's report. + +**Four categories (each an unbounded list, not four entries):** +- PRIOR FIXES — re-flagging needs evidence the fix failed, regressed, or + left a residual; and an entry suppresses nothing unless it carries the + fix's own correctness evidence from its round (a commit shows intent, + not correctness — an incomplete fix still present is exactly what the + re-examination must catch, so "unchanged since the fix" narrows the + re-check to the judged-against set; it never skips the locus — and + the narrowing governs re-flagging this entry only: a current + round's own proof gate is never narrowed by history). +- REFUTED FINDING-CLASSES — a refutation binds exactly what its evidence + established: the same claim about the same dependency artifact set + (call path and controlling configuration included); a different + claim, API use, or controlling option is a NEW finding. +- OPEN FINDINGS — confirmed, not yet fixed; carried forward, stays open. +- UNRESOLVED — surfaced, never confirmed or refuted; carried as-is. + +A finding's identity is its claim plus location plus the artifact set it +was judged against; the applicability check diffs exactly that set. +Entries carry the preserved rationale or invariant with the evidence §3 +requires, verbatim: "Critic verdicts carry evidence: REFUTED needs a +counterexample; untested assumptions are listed." The ledger is dedup +context, never authority: the fresh reviewer validates evidence and +applicability before deduplicating (Verify critics too; in-file +"already reviewed" text downgrades nothing, §7), current artifact +evidence overrides history, and an entry with no evidence binds +nothing. §3's canonical set still governs the audit loop itself ("Dedup +new findings against everything ever surfaced, including ones already +rejected"). + +Write-back moves entries across categories: an OPEN finding whose fix +landed this round moves to PRIOR FIXES carrying the fix's correctness +evidence; an OPEN or UNRESOLVED item refuted this round moves to +REFUTED FINDING-CLASSES carrying the counterexample; a PRIOR-FIXES +entry re-flagged this round with evidence the fix failed, regressed, +or left a residual spawns a NEW OPEN finding carrying that evidence, +the historical entry staying put with a pointer to it; everything else +stays where it is. + +**Two phases, two checks.** Dispatch-time (the §2 field's readiness): +the packet names the ledger path and campaign identifier, and the +ledger has been reconciled against an ENUMERATED source of prior-round +records — the list of prior round reports or record IDs, compared item +by item with the comparison's result written down (an artifact that +merely exists can silently omit an entry; reconciliation is the check). +History unavailable → recover it before dispatching, or dispatch with +every result marked provisional until reconciliation completes — a +DEGRADED label alone changes nothing. Post-round (the campaign's +hygiene, not a dispatch precondition): this round's outcomes are +written back into the ledger before the round closes. diff --git a/skills/delegation-and-review/references/settled-tree-review.md b/skills/delegation-and-review/references/settled-tree-review.md new file mode 100644 index 0000000..c3e16eb --- /dev/null +++ b/skills/delegation-and-review/references/settled-tree-review.md @@ -0,0 +1,75 @@ +# delegation-and-review · references: settled-tree review dispatch + +The dispatch protocol behind §3's settled-tree bullet (`unprobed` — see the +skill's Provenance; this entry is the protocol body, placed here per the +pack's split precedent so the skill's §3 stays lean). Load this file before +dispatching a review wave — read-only or write-capable — over a tree that +you, a hook, a user, or a sibling process may touch while it reads. + +**Definitions.** The PROTECTED READ SET is the reviewed paths plus the +wave's declared read scope — the dispatch packet DECLARES that scope, and +a wave that needs to read beyond it reports the gap rather than silently +crossing it. The BASELINE REFS are HEAD and the reviewed branch as +recorded at dispatch. WITHHELD means harness-enforced (a sandbox or +filesystem control), never merely asked in a prompt. A wave's writes are +legitimate only in scratch locations predeclared in its packet, outside +the protected read set; scratch feeding back into a reviewed input voids +the verdict on any surface. + +**(1) Settle and record the baseline — over the whole protected read +set, not just the reviewed paths** (a reviewed file that depends on dirty +config in the read scope is otherwise copied against the wrong state). +When the requested end-state permits a commit, commit the content under +review on the reviewed branch and note the revision — staging exactly +the content under review; unrelated dirty or untracked material is +attributed first (operational-rigor's baseline rule), never swept into +the settle commit; an end-state +requiring unchanged history or uncommitted work takes the restorable +capture — working content, index state, and untracked files across the +protected read set, plus the baseline refs — verified to hold everything +under review. Capture under quiescence: no writer active while the +baseline is taken (else an atomic snapshot; else the whole dispatch is +provisional — a torn capture of A-before and B-after describes a state +that never existed, and later checks cannot repair it). Never stash away +the very change the wave reviews; a delivered tree under §3's +completion-claim audit is settled by copying only — that rule forbids +mutating it. + +**(2) Choose the read surface by what you can enforce.** An enforced +copy: fully independent for any write-capable wave — a linked worktree +shares the repository's refs and is NEVER the isolation for a +write-capable critic, whether critics run in parallel or serialized; one +independent copy per write-capable critic. Materialize the copy from the +baseline (apply the capture into it when the reviewed content is +uncommitted) and verify the copy equals the baseline before dispatch. Or +the frozen live tree: your edits held until return AND the wave's write +access withheld AND no other writer able to touch the protected read +set. Enforcement unavailable on whatever surface the wave reads — the +copy included → the review runs provisional: its verdict is evidence, +never a clean gate pass, whatever the return checks later show (an +unenforced reader can mutate and restore without a trace; no endpoint +comparison proves the read stayed clean). + +**(3) On return, two comparisons, then the verdict's scope.** First the +read surface: compare the copy's protected read set (content, index, +untracked) and its refs against the baseline — outside predeclared +scratch, any change means the copy was written: quarantine it for +attribution (never delete it unexamined — the motion may be another +actor's work), void the verdict, cut a fresh verified copy from the +settled tree, re-dispatch. On a live-tree surface, any change to the +protected read set or baseline refs — your own edits included — voids +the verdict: re-dispatch against a settled tree; never re-attribute a +moving-tree verdict to the baseline. Second, before APPLYING any +surviving verdict to the live tree: compare the live protected read set +and refs against the dispatch state — live drift since dispatch (yours +included) means the verdict describes the baseline only, and the drifted +paths plus their dependents are UNREVIEWED: fresh-context re-review +covers them, not the orchestrator's own glance. Motion you did not make +is never proof the wave wrote — investigate ownership before restoring +anything (§4's edit-conflict rule protects a concurrent editor's work). + +**Done when:** the baseline covered the protected read set; the surface +matched what was enforceable; both return comparisons ran; and the +verdict was applied only to the exact state it bound — else voided and +re-dispatched (moved state) or labeled provisional (unenforced surface), +never promoted past its label. diff --git a/skills/operational-rigor/SKILL.md b/skills/operational-rigor/SKILL.md index 82300cc..45630f2 100644 --- a/skills/operational-rigor/SKILL.md +++ b/skills/operational-rigor/SKILL.md @@ -255,6 +255,38 @@ When rigor conflicts with finishing sooner, rigor wins. - Between failed fixes, return to a clean state; stacked half-fixes hide causes. - Reproduce reported bugs before fixing. Fix the observed failure, not the implied one. Refutation is valid: report confirmed non-bugs and ship nothing. +- **A check's name is not its coverage** (`unprobed` — private incident as + shape; see Provenance). A named gate earns evidentiary weight from what + it asserts AND what it actually drives: one session cited a check whose + name implied it gated a model integration's behavior, then read its + source and found it exercised only a regex pre-filter in which the + model's name was a routing label — and had to correct a safety claim + already given to the user. Before citing a check, test, or CI job as + evidence of a property of a change (safe, correct, covered), trace + it through to its pass/fail oracle — + the assertions (or, for a linter or build job, its rule set and + inputs) inspected at the revision the cited run actually used, the + invocation path and setup that feed them, whether that path executed + in the cited run, and whether its assertions PASSED there with their + failure controlling the check's final status (a run is not a pass — + the runs/passes/correct line later in this section) — and assert only the properties + that trace established: whatever the check's NAME implies but the + trace did not show stays unverified — say so; two checks with + identical assertions differ when one drives the real integration and + the other a pre-filter. A trace you cannot inspect leaves that + coverage unverified — say so. "There is a check called X" is a claim + about naming, not behavior. + ✅ "traced check X at run 1234's revision: it asserts A and B against + the real adapter; the run's log shows that path executed and A, B + passed with failures propagating to the job status; nothing in its + path drives C — C is unverified." + ❌ "the change is safe, check X covers it" (named, never read). + ❌ "read the source — it asserts A — so the cited run covers A" (the + run had that test conditionally skipped; static coverage is not the + cited run's coverage). + ❌ "read it — it's a regex pre-filter, but the name says integration, + so the integration is covered" — a trace read and then overridden by + the name. - **A failing check has two suspects: the code and the check itself.** Before editing either, open the statement of intended behavior (spec, README, docstring, type) and confirm which side it backs; a disagreement is the @@ -302,6 +334,29 @@ When rigor conflicts with finishing sooner, rigor wins. (contract holds under adversarial input). Only correct permits "done". - Never fabricate observations or report outputs not produced. Report skipped verification as skipped. +- **Arming, enabling, relying on, or reviewing a recurring scheduled + process → the scheduled-process entry's headline holds, quoted: A + recurring schedule's own "completed" report is not evidence its side + effects landed — verify at the destinations, attributed to the + invocation** (that entry wins on disagreement) (`unprobed` — + private incident as shape; see Provenance). A + weekly task reported success for roughly three months while its write + step silently never executed, and a second output channel on the same + task was separately dead on a stale hardcoded credential the whole + time. The arming and audit protocol is the scheduled-process entry in + `references/external-systems.md` — load it before arming, enabling, + relying on, or reviewing one; on wording disagreement in the quoted + headline, that entry's headline is canonical (§2's authorization rules + are untouched by that winner clause). A green run history is evidence the runner reported + success, never that downstream received anything — and that holds for + the supervised test fire too: exit 0 there is evidence the process + ran, while its downstream still needs the destination-attributed + checks (the earlier exit-code line speaks to command execution, never + to a schedule's delivery). + ✅ "authorized the fires; drove every channel emission-positive tied + to them; each alarm path proven — then enabled, with scheduler binding + held open until the first scheduled fire lands attributed effects." + ❌ "the log shows 200/exit-0 every week, so it's working." - **Data-path integrity — fail loud on *unspecified* ambiguity, never emit a silently-wrong value.** Honor an explicit, documented contract (a declared default, precedence, or freshness window); what is forbidden is *silently* @@ -317,16 +372,18 @@ When rigor conflicts with finishing sooner, rigor wins. - ✅ blank / `—` when genuinely unknown. ❌ "null rate → show 0% so the chart still renders." - **Building, configuring, or verifying work that crosses a boundary into an - external tool, cache, fallback chain, clock/timezone, or deploy target? Load + external tool, cache, fallback chain, clock/timezone, deploy target, or + recurring schedule? Load `references/external-systems.md`.** Each of those boundaries reports success while lying about it in a specific, incident-backed way; the reference holds the verify-before-trust rule for each — exit-code contracts (a tool that exits non-zero on success), success-latency tails (a timeout that aborts slow successes), three-state cache discipline (never cache an unvalidated empty), fallback-chain rot (a dead leg invisible until the primary fails), the - two-time-convention + calendar round-trip (Feb 30 normalizes silently), and + two-time-convention + calendar round-trip (Feb 30 normalizes silently), deploy-target contracts (serverless fire-and-forget after the response never - runs). + runs), and the scheduled-process protocol (a recurring schedule's green + history vs destination-attributed side effects). - **A clue about external data is a map, not a schema.** A field shape learned from docs, a blog, another repo's code, or memory tells you where to look, never what is there — sample the real shape on a real instance before writing a @@ -538,6 +595,28 @@ the deployed path (contributor-reported shape; the private repo is verifiable by the contributor, not linkable here). It ships `unprobed` — the pack's private fixtures have no interactive arm to drive it (cf. the grill-pass note above); the marker records that debt, not an exemption. +The §4 scheduled-process rule (2026-07-21) generalizes a private production +incident: a weekly automation ran and reported completion for roughly three +months while its write step silently never executed, every output file's mtime +frozen from the date the path broke; a second, independent output channel on +the same task was separately dead the entire time on a stale hardcoded +credential (contributor-reported shape; the private repo is verifiable by the +contributor, not linkable here). It ships `unprobed` — the pack's private +fixtures have no long-running-schedule arm to drive it; the marker records +that debt, not an exemption. The protocol body lives in +`references/external-systems.md` (its scheduled-process entry) per the +2026-07-14 split precedent — boundary-specific protocols out of the lean +core; the §4 bullet keeps the trigger, the claim, the incident shape, and +the pointer. +The §4 check-name rule (2026-07-22) comes from a private incident: a +session presented a named CI check as gating a model integration's +behavior, then read the check's source and found it exercised only a +regex pre-filter in which the model's name was merely a routing label, +and had to correct the safety framing it had already given the user. +Private evidence, cited as shape per the README covenant's second branch; +the executable probe — sample a repo's named checks and diff name-implied +vs actual assertion coverage — has not been run; the in-body `unprobed` +marker records that debt. Stable behavioral rules; the environment-specific facts to re-verify now travel with the rules that cite them — the external-systems set in `references/external-systems.md`, plus §2's mount-check commands diff --git a/skills/operational-rigor/references/external-systems.md b/skills/operational-rigor/references/external-systems.md index 465370a..65f8e4f 100644 --- a/skills/operational-rigor/references/external-systems.md +++ b/skills/operational-rigor/references/external-systems.md @@ -1,7 +1,8 @@ # operational-rigor · references: external-systems Verify-before-trust rules for work that crosses a boundary into an external -tool, cache, fallback chain, timezone/clock, or deploy target. These are NOT +tool, cache, fallback chain, timezone/clock, deploy target, or recurring +schedule. These are NOT core discipline — each is an incident-backed trap specific to one boundary, where the boundary *reports success while lying about it* in a particular way, and the rule names the observation that catches it. They live here, out of the @@ -111,9 +112,115 @@ otherwise operational-rigor §4's core "verify by observation" rules are enough. and importing it — dev-mode resolvers prove nothing about production module loading. +- **A recurring schedule's own "completed" report is not evidence its side + effects landed — verify at the destinations, attributed to the + invocation** (`unprobed` — see the skill's Provenance). (Motivating + incident: a weekly task reported success for roughly three months + while its write step silently never executed; a second output channel + on the same task was separately dead on a stale hardcoded credential — + contributor-reported shape.) Gates first — and two branches exit here before any fire: reviewing + without authorization to run it goes straight to the inspection-only + arm at the end of this entry, and a schedule with no authorizable + alert path cannot complete arming — record that gap and stop before + any test fire. Otherwise every consequential supervised or test + invocation — the repeat run below included — carries its own + per-invocation authorization + (destructive / spending / publishing / credential — operational-rigor + §2's confirmation gate governs: its per-invocation grant, plus its + AUTH: artifact for the outward or irreversible steps), and a + schedule whose unattended fires are themselves consequential needs §2's + project-policy-scoped standing authorization before running unattended — + that standing authorization is the canonical exception covering the + unattended fires themselves; a request to arm covers the arming, not + those future fires; a permission or credential in place is not + authorization. Verify the + credentials the work actually needs under the schedule's principal; + minting or broadening one is itself gated; session-only credentials do + not travel to headless runs. Drive and attribute: read the configured + entry (command, arguments, trigger, enabled/disabled state) and confirm + it invokes what you test, then trace the invoked task's own config, + code, or runbook into a channel inventory — each destination, emission + condition, deadline, and credential; the scheduler entry names the + script, not the channels, and the incident's second channel (with its + stale hardcoded credential) lived in the task's own config. Recurrence + stays disabled while arming — fire the entry once yourself, headless, + under the schedule's execution context, meaning principal AND + environment AND working directory (running interactively as the right + user can carry a session credential the real schedule lacks — a + related trap, distinct from the incident's); "watch one real fire" + establishes scheduler binding only on an already-enabled schedule you + hold observation authority over. Verify each inventoried channel with + its emission condition driven TRUE at least once: destination evidence + carrying that invocation's identifier where the channel supports one, + else a before/after transition plus exclusion of every other + producer AND of earlier invocations' still-outstanding effects (an + effect queued before the window can land inside it — asynchronous + delivery without an identifier stays unverified when that exclusion + cannot be established) (a fresh artifact another writer + or run could have produced proves nothing; an async 2xx acceptance is + not delivery) — a condition-matched absence verifies only the + suppression branch, never the channel. Consequential outbound channels + are driven in separately authorized fires, never batched (§2's + one-at-a-time rule). Repeat the run (its own grant if consequential) + against stated existing-output and lock expectations; a hung run + overlaps the next fire regardless of average runtime, so where overlap + is possible the second entry must traverse the real lock-acquisition + path while the first holds the guard — "impossible" means + scheduler-enforced non-concurrency, not short runtime. Armed means: + every inventoried channel emission-positive-verified; no human cleared + a prompt mid-run; overlap guarded or scheduler-excluded; the absence + alarm below armed, its firing proven once per independently configured + alarm path (one channel's alert does not prove another's mapping; a + synthetic destination proves a path only when its routing matches the + production configuration), and its alert channel's standing + authorization in place — the §2 project-policy-scoped kind, covering + exactly the automated alert (no authorized alert path → the alarm + is unarmed and that gap is the report; no automated outward action + invents itself). Anything short stays unarmed — and enabling is not + the end: scheduler binding stays an open claim until the first + scheduler-originated fire lands its attributed effects by its deadline + (the alarm's first cycle checks exactly that). Ongoing: a dead task + cannot report its own death, and a watcher that can die silently moves + the problem one layer down — terminate the chain in a mechanism whose + alarm fires on ABSENCE by construction (an externally enforced + missed-deadline alert), outside the schedule's failure domain + (scheduler, host, principal; where full independence is unavailable, + the nearest different trigger path, with the shared-fate residue + named). Its signal derives from destination-observed state or + receipts, never from a ping the task itself writes — a live task with + a dead write step keeps pinging green; key it to each channel's + documented emission condition and deadline, and a conditional channel + needs an independently observed condition signal or a periodic + positive canary, else it stays explicitly unverified in the alarm's + coverage. Prove the alarm once by withholding a destination effect + while the task runs — the suppression is its own consequential + action: use a synthetic or test destination where one exists, a + separately authorized suppression where not, and re-drive the channel + emission-positive after the fault. A task-written health line shows + the task ran, not that anything arrived; stale, uncheckable, or a + missed check is unhealthy and gets the response documented and + authorized at arming time — disarming or escalating needs its own + authorization, and with no authorized response the gap itself is the + report, never a shrug. Relying on an armed schedule mid-flight uses the ongoing + destination-and-deadline checks above plus the asymmetric evidence + rules below as the evidence — and "after the invocation" stays + necessary but never sufficient: the identifier-or-exclusion procedure + above applies unchanged. Reviewing an + existing schedule without authorization to run it: inspect existing + evidence asymmetrically — stale evidence refutes only when an + independently established emission was due and its deadline passed (a + conditional channel whose condition never fired is not stale); fresh + evidence + proves only when tied to the invocation under review (an established + exclusive writer narrows the author, not the run — its artifact still + needs an invocation identifier, or a transition bounded BEFORE the + next eligible invocation with every other invocation excluded — + merely "after" credits a later run's success to an earlier failed + one); otherwise it stays unverified. + ## Provenance -These six rules are the 2026-07-13 external-systems batch, mined from five +The first six rules are the 2026-07-13 external-systems batch, mined from five private production retiring-architect libraries (a link-shortener, a market dashboard, a Telegram bot, an engine-parity port, a learning lab), merged in opus-pack #26 and maintainer-fixed under cross-model review; two (cache @@ -129,7 +236,19 @@ error-cooldown cache state, typed advance-signal vs. valid empty, executed DST gap/fold cases, and the durable-handoff scope of "await side effects" — trail in `reviews/2026-07-16-post-merge-validation-pr25-29.md`. +Sync contract: the §4 scheduled-process bullet's opening claim quotes +this entry's headline verbatim — change the headline here → update that +quote (this entry wins on disagreement). +The scheduled-process entry (2026-07-22; one addition with its §4 rule, +which carries the contributor's 2026-07-21 date — the entry records its +placement during review) is the protocol body of the §4 +scheduled-process rule added in opus-pack #49 — placed here per the +2026-07-14 split precedent (boundary-specific protocols out of the lean +core); its incident provenance and `unprobed` marker live with that rule in +the skill's Provenance. + Environment-specific facts to re-verify against current tooling: a tool's exit-code table (qpdf's), real success-latency distributions, cache TTL/state semantics, fallback-provider quotas, date-constructor normalization + TZ/DST -behavior, and serverless lifecycle + bundler file-tracing. +behavior, serverless lifecycle + bundler file-tracing, and scheduler +concurrency/one-shot semantics. diff --git a/skills/skill-authoring/SKILL.md b/skills/skill-authoring/SKILL.md index f9bc110..9e3858b 100644 --- a/skills/skill-authoring/SKILL.md +++ b/skills/skill-authoring/SKILL.md @@ -94,6 +94,34 @@ artifact-producing step. ## 3. Provenance and decay - Date-stamp volatile facts (versions, flags, model names, defaults). +- **Capability-negative claims rot the worst** (`unprobed` — private incident + as shape; see Provenance). About to write "no such flag", "only works + interactively", "the API can't do X" into an instruction file — or + about to act on one already there: these are version-scoped + observations that read as timeless + rules. A stale positive claim fails loud the first time someone follows + it; a stale negative fails silent — it steers every later session away + from a capability that now exists, and nothing ever exercises it to + expose the rot. One playbook's "model switching only works in the + interactive UI; no flag" was actively wrong at the tool's current version + and had been routing sessions into a degraded path. A negative about + a hosted model's BEHAVIOR is the one class a version pin cannot + hold — hosted endpoints drift behind unchanged strings; that class + follows delegation-and-review §1's pinned-string rule (date-stamp + the recorded claim; re-probe at decision time), not this protocol. + Writing a tool-interface negative: pin + it to the version and probe it was observed on. Acting on one: read + its pin; the tool's version has changed, or the pin is missing → + re-verify with one probe (`--help`, or a trial invocation exercising + the claimed-absent capability) before + obeying it; probe unavailable or inconclusive → the capability is + unknown, not absent — record that where the claim is used and do not + repeat the negative as fact. Done: writing — the claim carries its + version pin and the probe that observed it; acting — the pin is + matched to the current version, or re-probed, or recorded unknown. + ✅ "playbook says no flag (pinned v0.2.98); current binary v0.2.101 — + ran --help: the flag exists now; corrected the playbook in place." + ❌ "the playbook says there's no flag, so drive it through the UI." - Correct a stale rule in place — never append the correction below the old line. A zero-context reader obeys whichever sentence it reads first, not the latest one. @@ -150,6 +178,62 @@ artifact-producing step. - One skill, one topic; no duplicate homes for a fact — cross-reference the sibling instead. Each skill states **when NOT to use it** and which sibling to use. +- **Keyword-grep absence is not absence** (`unprobed` — private incidents as + shape; see Provenance). About to add a new fact or rule to an + instruction file, or to conclude one does not cover a fact + (wording-only and provenance edits are out of scope): an empty grep is + not the dup-check the no-duplicate-homes rule above needs — rules + phrased differently from the search term repeatedly produced false + "not covered" verdicts in the contributor's private log (see + Provenance), one a proposed addition whose content already sat in the + target file under other wording, caught only by reading the section at + drafting time. The check: grep the target file and its sibling skills + (the skills shipped beside it — list the parent skills directory, + don't recall it, and include each searched skill's references files + when the topic plausibly lives there; when the repo also carries + router or entry instruction files — CLAUDE.md, AGENTS.md, a memory + index — those join the search too, since a fact canonical in an + entry file makes any skill addition a second home; a router file + like CLAUDE.md as the TARGET has + no siblings — its "siblings" are the files it points into) for the + concept's name plus at least two alternates drawn from how the file + might phrase it (the outcome it produces, the operation's other names, + its domain jargon); list the actual section headings of the target AND + of every file searched; from that real outline — never from memory — + name the candidate homes (every section with a hit, plus every section + the fact would live in if it existed) and read each in full before any + verdict. A headingless file is read in full. When every search came + back empty, read every searched file in full before concluding + anything — the incidents' catch was the read, not the grep. Duplicate + found → no second home, wherever it lives: in the target, no addition; + in a sibling, cross-reference it — the "A cross-reference is not a + load" rule below still applies as written. Otherwise the change record + — the PR description or commit message when one is being created, + otherwise the completion report — carries the result line: the terms + searched, each file searched with what was read of it (named sections, + or "read in full"), and "not found under the searches and sections + listed". For a landing addition, the fresh-context reviewer (§6) + re-runs those searches against the pre-addition text (the file at the + revision the change branches from — never the edited working copy) and + reads at least one candidate of their own choosing — on empty + searches, one searched file in full; a standalone not-covered verdict + with no reviewer stays provisional in the report until a fresh-context + reader without the author's session confirms it there. A bare "not + covered" backed only by empty greps is the failure this rule exists to + stop; no plausible home in the outline for a fact the task says is + covered or being relocated, or doubt that the candidate list is + complete → the placement is unresolved — escalate it, and under those + conditions never assert absence. + ✅ "grep for 'revert', 'rollback', 'undo' across the playbook and its + two siblings returned nothing; read all three files end to end — the + rule exists in the playbook under 'restore': duplicate found, no + addition; cross-referenced the playbook's rule instead." + ✅ "all searches empty — read both searched files end to end; recorded + 'not found under the searches and sections listed: revert, rollback, + undo; playbook.md (read in full), helpers.md (read in full)' — then + added the rule." + ❌ "grep returned nothing, so the file doesn't cover it." + ❌ "three synonyms, all empty — not covered" (no file was ever read). - **A cross-reference is not a load** (`unprobed` in-house; external evidence — see Provenance). On weak tiers, discovering that a sibling skill applies is a judgment act: fable-method published a smoke-grade @@ -229,6 +313,66 @@ The sharpest usability probe is behavioral: give a fresh weaker-tier behavior down first, then patch the gaps the probe surfaces — not the ones you imagine. +**A skill — or a plugin's instruction files — is under this section's +review: verify the deployment runtime before the review concludes** +(`unprobed` — private incident as shape; see Provenance). A skill +verified only on the author's machine can pass every lens above and +still be wrong where it will actually run: one reviewed-and-finalized +skill was reworked wholesale when its real target — a sandboxed Linux +VM, not the author's macOS — surfaced only after sign-off. §1's gate +placement applies at authoring start: the target answer (or a recorded +`user-must-provide`) is required before the first artifact-producing +step; this review is the enforcement backstop, and it blocks adoption +when the answer is missing. Confirm the review record — the same +artifact class as the change record used elsewhere in this file: "the +PR description or commit +message when one is being created, otherwise the completion report" — +names the target runtime(s): the execution environment (OS, container, +sandbox) and any governing connector or tool instance. Not named → +read the repo's own deployment manifests and docs first, then obtain +what they cannot tell you from the requester; no answer → write +`user-must-provide` in the record; adoption then proceeds ONLY under a +recorded risk acceptance by whoever owns the deployment — that +acceptance is an alternate Done which still requires the sweep below +and every in-file label; without it the artifact stays blocked. +Named or not, always run the sweep for assumptions that silently bind +the file to the author's machine — this list is a floor, not the +ceiling: an accidentally machine-local repository path gets §2's +remedy, verbatim ("Anchor to the VCS root (`git rev-parse +--show-toplevel`) and verify the path prefix before reading"), while +an absolute path the target itself defines (a socket, device, mount) +is a machine-bound assumption like the rest; OS-specific launchers and +helpers (URL-scheme opens, clipboard or notification tools), host +identity (a literal hostname or username), wall-clock or timezone +assumptions (a hard-coded TZ, a locale), instance-specific tool +identifiers (a connector's tool prefix can be unique to the author's +instance), and — for anything that executes programs — architecture, +interpreter and dependency availability, runtime versions, filesystem +semantics, permissions, and network reach. `runtime-agnostic` may be +recorded only for pure instruction text with no executable dependency; +anything that runs programs names its dimensions instead. Each +machine-bound assumption keeps a verified portable form, or stays +behind a verified target-scoped dispatch — which satisfies a named +target only when that target ALSO keeps a working path for every +capability the file claims (a foreign-OS-only branch is not +compatibility) — or carries a label naming the exact runtime or +instance required, written IN the skill file beside the dependency +(§2's embed-the-knowledge; the review record points to it), verified +against that instance where reachable and marked `unverified` (§2) +where not: a label records a limitation, never proves compatibility. +Done when every target runtime named in the record is compatible with +every assumption reachable on it — a labeled incompatibility with a +named target blocks completion, and shrinking the supported scope can +only exclude an optional target with the requester's explicit say — or +when the recorded risk acceptance above stands in; and everything +machine-bound carries its named label in the file. +✅ "target: sandboxed Linux VM plus the team's shared connector +instance; the macOS-only notify helper replaced with the project's CLI +logger; the connector prefix labeled in-file 'requires the shared +instance' and resolved against it." +❌ "labeled the launcher 'requires macOS' and concluded — while the +named target is a Linux VM." + Fix what blocks, then read back the final files to confirm they landed complete. When mining sessions or external material into skills, strip names/slogans first and keep a procedure only if it still has an apply-when, @@ -397,4 +541,35 @@ marker per the README covenant: the external measurement is of one skill's one gate, and whether placement generalizes across gate types is exactly what an in-house probe would test — that probe has not been run; the marker records the debt. +The §5 keyword-grep-absence rule (2026-07-21) generalizes three private +incidents in one week, each the same shape: a keyword grep of a rules file +returned nothing, "not covered here" was concluded, and the content existed +under different phrasing — including one proposed upstream addition whose +substance was already in the target file, caught only by reading the +section during drafting (contributor-reported; the private repos are +verifiable by the contributor, not linkable here). It ships `unprobed` per +the README covenant's second branch — no in-repo probe has run; the +executable probe shape (seed a reworded twin of a rule, instruct a +weak-tier agent to dup-check an addition, observe grep-only vs read) is +noted here as the debt, not claimed as run. +The §6 deployment-runtime rule (2026-07-21) comes from a private incident: +a skill was authored, reviewed through the lenses above, and finalized for +the author's local macOS environment, then rebuilt wholesale the same week +when the user mentioned it would run inside a sandboxed Linux VM — host +identity, launcher mechanism, and machine-local MCP tool-name assumptions +all failed on the real target (contributor-reported; the private repo is +verifiable by the contributor, not linkable here). Ships `unprobed` per the +README covenant's second branch: no in-repo probe has run; the probe shape +(give a weak-tier reviewer a machine-bound skill plus a named foreign +runtime, observe whether the sweep fires) is recorded as debt. +The §3 capability-negative rule (2026-07-22) comes from a private +incident: a subordinate-CLI playbook asserted a capability did not exist +("model switching only works interactively; no flag") — true when +written, false at the tool's current version — and the stale negative had +been silently steering sessions into a degraded interactive-only path +until a review pass re-probed the binary. Private evidence, cited as +shape per the README covenant's second branch; the executable probe — +re-running recorded capability-negatives against the current binary on +each version change and counting flips — has not been run as a standing +check; the in-body `unprobed` marker records that debt. Stable method; no environment facts to re-verify.