dev-tweak
Skill0 starsChanged 4 months agoMITView on GitHub
Use when a change fits 1-3 files, no pipeline needed. Use with /dev-tweak.
In this repository42 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- content-rewriteSkill
- content-writeSkill
- core-auditSkill
- core-bootstrapSkill
- core-commitSkill
- core-explainSkill
- core-finalizeSkill
- core-orchestrateSkill
- core-pullSkill
- core-setupSkill
- core-updateSkill
- design-convertSkill
- design-shipSkill
- design-tokensSkill
- dev-inspectSkill
- dev-learnSkill
- dev-manualSkill
- dev-optimizeSkill
- dev-securitySkill
- dev-shipSkill
- game-debugSkill
- game-optimizeSkill
- game-shipSkill
- game-tweakSkill
- marketing-contentSkill
- marketing-researchSkill
- marketing-screenshotsSkill
- project-addSkill
- project-appSkill
- project-memorySkill
- project-planSkill
- project-removeSkill
- project-researchSkill
- project-seedSkill
- project-syncSkill
- project-todoSkill
- project-tunnelSkill
- team-issuesSkill
- team-outsourceSkill
- team-reviewSkill
- team-verifySkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 33
verify: scoped tests + lint per PHASE 3 below
- Very specific: line 283
Tests: run existing tests covering the touched files.
- Very specific: line 405
Use {fix|refactor|perf|style|test|docs|chore}({slug}): {summary}.
- Distinctive: line 428
Optional learning (0-1): only for a bugfix whose root cause has value beyond this spot (filter per shared/LEARNING-WRITE.md § Writer Append …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Tweak
Fast path for small web-stack changes: a bugfix, copy/styling adjustment, config change, or small
refactor that fits 1-3 files. Everything heavier belongs to /dev-ship — the gate that decides is
shared/TWEAK-DISCIPLINE.md (size gate, backlog guard, registration
policy, never-do list). No TaskCreate phase tracking — a tweak run is minutes of work with no
compaction risk; ceremony is what this skill exists to avoid (deliberate, not a gap:
check-task-markers.py expects 0 units here). Safe to run several /dev-tweak
invocations concurrently against the same repo/branch — PHASE 4's commit lands atomically per
shared/SCOPED-COMMIT.md § 5. Skill file stays English; user-facing
output follows CLAUDE.md § User Preferences → Language:.
Tweak configuration (per shared/TWEAK-DISCIPLINE.md):
- verify: scoped tests + lint per PHASE 3 below
- escalation ship target:
/dev-ship - escalation debug target:
/dev-ship {feature}debug round, or the inline DEBUG-LADDER.md tier-3 discipline outside a feature context
PHASE 0 — Pre-flight, size gate & backlog guard
Todo: session already in plan mode at invocation (harness-level, not this skill's own) → still run steps 1-3 and 5-6 now — they're read-only and plan-mode-safe. Defer only step 4 (a write) to the first action after the session's next
ExitPlanModeresolves, before PHASE 1 starts. A fired gate/guard still routes toreferences/escalate.mdregardless of plan mode.
- Repo: resolve
$REPOpershared/SYNC.md§ Worktree-aware Path Resolution —git worktree list --porcelain | head -1for{main_worktree}vsgit rev-parse --show-toplevelfor{current}; different → use{main_worktree}/.project/..project/absent → degrade gracefully: skip the card lookup, guard, and learnings silently, keep the rest (the code change is the value; do not scaffold). - Mode + description:
.project/present → resolve the card with the narrowest load that can answer the question, per shared/TWEAK-DISCIPLINE.md § Card pickup path 1 (exact name, or an unambiguous ≥2-shared-token match against liveTWEAKcards):- Invocation argument is a bare kebab-case token (a plausible card name) → try the
single-card load FIRST:
node ~/.claude/scripts/backlog-load.js "$REPO" read-feature "<arg>".present: true+type: "TWEAK"→ card mode, and this payload already carriesdependencies[]— no second read, noguard-itemsload at all (card mode skips step 5's guard anyway, so the full-backlog payload would be loaded for nothing). present: false, a non-TWEAK type, or free-text prose → THEN loadnode ~/.claude/scripts/backlog-load.js "$REPO" guard-itemsfor the ≥2-shared-token match and step 5's guard (one load, not two).- Match → card mode. Description = the card's
description. Dependency check againstdependencies[]from whichever load ran (guard-itemsomits the field — on that path read the matched card'sdependenciesfrombacklog.jsondirectly): oneAskUserQuestiononly when a dependency is present and not yetshipped/DONE(per TWEAK-DISCIPLINE § Card pickup); no dependencies field → skip silently. A dependencyread-featurereports aspresent: falseis usually already resolved and archived, not missing — look it up in.project/archive/backlog-archive.json#archived[]and checkshipped: true(the criterion per TWEAK-DISCIPLINE § Card pickup). An archivedfeature.jsoncarriesstatus, nevershipped, sostatus: "DONE"there is a weaker fallback signal, not the check. - No match, or
.project/absent → free-text mode. Description from the invocation argument; if empty, ask one short question.
- Invocation argument is a bare kebab-case token (a plausible card name) → try the
single-card load FIRST:
Branch guard.
Todo: run shared/TWEAK-DISCIPLINE.md § Branch guard's actual check now —
git symbolic-ref --short refs/remotes/origin/HEAD(or themain/masterfallback) vsgit branch --show-current. Run both commands; never infer the default branch from the session's environment block or from memory. On the default branch → continue silently. Any other branch or detached HEAD → warn + ask before proceeding.Baseline — mandatory precondition for PHASE 4 and for a later escalate.md "override" choice, not optional ceremony.
Todo: run now, before step 5's gate check:
mkdir -p .project/session && git status --porcelain | sort > .project/session/pre-tweak-status.txtper shared/SCOPED-COMMIT.md § 1 (skip only when.project/is absent). Runs even when the gate is about to escalate — the file is cheap and unblocks a later "Continue as tweak" override without re-deriving state.Gate (intake pre-check) + guard.
Apply shared/TWEAK-DISCIPLINE.md § Size gate criteria 1, 5 and 6 to the projected scope now — never from memory or from this file's own intro framing (criteria 2, 3 and 4 need the real file set and are decided in PHASE 1 step 2 instead). Use the shared table's own numbers — do not renumber locally:
- 1 — Net-new surface — adds capability instead of adjusting existing behavior
- 5 — Guard hit with in-pipeline status — see § Backlog guard resolution
- 6 — Debug tier-3 signals — intermittent failure, cause spans multiple modules, or a prior fix attempt already failed (DEBUG-LADDER.md tier 3)
Any of these fires → Read
references/escalate.mdnow, before locating.§ Backlog guard: card mode → skip (the card already names the scope — a fresh dedup would just rediscover itself). Free-text mode → run § Backlog guard as before, then § Card pickup path 2 (the TWEAK-only mini-guard) against the same
guard-itemsload from step 2.Todo: if any gate criterion fires or a guard demands escalation → Read
.claude/skills/dev-tweak/references/escalate.mdand follow it — never continue silently.Slug: card mode → the card's own kebab
name(no re-derivation). Free-text mode → derive a kebab-case slug from the description (commit scope + learnings feature key).Todo: print the intake status now, at this phase boundary — not deferred to the final report:
Guard: ✓ no card overlap(or the warn/advisory lines). Card mode printsCard: {name}instead — the card already names the scope (step 5 skipped the guard), so there is no guard result to report. Runs even when step 5's gate is about to escalate (same mirrored rule as step 4's baseline) —references/escalate.md § 3 (a)reads this printed name when it promotes the card out of the tweak lane. TheGate:verdict itself prints in PHASE 1 step 2, once the file set is known — do not print it here.
PHASE 1 — Locate & context
Locate the change with minimal reads (Grep → targeted Read). The files found here feed the size-gate re-check and the learnings load below.
Pre-seeded from a ship de-escalation handoff (invocation carries a
files[]+acceptance[]pair, per shared/TWEAK-DISCIPLINE.md § De-escalation gate (a)) → skip the Grep/Read locate itself; use the passedfiles[]as the located set directly. Everything downstream is unchanged: step 2's size-gate re-check still runs against that set — the handoff is not an exemption from it, and a criterion firing here still escalates exactly as a freshly-located set would. Hold the passedacceptance[]in memory and use it as PHASE 3's verify checklist (a test/check that exercises one of its scenarios counts toward Tier 1's auto-pass condition) instead of relying on whatever coverage happens to already exist.Todo: an intake step here — a clarifying
AskUserQuestion, or what the located code reveals — can surface that the real scope exceeds the size gate (the described 1-file tweak is actually a schema/sequencer/multi-file change). The moment it does, Readreferences/escalate.mdand escalate before any design work — do not run an Explore/plan/EnterPlanModecycle on the out-of-scope shape first (that is the intake-side twin of PHASE 2's "do not finish the edit first"). Holds even when the session is already in harness plan mode. This gates every step below: only once it clears do steps 2-5 run.Todo (card mode): locate shows the described defect already resolved on
main(a later commit fixed it, or it never applied — stale), or the card's whole reason to exist is superseded by a wider card (nothing fixed it, another card absorbed it — confirm with oneAskUserQuestionnaming that card first) → skip PHASE 2, PHASE 3, and PHASE 4 step 1 entirely (including step 3's learnings load); go straight to the matching PHASE 4 write per shared/TWEAK-DISCIPLINE.md § Card pickup → Stale card / Obsolete-superseded card. Both cases: commit nothing, report carries noVerdict:/commit-sha line. Superseded decline → continue the tweak as originally scoped.Close the size gate — with the file set now known, apply shared/TWEAK-DISCIPLINE.md § Size gate criteria 2, 3 and 4 (file span, new test file, architecture) to the actual files. Criterion 3 fires on a new test file or harness only — new cases in an existing test file are tweak-compatible. A criterion fires → Read
references/escalate.mdbefore any design work.Todo: print
Gate: ✓ tweak-sized ({n} file(s))now. Not printed → this step did not run; do not proceed to step 3. One exception to "now": an intakeAskUserQuestionin step 1 whose answer itself decides the file set (a scope choice between a 1-file and a 2-file fix) — print theGate:line after that answer lands, since{n}does not exist before it. Never skip the print, only defer it past that one question.Learnings — mandatory, not gated on tweak size. Run exactly this, after locate so
--pathscarries the real file anchors (see shared/LEARNINGS-LOAD.md for the full parameter/relevance model):node ~/.claude/scripts/learnings-search.js "$REPO" load \ --feature "{slug}" --scopes component --pitfall-prefix true \ --paths "{located files, comma-separated, repo-relative}"Todo: any non-zero exit (including exit 2, usage error) is a failed step, not a zero-match result — fix the invocation and re-run before proceeding. Only exit 0 with empty stdout is a genuine zero. The count feeds step 5's
Lane:line below; no separate print here.Durable-decisions check — dev-tweak's only route back to a feature's already-settled design questions (
durableDecisions[]has no other reader on the modify path — seeshared/FEATURE-LOAD.md)..project/absent (already degraded at PHASE 0 step 1) → skip silently, same as the rest of this skill's graceful degradation..project/present → grep.project/features/*/feature.jsonand.project/features/archive/*/feature.jsonforfiles[].pathentries matching any located file (repo-relative path match). No match on any feature → skip silently, no cost — most tweaks touch files no pipeline feature ever built.Todo: a feature matched → project its decisions first (cheap, no Read):
node -e 'const f=require(process.argv[1]); console.log(JSON.stringify((f.durableDecisions||[]).map( x=>({decision:x.decision,constraint:x.constraint,chosen:x.chosen}))))' \ <path-to-feature.json>Every projected entry has a null/absent
constraintandchosen→ no recorded constraint can bind this tweak: say so in one clause and continue, no Read. Otherwise → Read.claude/skills/dev-tweak/references/durable-decisions.mdand follow it (multi-match tiebreak, how the constraints bind PHASE 2).Lane routing.
Todo: judge this table fresh against this run's actual locate/learnings results, never from memory. Evaluate rows in order; the first match picks the lane. Source of truth: shared/TWEAK-DISCIPLINE.md § Lane routing — do not renumber locally, same policy as PHASE 0 step 5's inlined size-gate criteria.
# Condition Lane 1 Stale or obsolete/superseded card, or a docs-only / .project-only change (docs-only = no tracked source file is edited; a docstring or comment edit inside a source file is a code change and does not qualify)A 2 A verify round in this run failed, or a size-gate escalation was consciously overridden (§ Escalation gate c) C 3 PHASE 1 locate left ≥2 candidate sites open, or landed on none B 4 A learning printed with type pitfallcarries the⟨path⟩marker (its ownpaths[]overlap a located file) — read the marker, never re-classifyB 5 Otherwise A A lane only ever moves up during a run, and never overrules the size gate. Row 2 fired → Read TWEAK-DISCIPLINE § Lane routing for its hard rules (the second failed round ends the tweak) before designing.
Then print one line, always — Lane A included:
Lane: {A|B|C} · Learnings: {n} ({matched pitfall, or "no pitfall on located paths"}).{n}= total lines the load printed across all blocks — a raw count, not a deduped one; nothing downstream depends on the exact number.
PHASE 2 — Implement
- STOP — gate before the first
Edit: scroll up and confirm four artifacts exist above this point — a printedGate:line (PHASE 1 step 2), alearnings-search.jstool result (step 3), afeature.jsongrep result or its "no match" (step 4), and a printedLane:line (step 5). Judge what the transcript shows, not what you remember doing. Any one absent → go back to that step now; do not edit first and reconcile after. All four present → say so in one line (Pre-edit gate: ✓ 4/4) before the firstEdit— a gate that leaves no trace cannot be distinguished from a gate that was skipped. An escalation firing in PHASE 1 is the one exception: the run ends atreferences/escalate.mdinstead, which prints its own two-line report. Lane execution — run the lane PHASE 1 step 5 picked:
- A — direct. No
EnterPlanMode. Edit straight away. - B — designed.
EnterPlanMode(skip if already active) → design → write the decision to the plan file →ExitPlanMode→ implement. - C — B plus a second opinion. A
Planagent (model: "opus") writes the design, then a Fable consult on the plan file per shared/SECOND-OPINION.md, both beforeExitPlanMode.
Semantics and the hard rules stay in shared/TWEAK-DISCIPLINE.md § Lane routing. Four dev-side deltas:
- Row 4 (pitfall) triggered the lane → the plan file's design names the concrete mitigation in one line — part of the design, not a separate print.
- Lane C → the Fable digest must be visible before
ExitPlanMode, when the gate is presented. - Opus/Fable involvement is not a size-gate exemption — a wider file span or net-new surface
found during design still routes to
references/escalate.md. - The harness may open its own plan-mode workflow prescribing Explore/
Planagent fan-out onEnterPlanMode. Ignore it: the file set is already located, a tweak designs inline.
- A — direct. No
- Edit discipline per shared/TWEAK-DISCIPLINE.md § Edit
discipline — read-before-write, bounded read size, deliberate (not random) test-file pick. A
located file has a frontend extension (
.tsx/.jsx/.vue/.svelte/.cssor equivalent) → load the theme digest (same extraction as/dev-inspectPHASE 0 step 4 — color tokens, motion,cssVars; session-memoized) and Read shared/EDIT-DISCIPLINE.md, hold the diff against it. No frontend file located → skip both, no cost. - Bugfix-shaped tweaks follow shared/DEBUG-LADDER.md tier 1/2: hypothesis before edit, evidence before a second attempt — never guess-and-check.
Mid-flight re-check.
Todo: the moment actual scope exceeds the size gate (a 4th source file touched, a discovered new surface) → stop now and Read
references/escalate.md— do not finish the edit first and reconcile after.
PHASE 3 — Verify light
A tweak that edits no git-tracked file at all — only gitignored .project/ state (e.g.
recording a known issue as a learning) — or a stale or obsolete/superseded card with nothing to
edit (see PHASE 1) — has nothing to verify and nothing to commit: skip PHASE 3 and PHASE 4 step 1,
say so in the report (no Verdict:/commit sha lines), and go straight to the card-completion (or
cancellation) + learning writes. A docstring/comment-only edit inside a tracked source file is
still a code change — it runs the normal verify + commit flow below, just with no behavior for a
test to exercise (routes to PHASE 3's Tier 2 modal, not the auto-pass tier). Everything below
assumes a code change.
Scoped to the touched modules — never the full suite unless it is genuinely fast:
- Tests: run existing tests covering the touched files. Take the test and lint commands from the
project's own docs first —
CLAUDE.md § Commands,.project/, or the test harness's own config — and only fall back to the web defaults below when the project names none. A non-JS project (Python/Go/Rust/C++) will not have the commands in the next two bullets. - The documented command is suite-wide (the common case outside JS:
pytest <dir>,go test ./...,cargo test) → do not run it as written; the project naming it does not make it scoped. Derive the scoped form — append the touched test file(s), or a-k/pattern filter — and run any build/compile step those same docs mandate as its own separate command. Run the unscoped command only when a measured run comes back under ~60s; over that, name in the report which scoped subset ran instead. - The project's docs mandate a post-build step (deploy, sync an artifact to a runtime data
directory, restart a service) → it belongs to verify, not to "later": a green test run on a build
the user's runtime never received is a false pass. Run it. Could not run it → it becomes a PHASE 4
step 4
Next steps:item, phrased as the command the user runs — never a line inside the report fence: an unrun step is the user's action, and label-value lines read as archive data they scroll past. - Web defaults:
npx vitest related <files>, or the project's test command with a path/pattern filter. - Harness failure (collection/import error, missing interpreter or deps, stale virtualenv) is
not a baseline regression — repair it when the broken piece is gitignored local state (e.g. a
stale
.venv), say so in the report, then re-run. Never edit source to make a broken harness pass. - Lint: on changed files only — Biome (
npx biome check) when@biomejs/biomeis in package.json; ESLint when configured; skip with one line otherwise.tsc --noEmitonly when configured and cheap. - Visual/copy tweaks: re-check live in the running app (DEBUG-LADDER tier 1) instead of tests.
Drive the app via the
/runskill — it owns the per-project launch path (browser dev-server, Tauri/Electron desktop shell) so this stays project-agnostic. Capture concrete evidence before judging pass: a screenshot, a computed-style/DOM assertion, the changed pixels — never an eyeballed "looks right". Can't reach/drive the running app (wrong worktree, no dev server, headless environment) → say so explicitly and ask the user to verify visually; never report the live check as passed when it wasn't run.
New failures vs the baseline → fix within the current tier's discipline; unfixable within tweak
scope → Read references/escalate.md. Not a failed round: a test or assertion this same PHASE 2
pass authored failing on its own defect (an over-broad matcher, a wrong fixture), corrected without
touching the code under change — that is the test loop working. It becomes a failed round the moment
the correction reaches the source under change. A failed round also feeds
shared/TWEAK-DISCIPLINE.md § Lane routing row 2: the first
failed round in this run lifts to Lane C for the next PHASE 2 pass (re-score, don't re-derive from
scratch — the lane only ever moves up); a second failed round on the same issue routes to
references/escalate.md instead of a fourth lane.
Live verdict.
Todo: check the auto-pass condition below FIRST, before considering the modal — the modal is the fallback, not the default.
Tier 1 — auto-pass (no modal). Skip straight to PHASE 4 when all of these hold — machine proof only, never a self-assessment of "this is trivial":
- the checks above actually ran and came back clean, AND
- at least one test exercises the changed behavior (lint/typecheck alone doesn't count; a change with no covering test doesn't count), AND
- this is not a visual/copy tweak (the "visual/copy tweaks" bullet above still applies — a live re-check there is human judgment, not machine proof), AND no reachability caveat fired. That caveat is not visual/copy-only: it fires for any change whose user-visible effect can only be confirmed in a running app or runtime this session cannot drive (game engine, trading terminal, daemon). Source-level proof that the call site is correct is real evidence, but it is not that confirmation — route to Tier 2 and name what the user should look at.
Only the covering-test bullet failed, and coverage is one mechanical assertion away — an
existing test file already covers the touched module AND the assertion is mechanical (a value, a
source-level invariant, a rendered string) → add that one case, re-run the checks, and re-evaluate
Tier 1. Size-gate criterion 3 fires on a new test file only, so this stays tweak-sized, and PHASE
4's commit-type list already carries test for exactly this. No such file, or the assertion needs a
new harness or fixture (criterion 3 fires) → Tier 2. Bounded on purpose: never invent a test whose
only purpose is to dodge the modal.
Any other one of these failing → Tier 2.
Tier 2 — ask. Correctness rests on human judgment → one AskUserQuestion before wrap-up, four
options. Use these four verbatim — do not improvise replacements even when a live check was
blocked; a blocked live check maps to I'll test it myself. For a visual/copy tweak the live
re-check above runs FIRST and the modal presents its evidence (screenshot / verified value) — so
Pass there is an informed confirm-and-commit, never a decision made before the result exists. A
fifth path, Re-score — design this properly, is deliberately NOT a modal option (AskUserQuestion
caps at 4) — reached only via the built-in Other answer; treat that answer exactly as its
bullet below describes:
Pass (Recommended)→ the shown result is correct → continue to PHASE 4 and commit.I'll test it myself→ state plainly what to test and what "pass" looks like, then wait — do not proceed to PHASE 4 until the user replies. "Works" → PHASE 4. "Doesn't hold up" → counts as a failed round (§ Lane routing row 2, same first/second-round rule as above) → back to PHASE 2 on the same file scope, then re-run PHASE 3.One more small tweak→ back to PHASE 2 for one more iteration on the same file scope, then re-run PHASE 3. This doesn't reset the size gate — a new file surfacing on this pass still firesreferences/escalate.mdexactly like any other mid-flight re-check (PHASE 2 step 5). Not itself a failed round (the prior pass may have verified clean) — only an actual PHASE 3 failure counts toward § Lane routing row 2.Re-score — design this properly(Other) → counts as a failed round (§ Lane routing row 2) → re-enter PHASE 2 step 2; the lane lifts per that row (first re-score → Lane C, second →references/escalate.md).Revert — restore to baseline, don't commit(per shared/TWEAK-DISCIPLINE.md § Edit discipline) → restore the working tree topre-tweak-status.txt(PHASE 0 step 4), commit nothing, skip PHASE 4 step 1 entirely. Card mode → the card is not touched (noshipped/CANCELLEDwrite — the defect is still open, this run just didn't fix it). Report closes withVerdict: reverted, not committedinstead of a commit sha.
PHASE 4 — Wrap-up
Scoped commit per shared/SCOPED-COMMIT.md — never a bare
git add && git commit. Write the commit message to a scratch file under.project/session/first, then land with exactly this call — the script accepts no other arguments, and in particular there is no baseline flag:pre-tweak-status.txtis your own reference for categorizing files, never something you pass in.bash ~/.claude/scripts/scoped-commit.sh \ --message <path-to-message-file> \ --files <comma-separated-paths>Deltas vs § 5, one rule per line:
- Baseline is
pre-tweak-status.txt; OVERLAP policy is auto-include (the fix is the point); fallback: ask which files belong to the tweak. --fileslists the files THIS run edited — never the whole baseline diff. A concurrent/dev-tweakon the same tree makes its own files look NEW against your baseline too (§ 2 buckets every changed file as NEW / OVERLAP / PRE-EXISTING; NEW cannot tell your file from theirs).- Message type is never
feat— a tweak adds no net-new capability (size-gate criterion 1). Use{fix|refactor|perf|style|test|docs|chore}({slug}): {summary};testwhen the only change is added or expanded test coverage,docswhen it is a docstring/comment/markdown-only edit (PHASE 3's comment-only branch). - Cleanup: remove the baseline file and the commit-message scratch file.
- Baseline is
Card-mode completion (skip entirely in free-text mode): move the card from
.project/backlog.json#features[]to.project/archive/backlog-archive.json#archived[], setting exactlyshipped: true,shippedAt(YYYY-MM-DD),shippedSha(step 1's commit), andsummary(the tweak's one-line outcome). Those four and no others — astatusflip or atransitiondelete is not part of this write. Semantics, the archiving contract, and the dashboard rationale live in shared/TWEAK-DISCIPLINE.md § Card pickup → completion write; read it only if the move itself is unclear.Then run shared/BACKLOG.md § Archive-move invariant: re-read both files and confirm the card is absent from
features[]and present inarchived[]with all four fields. A running board app (serve-backlog.js) can silently revert an external write from its in-memory store — re-apply on a revert. Only once this holds does the report carryCard: {name} → shipped.Obsolete/superseded card instead (PHASE 1's confirmed obsolete branch): run that same file's § Card pickup cancellation write instead — the card stays in
features[], no archive move.Optional learning (0-1): only for a bugfix whose root cause has value beyond this spot (filter per shared/LEARNING-WRITE.md § Writer Append Protocol). The payload goes in on stdin — there are no
--feature/--summaryflags:node ~/.claude/scripts/learnings-write.js append "$REPO" <<'JSON' {"entries":[{"feature":"{slug}","type":"pitfall","source":"extracted", "summary":"...","tags":["..."],"paths":["{located file}"]}]} JSONpathscarries the located files — PHASE 1 step 3 loads with--paths, so a learning written without them is invisible to this skill's own next relevance load. 0-3 tags perLEARNING-WRITE.md § Tag Vocabulary. A non-zero exit is a failed step, not a zero result — fix the payload and re-run (same rule as PHASE 1 step 3). Then run the Consolidation Gate once (LEARNING-WRITE.md § Consolidation Gate). Skip both silently otherwise. No state auto-push (TWEAK-DISCIPLINE § Registration policy).Stale-learning correction — separate from the 0-1 budget above, and not gated on the bugfix filter: PHASE 1 step 3's load surfaced a learning this tweak just made wrong (a convention it renamed, a limit it lifted, a path it moved) or superseded (the workaround it prescribes is no longer the best route) → correct that entry in place. Same stdin shape as
append, with the patch fields flat alongsidematch— a nested{"match":…,"patch":{…}}is silently ignored:node ~/.claude/scripts/learnings-write.js enrich "$REPO" <<'JSON' {"patches":[{"match":{"feature":"...","type":"pitfall", "summaryEquals":"<exact current summary>"}, "summary":"<corrected summary>"}]} JSONThis call fails silently. Exit 0 with
{"patched":0,"alreadyApplied":1}on a first correction means the payload was not understood, not that the work was already done — re-read the entry and confirm the summary actually changed before reporting it. Onlypatched: 1is success. This repairs existing memory rather than adding to it, so it neither counts against the 0-1 budget nor triggers the Consolidation Gate, and it is not a new backlog write. Leaving a contradicted learning in place is the drift trap this closes — the next run reads it as current and undoes the tweak.Report — one fenced block per
shared/OUTPUT.md§ Report Block (≤72 chars, Label-value grammar), with any "what changed" prose detail outside the fence.Todo: Read
.claude/skills/shared/OUTPUT.md§ Report Block now, before composing the block — 75 lines. Reconstructing the grammar from memory drops the====underline and lets explanatory sentences into the fence, the two rules that decide whether the user can scan the result at all.Repeat the
Card:/Guard:,Gate:andLane:lines here even though they printed mid-run — this block is the durable record. Fields:- what changed, with
file:linerefs; checks run; commit sha - a
Guard:line reflecting PHASE 0's actual result — never assert "no card overlap" if the guard didn't run (say so instead); card mode prints this exact form instead of aGuard:label:Card: {name} → shipped, orCard: {name} → cancelled (superseded by {card})for the obsolete/superseded outcome - a
Verdict:line —auto-passed on green checks ({n} tests + lint)for a Tier 1 auto-pass, oruser-confirmed/self-testedfor whichever Tier 2 path was taken. Auto-pass is never silent — the report always states why the modal didn't fire. - a
Lane:line always, Lane A included —Lane: {A|B|C} · Learnings: {n}(carry PHASE 1 step 5's line forward verbatim; B/C append the matching row in one line). This field is the proof PHASE 1 step 3's learnings load actually ran — its absence means that step was skipped. - a
Consult:line only when Lane C actually spawned a consult — values per shared/SECOND-OPINION.md § Logging (consulted ({trigger})/consulted ({trigger}) → revised/consulted ({trigger}) → confirmed/unavailable). Omit entirely on Lane A/B — there is nothing to log. - a
Learning:line when one was written;Escalation overridden: {criterion}when applicable a post-fence
Next steps:numbered block (shared/SKILL-PATTERNS.md § Next Steps) when either trigger fires; neither fires → a tweak is terminal, no next-step offer:- PHASE 3 could not run a project-mandated post-build step → the command the user must run, first in the list. Fires in card mode too, where the tweak is otherwise terminal.
- the guard flagged a TODO card (free-text mode only) →
/dev-ship {card}
An escalation park (
references/escalate.md § 3 (a)) prints its ownPick it up with /dev-ship {name}.line instead of this block.
Todo: raised a skill-feedback point alongside this report (friction observed during the run, per
~/.claude/CLAUDE.md § Skill Feedback) → store it now, in one call:node ~/.claude/scripts/skill-feedback.js add --skill dev-tweak --note "<point>"(repeat--noteper point;--source userfor a point the user raised). The report is not the store — an unstored point is lost, so/core-auditnever sees its recurrence count. Nothing observed during the run → no call, no ritual closer.- what changed, with
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

