ramstack 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +44 -0
- package/agents/comment-sicko.md +32 -0
- package/agents/poteto-agent.md +9 -0
- package/cli/rstack.mjs +539 -0
- package/package.json +29 -0
- package/skills/architect/README.md +25 -0
- package/skills/architect/SKILL.md +83 -0
- package/skills/architect/agents/openai.yaml +5 -0
- package/skills/architect/references/design-red-flags.md +33 -0
- package/skills/architect/references/rationale-template.md +35 -0
- package/skills/architect/references/runner-prompt.md +20 -0
- package/skills/arena/README.md +21 -0
- package/skills/arena/SKILL.md +71 -0
- package/skills/arena/agents/openai.yaml +5 -0
- package/skills/automate-me/README.md +21 -0
- package/skills/automate-me/SKILL.md +109 -0
- package/skills/automate-me/agents/openai.yaml +5 -0
- package/skills/blast-radius/README.md +21 -0
- package/skills/blast-radius/SKILL.md +50 -0
- package/skills/blast-radius/agents/openai.yaml +5 -0
- package/skills/bro/README.md +16 -0
- package/skills/bro/SKILL.md +7 -0
- package/skills/bro/agents/openai.yaml +5 -0
- package/skills/create-verification-skill/README.md +22 -0
- package/skills/create-verification-skill/SKILL.md +44 -0
- package/skills/create-verification-skill/agents/openai.yaml +5 -0
- package/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/skills/figure-it-out/README.md +22 -0
- package/skills/figure-it-out/SKILL.md +55 -0
- package/skills/figure-it-out/agents/openai.yaml +5 -0
- package/skills/how/README.md +25 -0
- package/skills/how/SKILL.md +134 -0
- package/skills/how/agents/openai.yaml +3 -0
- package/skills/how/references/critic-prompt.md +59 -0
- package/skills/how/references/critique-rubric.md +58 -0
- package/skills/how/references/explainer-prompt.md +55 -0
- package/skills/how/references/explorer-prompt.md +52 -0
- package/skills/interrogate/README.md +21 -0
- package/skills/interrogate/SKILL.md +112 -0
- package/skills/interrogate/agents/openai.yaml +5 -0
- package/skills/interrogate/references/code-quality-review.md +47 -0
- package/skills/interrogate/references/lead-judgment.md +58 -0
- package/skills/interrogate/references/reviewer-prompt.md +72 -0
- package/skills/interrogate/references/rubric.md +77 -0
- package/skills/maintain-verification-skill/README.md +21 -0
- package/skills/maintain-verification-skill/SKILL.md +39 -0
- package/skills/maintain-verification-skill/agents/openai.yaml +5 -0
- package/skills/no-comments/README.md +22 -0
- package/skills/no-comments/SKILL.md +24 -0
- package/skills/no-comments/agents/openai.yaml +5 -0
- package/skills/poteto-mode/README.md +26 -0
- package/skills/poteto-mode/SKILL.md +140 -0
- package/skills/poteto-mode/agents/openai.yaml +5 -0
- package/skills/poteto-mode/playbooks/authoring-a-skill.md +13 -0
- package/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
- package/skills/poteto-mode/playbooks/autopilot-full.md +13 -0
- package/skills/poteto-mode/playbooks/autopilot-stack.md +16 -0
- package/skills/poteto-mode/playbooks/babysit.md +27 -0
- package/skills/poteto-mode/playbooks/bug-fix.md +17 -0
- package/skills/poteto-mode/playbooks/eval.md +27 -0
- package/skills/poteto-mode/playbooks/feature.md +21 -0
- package/skills/poteto-mode/playbooks/hillclimb.md +21 -0
- package/skills/poteto-mode/playbooks/investigation.md +14 -0
- package/skills/poteto-mode/playbooks/multi-phase-plan.md +3 -0
- package/skills/poteto-mode/playbooks/opening-a-pr.md +11 -0
- package/skills/poteto-mode/playbooks/orchestrate.md +113 -0
- package/skills/poteto-mode/playbooks/pause-safely.md +10 -0
- package/skills/poteto-mode/playbooks/perf-issue.md +24 -0
- package/skills/poteto-mode/playbooks/prototype.md +14 -0
- package/skills/poteto-mode/playbooks/refactoring.md +16 -0
- package/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/skills/poteto-mode/playbooks/session-pickup.md +13 -0
- package/skills/poteto-mode/playbooks/shipping.md +20 -0
- package/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
- package/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/skills/poteto-mode/playbooks/worktree-cleanup.md +14 -0
- package/skills/poteto-mode/references/bugbot-triage.md +142 -0
- package/skills/poteto-mode/references/plan.md +105 -0
- package/skills/poteto-mode/scripts/bootstrap.ts +62 -0
- package/skills/poteto-mode/scripts/bun.lock +67 -0
- package/skills/poteto-mode/scripts/orch/orch.test.ts +634 -0
- package/skills/poteto-mode/scripts/orch/orch.ts +578 -0
- package/skills/poteto-mode/scripts/orch/store.ts +1607 -0
- package/skills/poteto-mode/scripts/package.json +16 -0
- package/skills/poteto-mode/scripts/watch-pr/cli.test.ts +224 -0
- package/skills/poteto-mode/scripts/watch-pr/cli.ts +223 -0
- package/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +118 -0
- package/skills/poteto-mode/scripts/watch-pr/github.test.ts +306 -0
- package/skills/poteto-mode/scripts/watch-pr/github.ts +699 -0
- package/skills/poteto-mode/scripts/watch-pr/policy.test.ts +420 -0
- package/skills/poteto-mode/scripts/watch-pr/policy.ts +832 -0
- package/skills/poteto-mode/scripts/watch-pr/render.ts +169 -0
- package/skills/poteto-mode/scripts/watch-pr/tsconfig.json +13 -0
- package/skills/poteto-mode/scripts/watch-pr/types.compile.ts +93 -0
- package/skills/poteto-mode/scripts/watch-pr/types.ts +401 -0
- package/skills/poteto-mode/scripts/watch-pr/watch-pr +6 -0
- package/skills/poteto-mode/scripts/worktree-audit.sh +86 -0
- package/skills/principle-boundary-discipline/README.md +17 -0
- package/skills/principle-boundary-discipline/SKILL.md +34 -0
- package/skills/principle-boundary-discipline/agents/openai.yaml +5 -0
- package/skills/principle-build-the-lever/README.md +17 -0
- package/skills/principle-build-the-lever/SKILL.md +23 -0
- package/skills/principle-build-the-lever/agents/openai.yaml +5 -0
- package/skills/principle-encode-lessons-in-structure/README.md +17 -0
- package/skills/principle-encode-lessons-in-structure/SKILL.md +31 -0
- package/skills/principle-encode-lessons-in-structure/agents/openai.yaml +5 -0
- package/skills/principle-exhaust-the-design-space/README.md +17 -0
- package/skills/principle-exhaust-the-design-space/SKILL.md +21 -0
- package/skills/principle-exhaust-the-design-space/agents/openai.yaml +5 -0
- package/skills/principle-experience-first/README.md +17 -0
- package/skills/principle-experience-first/SKILL.md +19 -0
- package/skills/principle-experience-first/agents/openai.yaml +5 -0
- package/skills/principle-fix-root-causes/README.md +17 -0
- package/skills/principle-fix-root-causes/SKILL.md +23 -0
- package/skills/principle-fix-root-causes/agents/openai.yaml +5 -0
- package/skills/principle-foundational-thinking/README.md +17 -0
- package/skills/principle-foundational-thinking/SKILL.md +21 -0
- package/skills/principle-foundational-thinking/agents/openai.yaml +5 -0
- package/skills/principle-guard-the-context-window/README.md +17 -0
- package/skills/principle-guard-the-context-window/SKILL.md +17 -0
- package/skills/principle-guard-the-context-window/agents/openai.yaml +5 -0
- package/skills/principle-laziness-protocol/README.md +17 -0
- package/skills/principle-laziness-protocol/SKILL.md +18 -0
- package/skills/principle-laziness-protocol/agents/openai.yaml +5 -0
- package/skills/principle-make-operations-idempotent/README.md +17 -0
- package/skills/principle-make-operations-idempotent/SKILL.md +24 -0
- package/skills/principle-make-operations-idempotent/agents/openai.yaml +5 -0
- package/skills/principle-migrate-callers-then-delete-legacy-apis/README.md +17 -0
- package/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +22 -0
- package/skills/principle-migrate-callers-then-delete-legacy-apis/agents/openai.yaml +5 -0
- package/skills/principle-minimize-reader-load/README.md +17 -0
- package/skills/principle-minimize-reader-load/SKILL.md +23 -0
- package/skills/principle-minimize-reader-load/agents/openai.yaml +5 -0
- package/skills/principle-model-the-domain/README.md +17 -0
- package/skills/principle-model-the-domain/SKILL.md +26 -0
- package/skills/principle-model-the-domain/agents/openai.yaml +5 -0
- package/skills/principle-never-block-on-the-human/README.md +16 -0
- package/skills/principle-never-block-on-the-human/SKILL.md +23 -0
- package/skills/principle-never-block-on-the-human/agents/openai.yaml +5 -0
- package/skills/principle-outcome-oriented-execution/README.md +16 -0
- package/skills/principle-outcome-oriented-execution/SKILL.md +22 -0
- package/skills/principle-outcome-oriented-execution/agents/openai.yaml +5 -0
- package/skills/principle-prove-it-works/README.md +18 -0
- package/skills/principle-prove-it-works/SKILL.md +33 -0
- package/skills/principle-prove-it-works/agents/openai.yaml +5 -0
- package/skills/principle-redesign-from-first-principles/README.md +16 -0
- package/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
- package/skills/principle-redesign-from-first-principles/agents/openai.yaml +5 -0
- package/skills/principle-separate-before-serializing-shared-state/README.md +16 -0
- package/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
- package/skills/principle-separate-before-serializing-shared-state/agents/openai.yaml +5 -0
- package/skills/principle-sequence-verifiable-units/README.md +18 -0
- package/skills/principle-sequence-verifiable-units/SKILL.md +22 -0
- package/skills/principle-sequence-verifiable-units/agents/openai.yaml +5 -0
- package/skills/principle-subtract-before-you-add/README.md +17 -0
- package/skills/principle-subtract-before-you-add/SKILL.md +22 -0
- package/skills/principle-subtract-before-you-add/agents/openai.yaml +5 -0
- package/skills/principle-type-system-discipline/README.md +19 -0
- package/skills/principle-type-system-discipline/SKILL.md +31 -0
- package/skills/principle-type-system-discipline/agents/openai.yaml +5 -0
- package/skills/recall/README.md +23 -0
- package/skills/recall/SKILL.md +35 -0
- package/skills/recall/agents/openai.yaml +5 -0
- package/skills/reflect/README.md +24 -0
- package/skills/reflect/SKILL.md +77 -0
- package/skills/reflect/agents/openai.yaml +5 -0
- package/skills/reflect/references/divergent-reviewer.md +43 -0
- package/skills/reflect/references/judgment-reviewer.md +42 -0
- package/skills/reflect/references/synthesizer.md +56 -0
- package/skills/reflect/references/tooling-reviewer.md +57 -0
- package/skills/setup-rstack/README.md +25 -0
- package/skills/setup-rstack/SKILL.md +81 -0
- package/skills/setup-rstack/agents/openai.yaml +3 -0
- package/skills/show-me-your-work/README.md +23 -0
- package/skills/show-me-your-work/SKILL.md +82 -0
- package/skills/show-me-your-work/agents/openai.yaml +5 -0
- package/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/skills/show-me-your-work/scripts/log.sh +40 -0
- package/skills/swarm/README.md +21 -0
- package/skills/swarm/SKILL.md +46 -0
- package/skills/swarm/agents/openai.yaml +5 -0
- package/skills/tdd/README.md +21 -0
- package/skills/tdd/SKILL.md +44 -0
- package/skills/tdd/agents/openai.yaml +5 -0
- package/skills/teach/README.md +22 -0
- package/skills/teach/SKILL.md +21 -0
- package/skills/teach/agents/openai.yaml +5 -0
- package/skills/technical-writing/README.md +23 -0
- package/skills/technical-writing/SKILL.md +130 -0
- package/skills/technical-writing/agents/openai.yaml +5 -0
- package/skills/typescript-best-practices/README.md +22 -0
- package/skills/typescript-best-practices/SKILL.md +28 -0
- package/skills/typescript-best-practices/agents/openai.yaml +3 -0
- package/skills/typescript-best-practices/references/patterns.md +292 -0
- package/skills/unslop/README.md +21 -0
- package/skills/unslop/SKILL.md +80 -0
- package/skills/unslop/agents/openai.yaml +3 -0
- package/skills/why/README.md +26 -0
- package/skills/why/SKILL.md +229 -0
- package/skills/why/agents/openai.yaml +3 -0
- package/skills/why/references/epistemics.md +144 -0
- package/skills/why/references/investigator-prompt.md +103 -0
- package/skills/why/references/source-playbook.md +17 -0
- package/skills/why/references/sources/code-archaeology.md +88 -0
- package/skills/why/references/sources/databricks.md +70 -0
- package/skills/why/references/sources/datadog.md +99 -0
- package/skills/why/references/sources/incident-postmortem.md +15 -0
- package/skills/why/references/sources/linear.md +48 -0
- package/skills/why/references/sources/notion.md +55 -0
- package/skills/why/references/sources/sentry.md +100 -0
- package/skills/why/references/sources/slack.md +54 -0
- package/skills/why/references/synthesizer-prompt.md +135 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Read-only worktree prune audit. Classifies every git worktree by size, merge
|
|
3
|
+
# state, uncommitted work, remote/PR state, and the most recent chat that
|
|
4
|
+
# operated in it. Emits a table sorted by size with a suggested bucket. Never
|
|
5
|
+
# deletes anything; deletion stays a human-gated step in the playbook.
|
|
6
|
+
#
|
|
7
|
+
# Usage: worktree-audit.sh [repo-path] (defaults to the current repo)
|
|
8
|
+
set -u
|
|
9
|
+
|
|
10
|
+
repo="${1:-$(git rev-parse --show-toplevel 2>/dev/null)}"
|
|
11
|
+
[ -z "$repo" ] && { echo "not in a git repo; pass a repo path" >&2; exit 1; }
|
|
12
|
+
cd "$repo" || exit 1
|
|
13
|
+
|
|
14
|
+
# Main worktree is the first entry; everything else is a candidate.
|
|
15
|
+
main_wt=$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')
|
|
16
|
+
|
|
17
|
+
# origin/main drives the merge check. Best-effort; stale is fine for a first pass.
|
|
18
|
+
git fetch origin main --quiet 2>/dev/null || echo "warn: could not fetch origin/main; merged column may be stale" >&2
|
|
19
|
+
|
|
20
|
+
# PR state by branch, fetched once. Empty if gh is unavailable.
|
|
21
|
+
prs=$(mktemp)
|
|
22
|
+
gh pr list --author "@me" --state all --limit 1000 \
|
|
23
|
+
--json number,state,headRefName 2>/dev/null > "$prs" || echo "[]" > "$prs"
|
|
24
|
+
|
|
25
|
+
# Transcripts dir: ~/.cursor/projects/<slugified-repo-path>/agent-transcripts.
|
|
26
|
+
slug=$(printf '%s' "$main_wt" | sed 's#^/##; s#/#-#g')
|
|
27
|
+
transcripts="$HOME/.cursor/projects/$slug/agent-transcripts"
|
|
28
|
+
now=$(date +%s)
|
|
29
|
+
|
|
30
|
+
printf "SIZE\tAGE\tMERGED\tDIRTY\tREMOTE\tPR\tLAST_CHAT\tBUCKET\tWORKTREE\n"
|
|
31
|
+
|
|
32
|
+
git worktree list --porcelain | awk '/^worktree /{print $2}' | while read -r wt; do
|
|
33
|
+
[ "$wt" = "$main_wt" ] && continue
|
|
34
|
+
|
|
35
|
+
size=$(du -sh "$wt" 2>/dev/null | awk '{print $1}')
|
|
36
|
+
head=$(git -C "$wt" rev-parse HEAD 2>/dev/null)
|
|
37
|
+
head_ts=$(git -C "$wt" log -1 --format='%ct' HEAD 2>/dev/null || echo 0)
|
|
38
|
+
age=$([ "$head_ts" -gt 0 ] 2>/dev/null && echo "$(( (now - head_ts) / 86400 ))d" || echo "?")
|
|
39
|
+
|
|
40
|
+
# Squash-merged branches are not ancestors of main, so PR state is the
|
|
41
|
+
# real signal; merge-base only catches fast-forward/rebase merges.
|
|
42
|
+
git merge-base --is-ancestor "$head" origin/main 2>/dev/null && merged=YES || merged=no
|
|
43
|
+
|
|
44
|
+
# Distinguish real WIP (tracked edits) from disposable untracked scratch.
|
|
45
|
+
porcelain=$(git -C "$wt" status --porcelain 2>/dev/null)
|
|
46
|
+
if [ -z "$porcelain" ]; then dirty=clean
|
|
47
|
+
elif printf '%s\n' "$porcelain" | grep -qv '^??'; then
|
|
48
|
+
dirty="wip:$(printf '%s\n' "$porcelain" | grep -cv '^??')"
|
|
49
|
+
else dirty="scratch:$(printf '%s\n' "$porcelain" | grep -c '^??')"; fi
|
|
50
|
+
|
|
51
|
+
branch=$(git -C "$wt" symbolic-ref --quiet --short HEAD 2>/dev/null || echo "")
|
|
52
|
+
if [ -z "$branch" ]; then remote=detached
|
|
53
|
+
elif git -C "$wt" show-ref --verify --quiet "refs/remotes/origin/$branch"; then
|
|
54
|
+
[ "$(git -C "$wt" rev-parse "origin/$branch" 2>/dev/null)" = "$head" ] \
|
|
55
|
+
&& remote=pushed \
|
|
56
|
+
|| remote="ahead$(git -C "$wt" rev-list --count "origin/$branch..HEAD" 2>/dev/null)"
|
|
57
|
+
else remote=no-remote; fi
|
|
58
|
+
|
|
59
|
+
pr=$([ -n "$branch" ] && jq -r --arg b "$branch" \
|
|
60
|
+
'.[] | select(.headRefName==$b) | "#\(.number)/\(.state)"' "$prs" 2>/dev/null | head -1)
|
|
61
|
+
[ -z "$pr" ] && pr="-"
|
|
62
|
+
|
|
63
|
+
# Most recent chat whose transcript operated in this worktree. Match path
|
|
64
|
+
# followed by "/" or a quote so glint-482 does not match glint-482-r37.
|
|
65
|
+
last="-"; last_ts=0
|
|
66
|
+
if [ -d "$transcripts" ]; then
|
|
67
|
+
f=$(rg -l -e "${wt}/" -e "${wt}\"" "$transcripts" 2>/dev/null \
|
|
68
|
+
| xargs stat -f '%m %N' 2>/dev/null | sort -rn | head -1)
|
|
69
|
+
if [ -n "$f" ]; then last_ts=$(echo "$f" | awk '{print $1}')
|
|
70
|
+
last=$(date -r "$last_ts" '+%Y-%m-%d' 2>/dev/null); fi
|
|
71
|
+
fi
|
|
72
|
+
recent=$([ "$last_ts" -gt 0 ] 2>/dev/null && [ $(( (now - last_ts) / 86400 )) -le 4 ] && echo yes || echo no)
|
|
73
|
+
|
|
74
|
+
case "$dirty" in wip:*) bucket=hold-wip ;; *)
|
|
75
|
+
case "$pr" in *OPEN*) bucket=hold-open-pr ;; *)
|
|
76
|
+
if [ "$recent" = yes ]; then bucket=verify-recent-chat
|
|
77
|
+
elif [ "$merged" = YES ] || [ "$pr" != "-" ]; then bucket=safe
|
|
78
|
+
else bucket=review; fi ;;
|
|
79
|
+
esac ;;
|
|
80
|
+
esac
|
|
81
|
+
|
|
82
|
+
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" \
|
|
83
|
+
"$size" "$age" "$merged" "$dirty" "$remote" "$pr" "$last" "$bucket" "$wt"
|
|
84
|
+
done | sort -t$'\t' -k1,1 -rh
|
|
85
|
+
|
|
86
|
+
rm -f "$prs"
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Boundary discipline
|
|
2
|
+
|
|
3
|
+
Validate at the edges. Trust internal types.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You wire validation, error handling, or framework adapters.
|
|
8
|
+
- You parse external input (CLI args, config files, network payloads, third-party APIs).
|
|
9
|
+
- You decide where a guard or nil-check belongs.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Place all validation and type narrowing at system boundaries where untrusted data enters. Inside the system, trust the typed data and skip re-validation. Keep business logic in pure functions with no framework dependencies. Expose domain concepts at the boundary, not transport or wire types.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-boundary-discipline
|
|
3
|
+
description: "Apply when wiring validation, error handling, or framework adapters. Concentrate guards at system boundaries (CLI, config, network, external APIs); trust internal types and keep business logic in pure functions."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Boundary Discipline
|
|
8
|
+
|
|
9
|
+
Place validation, type narrowing, and error handling at system boundaries. Trust internal code unconditionally. Business logic lives in pure functions; the shell is thin and mechanical.
|
|
10
|
+
|
|
11
|
+
**Why:** Scattered validation is noisy, redundant, and gives a false sense of safety. Validate data once at the boundary. Keep logic out of framework wiring so it can be tested without the framework.
|
|
12
|
+
|
|
13
|
+
**The pattern:**
|
|
14
|
+
- **At boundaries** (CLI args, config files, external APIs, network protocols): validate, return errors, handle defensively.
|
|
15
|
+
- **Inside the system:** typed data, error propagation, no re-validation. Trust the types.
|
|
16
|
+
- **Across the boundary.** Expose domain concepts, not the boundary's private representation. Keep general-purpose mechanism inside and special-purpose policy at the edge.
|
|
17
|
+
|
|
18
|
+
**Applications:**
|
|
19
|
+
|
|
20
|
+
Validation and error handling:
|
|
21
|
+
- Validate config at parse time (the boundary), not inside business logic
|
|
22
|
+
- Parse raw data into domain types at the boundary
|
|
23
|
+
- Do not re-export transport, storage, framework, or wire types through the public surface
|
|
24
|
+
- No redundant nil checks deep in call chains if the boundary already validated
|
|
25
|
+
|
|
26
|
+
Code organization:
|
|
27
|
+
- Business logic in pure functions with no framework dependencies
|
|
28
|
+
- Parse functions: pure transforms from raw bytes to typed state
|
|
29
|
+
- Prompt construction: structured state in, string out
|
|
30
|
+
- Scoring and assessment: pure transforms from state to results
|
|
31
|
+
|
|
32
|
+
**The tests:**
|
|
33
|
+
- "Is this data crossing a system boundary right now?" If not, validation is redundant.
|
|
34
|
+
- "Can this be a pure function that the shell just calls?" If yes, extract it.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Build the lever
|
|
2
|
+
|
|
3
|
+
When the work is not trivial, build the tool that does it instead of doing it by hand.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You face non-trivial edits, migrations, analyses, or checks.
|
|
8
|
+
- A reviewer needs a rerunnable artifact to verify the work.
|
|
9
|
+
- You fan work out to subagents and need a shared recipe.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Do the first unit by hand to learn the recipe, then build a codemod, script, or generator that handles the rest. The tool is one artifact a reviewer can read and rerun. A deterministic script turns "trust me" into "run this." Skip the lever only when the task is a couple of obvious edits you can see at a glance.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-build-the-lever
|
|
3
|
+
description: "Apply to any non-trivial work, not just bulk work: edits, migrations, analyses, checks. Build the tool that does it or proves it (codemod, script, generator, or a skill your subagents follow) instead of working by hand. The tool is the artifact a reviewer can rerun."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
# Build the Lever
|
|
7
|
+
|
|
8
|
+
When the work isn't trivial, build the tool that does it instead of doing it by hand.
|
|
9
|
+
|
|
10
|
+
**Why:** Two payoffs. Throughput: a codemod, generator, or script does the work the same way every time and reruns for free. Confidence: the tool is one artifact a reviewer can read and rerun to check the work. Hand-done changes can only be re-verified by redoing them. A deterministic script turns "trust me" into "run this".
|
|
11
|
+
|
|
12
|
+
**Pattern:** Default to building the lever. Skip it only when the task is genuinely trivial, a couple of obvious edits you can see at a glance.
|
|
13
|
+
|
|
14
|
+
- Do the first unit by hand to learn the recipe, then build the tool. Prove it by rerunning it on that unit and diffing against your hand-done version. Make the lever safe to rerun. A reviewer will.
|
|
15
|
+
- Codemod or script for edits, generator for repetitive files, a dump-to-sqlite query for analysis, a rerunnable check for verification.
|
|
16
|
+
- A deterministic lever beats fan-out. If the tool can process every unit in one pass, run it yourself; don't fan out delegates to hand-apply what a script can do.
|
|
17
|
+
- When you fan work out to subagents, write the lever as a skill they all read: the recipe, the verification contract, and the do-not-touch fences in one artifact, so every delegate inherits the same hardened version instead of re-explaining it per prompt and watching each one drift. Keep it outside the delegates' write scope so they can't quietly edit the contract.
|
|
18
|
+
- Applying this principle produces a file. If you cited it and there is no codemod, script, generator, or delegate skill in the diff, you didn't apply it.
|
|
19
|
+
- Commit the lever when the work outlives the session, so the next run reruns it instead of redoing it.
|
|
20
|
+
|
|
21
|
+
**Balance:** The bar is triviality, not repetition. A one-off still earns a lever when the lever is what makes the work checkable. Per the [Laziness Protocol](../principle-laziness-protocol/SKILL.md), build the smallest script that does or proves the job, never a framework.
|
|
22
|
+
|
|
23
|
+
Distinct from [Encode Lessons in Structure](../principle-encode-lessons-in-structure/SKILL.md), which makes a recurring instruction a durable guardrail. This is throughput and reviewability on the work in front of you. For scripting the verification itself, see [Prove It Works](../principle-prove-it-works/SKILL.md).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Encode lessons in structure
|
|
2
|
+
|
|
3
|
+
Turn recurring fixes into mechanisms, not instructions.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You catch yourself writing the same instruction a second time.
|
|
8
|
+
- A human correction or test failure reveals a recurring pattern.
|
|
9
|
+
- A textual rule could instead be a lint, metadata flag, runtime check, or script.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
When a fix recurs, encode it as the strongest structural mechanism the situation allows: an unrepresentable state, a lint rule, a canonical helper, or a runtime check. Delete the instruction it replaces. If the fix genuinely requires judgment, make the instruction more visible and add a failure-mode example.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-encode-lessons-in-structure
|
|
3
|
+
description: "Apply when you catch yourself writing the same instruction a second time, or notice a recurring correction. Encode the rule as a lint, metadata flag, runtime check, or script instead of more text."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Encode Lessons in Structure
|
|
8
|
+
|
|
9
|
+
Encode recurring fixes in mechanisms (tools, code, metadata, automation) instead of textual instructions. Every error, human correction, and unexpected outcome is a learning signal. Capture it, route it, and close the loop.
|
|
10
|
+
|
|
11
|
+
**Why:** Textual instructions are easy to miss. They require the reader to notice, remember, and comply. Structural mechanisms (lint rules, metadata flags, runtime checks, automation scripts) enforce the rule without cooperation.
|
|
12
|
+
|
|
13
|
+
**Pattern:**
|
|
14
|
+
When you catch yourself writing the same instruction a second time:
|
|
15
|
+
1. Ask: can this be a lint rule, a metadata flag, a runtime check, or a script?
|
|
16
|
+
2. If yes, encode it. Delete the instruction
|
|
17
|
+
3. If no (genuinely requires judgment), make the instruction more prominent and add an example of the failure mode
|
|
18
|
+
|
|
19
|
+
**Pick the strongest rung.** When more than one mechanism would work, choose the strongest the situation allows (an unrepresentable state that cannot compile, then a lint or banned API that fails CI, then a canonical helper, then a runtime check), because agents copy whatever the surrounding code already does and a weaker guard becomes the next template.
|
|
20
|
+
|
|
21
|
+
**Corollary:** Don't paper over symptoms. If the fix is structural, ONLY use the structural fix. The instruction IS the symptom.
|
|
22
|
+
|
|
23
|
+
**Feedback loop:**
|
|
24
|
+
- **Capture every correction.** When the human intervenes or tests fail, decide if it's a one-off or a pattern.
|
|
25
|
+
- **Route to the right layer.** One-off -> brain note. Recurring fix -> skill or lint rule. Systemic issue -> principle.
|
|
26
|
+
- **Close the loop.** Don't just record. Apply now or create a concrete todo.
|
|
27
|
+
|
|
28
|
+
**Anti-patterns:**
|
|
29
|
+
- Acknowledging without recording ("I'll keep that in mind" does not persist)
|
|
30
|
+
- Recording without routing (a brain note about a lint rule that should exist is wasted unless the lint rule gets implemented)
|
|
31
|
+
- Fixing without generalizing (fixing one instance while leaving the recurring pattern intact)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Exhaust the design space
|
|
2
|
+
|
|
3
|
+
When the right answer is not obvious, explore several alternatives before committing.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- A novel UI interaction has no precedent in the codebase.
|
|
8
|
+
- An architectural decision has multiple viable approaches.
|
|
9
|
+
- User experience depends on feel, not logic.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Build 2-3 competing prototypes or sketches and compare them side by side. A second flavor of the same shape does not count. Only commit after the comparison. Skip this for mechanical work, bug fixes, or changes where constraints dictate a single approach.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-exhaust-the-design-space
|
|
3
|
+
description: "Apply when facing a novel UI interaction or architectural decision with no precedent in the codebase. Build 2-3 competing prototypes and compare side by side before committing."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Exhaust the Design Space
|
|
8
|
+
|
|
9
|
+
When a novel interaction or architectural decision has no established precedent, explore several concrete alternatives before implementation. Building the wrong thing costs more than exploring three options.
|
|
10
|
+
|
|
11
|
+
**The rule.** When the right answer is not obvious, build 2-3 competing prototypes or sketches. Compare them side by side. Only then commit. Design it twice is this rule by another name. A second flavor of the first shape does not count.
|
|
12
|
+
|
|
13
|
+
**When it applies:**
|
|
14
|
+
- Novel UI interactions (no prior art in the codebase)
|
|
15
|
+
- Architectural choices with multiple viable approaches
|
|
16
|
+
- Product design decisions where user experience depends on feel, not logic
|
|
17
|
+
|
|
18
|
+
**When it doesn't:**
|
|
19
|
+
- Mechanical implementation where the pattern is established
|
|
20
|
+
- Bug fixes or refactors with a clear target state
|
|
21
|
+
- Changes where constraints dictate a single viable approach
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Experience first
|
|
2
|
+
|
|
3
|
+
When implementation convenience conflicts with user delight, choose delight.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- Product, UX, or feature-scope tradeoffs come up.
|
|
8
|
+
- You decide between shipping more features rough or fewer features polished.
|
|
9
|
+
- You weigh implementation ease against the experience of any consumer (end user, API caller, future maintainer).
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
The product is the experience. Ship less and ship better. Every feature, control, and option must earn its place. Sweat details like transitions, alignment, spacing, and error states. The "user" includes anyone who consumes the work: end users, API callers, and the next engineer who reads the code.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-experience-first
|
|
3
|
+
description: "Apply when product, UX, or feature-scope tradeoffs come up. Choose user delight over implementation convenience; ship fewer polished features over more rough ones."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Experience First
|
|
8
|
+
|
|
9
|
+
The product is the experience. Every technical decision either helps or hurts it. When implementation convenience conflicts with user delight, choose delight.
|
|
10
|
+
|
|
11
|
+
- Say no to 1,000 things (every feature, control, and option must earn its place)
|
|
12
|
+
- Ship less, ship better (polished experience with three features beats rough one with ten)
|
|
13
|
+
- Prototype before committing (design decisions are cheaper in throwaway HTML than production code)
|
|
14
|
+
- Sweat the details (transitions, alignment, spacing, feedback, error states)
|
|
15
|
+
- Tighten the core loop (every feature should serve the central workflow or get out of the way)
|
|
16
|
+
|
|
17
|
+
The user is whoever consumes the work. For a UI that is the end user. For a library or an internal API it is the colleague who imports it. The engineer who maintains the code next is a user too. Weigh their experience the same way, and explain impact from their seat.
|
|
18
|
+
|
|
19
|
+
Foundations should serve the experience, not the other way around. Foundational thinking governs the *sequence* of work; this principle governs the *target*.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Fix root causes
|
|
2
|
+
|
|
3
|
+
Trace every problem to its root cause and fix it there. Do not paper over symptoms.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You debug a failure, crash, or unexpected behavior.
|
|
8
|
+
- You are tempted to add a guard or nil-check to silence an error.
|
|
9
|
+
- Something breaks after a restart and you suspect state, not code.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Reproduce first. Ask "why" until you reach the root cause. Resist adding guards that silence crashes without fixing the underlying bug. When something fails after a restart, suspect stale persistent state before suspecting code. Check for the same pattern across the codebase and fix all instances.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-fix-root-causes
|
|
3
|
+
description: "Apply when debugging. Trace each symptom to its root cause and fix it there; reproduce first, ask why until you reach it, resist nil-check guards that silence crashes."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Fix Root Causes
|
|
8
|
+
|
|
9
|
+
When debugging, do not paper over symptoms. Trace every problem to its root cause and fix it there.
|
|
10
|
+
|
|
11
|
+
**Why:** Symptom fixes accumulate. Each workaround makes the system harder to reason about, and the real bug remains. Root-cause fixes are slower upfront but reduce total debugging time.
|
|
12
|
+
|
|
13
|
+
**Pattern:**
|
|
14
|
+
- Reproduce first (if you can't reproduce it, you can't verify your fix)
|
|
15
|
+
- Ask "why" until you hit the root cause
|
|
16
|
+
- Resist the urge to add guards (adding a nil check to silence a crash is a symptom fix)
|
|
17
|
+
- If a workaround needs a paragraph-long comment to justify it, the code is wrong (fix the code, not the comment)
|
|
18
|
+
- Check for the pattern, not just the instance (grep for the same pattern, fix all instances)
|
|
19
|
+
- When stuck, instrument. Don't guess (add logging, read the actual error)
|
|
20
|
+
|
|
21
|
+
**Restart bugs: suspect state before code**
|
|
22
|
+
|
|
23
|
+
Code doesn't change between runs. State does. When something "fails after restart," suspect stale persistent state first: config files, caches, lock files, serialized state. If clearing a state file restores behavior, prioritize state validation as the fix.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Foundational thinking
|
|
2
|
+
|
|
3
|
+
Get the data structures right so downstream code becomes obvious.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You choose core types and data structures before writing logic.
|
|
8
|
+
- You sequence scaffold-vs-feature work.
|
|
9
|
+
- You decide what concurrent actors share.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Define data shapes before writing logic. The right structure makes downstream code obvious; a late data-structure change is a rewrite. Sequence for option value: scaffold (CI, tests, shared types) before features. Before sharing state between actors, ask what happens if another actor modifies it concurrently. Remove dead weight first, then lay foundations.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-foundational-thinking
|
|
3
|
+
description: "Apply before writing logic: choosing core types and data structures, sequencing scaffold-vs-feature work, asking what concurrent actors share. Get the data structures right so downstream code becomes obvious."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Foundational Thinking
|
|
8
|
+
|
|
9
|
+
**Structural decisions** protect option value. **Code-level decisions** protect simplicity. Over-engineering is often a premature decision that closes doors. The right foundational data structure keeps doors open.
|
|
10
|
+
|
|
11
|
+
**Data structures first.** Get the data shape right before writing logic. The right shape makes downstream code obvious. Define core types early, trace every access pattern, and choose structures that match the dominant paths. A data-structure change late is a rewrite. Early, it is often a one-line diff.
|
|
12
|
+
|
|
13
|
+
At code level, DRY the structure, not every line. Types and data models should converge. Three similar statements still beat a premature abstraction. Prefer explicit over clever. Test behavior and edge cases, not line counts.
|
|
14
|
+
|
|
15
|
+
**Concurrency corollary.** Before sharing state between actors, ask "what happens if another actor modifies this concurrently?" If not "nothing", isolate.
|
|
16
|
+
|
|
17
|
+
**Scaffold first.** If something helps every later phase, do it first. Ask "does every subsequent phase benefit from this existing?" CI, linting, test infrastructure, and shared types are scaffold. Sequence for option value: setup before features, tests before fixes. Keep commits small and single-purpose.
|
|
18
|
+
|
|
19
|
+
Each increment should land a coherent abstraction or deepen one that exists. Do not spread a new capability across callers as special-case coordination.
|
|
20
|
+
|
|
21
|
+
Subtraction comes before scaffolding: remove dead weight first, then lay foundations.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Guard the context window
|
|
2
|
+
|
|
3
|
+
Every token that enters the context window should earn its place.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- Context is filling up with large outputs, long files, or repeated reads.
|
|
8
|
+
- You plan fan-out work across subagents.
|
|
9
|
+
- You decide whether to inline or externalize reference material.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
The context window is finite and non-renewable within a session. Route verbose outputs and large documents to subagents. Keep summaries in the main thread, not raw payloads. Do not read what you will not use. Size phases and cap scope to stay within budget.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-guard-the-context-window
|
|
3
|
+
description: "Apply when context is filling up: large outputs, long files, repeated reads, fan-out planning. Route bulk to subagents; keep summaries in the main thread, not raw payloads."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Guard the Context Window
|
|
8
|
+
|
|
9
|
+
The context window is finite and non-renewable within a session. Every token that enters should earn its place.
|
|
10
|
+
|
|
11
|
+
**Why:** Context overflow degrades reasoning quality, creates compression artifacts, and halts progress. Unlike compute or time, context spent inside a session cannot be reclaimed.
|
|
12
|
+
|
|
13
|
+
**Pattern:**
|
|
14
|
+
- **Isolate large payloads.** Route verbose outputs, screenshots, and large documents to subagents. The main context gets summaries, not raw data.
|
|
15
|
+
- **Don't read what you won't use.** Read selectively based on relevance. If a file isn't needed for the current task, skip it.
|
|
16
|
+
- **Keep frequently used content inline.** Templates and references used on every invocation belong in the skill file, not in separate files that cost a read each time.
|
|
17
|
+
- **Size phases and cap scope.** Limit files per phase, set turn budgets, account for mechanism costs.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Laziness protocol
|
|
2
|
+
|
|
3
|
+
Aim for the most result with the least code and complexity.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You refactor, evaluate diff size, or review code.
|
|
8
|
+
- You are tempted to add abstractions, layers, or signal threading.
|
|
9
|
+
- You choose between deletion and addition.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Prefer deletion over addition. Maintain a flat call hierarchy. Minimize the diff by making the smallest change that solves the problem. Before threading a new signal through types, schemas, or pipelines, look for a more direct path. If a human developer would find the code exhausting to maintain, it is a bad solution.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-laziness-protocol
|
|
3
|
+
description: "Apply when refactoring, evaluating diff size, or tempted to add abstractions, layers, or signal threading. Bias toward deletion and the smallest change that solves the problem."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Laziness Protocol
|
|
8
|
+
|
|
9
|
+
Writing code is cheap for you, which makes over-engineering easy. Counter it by borrowing a human maintainer's fatigue. Aim for the most result with the least code and complexity.
|
|
10
|
+
|
|
11
|
+
- **Prefer deletion.** When asked to refactor or improve, look for removals before additions.
|
|
12
|
+
- **Maintain a flat call hierarchy.** Avoid deep call chains. A rich interface that hides substantial work is not a deep call chain. If answering a question requires tracing through more than 3 files or layers, flatten it.
|
|
13
|
+
- **Consolidate decisions.** Do not repeat the same choice in several places. Put it behind one source of truth and pass the result as a simple flag.
|
|
14
|
+
- **Minimize the diff.** Make the smallest change that solves the problem. Fewer lines beat "elegant" boilerplate.
|
|
15
|
+
- **Question the threading.** If a task asks you to pass a new signal through types, schemas, pipelines, or similar layers, stop and look for a more direct path.
|
|
16
|
+
- **Sweat the small leaks.** Remove tiny pass-throughs, representation leaks, and duplicated choices before they spread. Small leaks compound into permanent coordination costs.
|
|
17
|
+
|
|
18
|
+
**Prime directive:** If a human developer would find the code exhausting to maintain, it is a bad solution. Be lazy. Stay simple.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Make operations idempotent
|
|
2
|
+
|
|
3
|
+
Design operations to converge to the correct state no matter how many times they run.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You design commands, lifecycle steps, or processing loops.
|
|
8
|
+
- Crashes, restarts, and retries are normal operating conditions.
|
|
9
|
+
- Partial prior runs might leave behind stale state.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Every state-mutating operation must answer two questions: "What happens if this runs twice?" and "What happens if the previous run crashed halfway?" Use convergent startup, content-based cleanup, and self-healing locks. If re-execution does not converge to the same end state, add a reconciliation step.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-make-operations-idempotent
|
|
3
|
+
description: "Apply when designing commands, lifecycle steps, or processing loops that run amid crashes, restarts, and retries. Converge to the same end state regardless of partial prior runs."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Make Operations Idempotent
|
|
8
|
+
|
|
9
|
+
Design operations so they converge to the correct state regardless of how many times they run or where they start from. Every state-mutating operation should answer: "What happens if this runs twice? What happens if the previous run crashed halfway?"
|
|
10
|
+
|
|
11
|
+
**Why:** Commands, lifecycle operations, and processing loops run where crashes, restarts, and retries are normal. If partial state changes the next run's outcome, every restart becomes a debugging session.
|
|
12
|
+
|
|
13
|
+
**The pattern:**
|
|
14
|
+
- Convergent startup: scan for existing state, clean stale artifacts, adopt live sessions
|
|
15
|
+
- Content-based cleanup: compare by content equivalence, not creation order
|
|
16
|
+
- Self-healing locks: use PID-based stale lock detection
|
|
17
|
+
- Idempotent scheduling: failed work respawns cleanly, fresh input regenerated after each cycle
|
|
18
|
+
|
|
19
|
+
**The test:**
|
|
20
|
+
1. What happens if this runs twice in a row?
|
|
21
|
+
2. What happens if the previous run crashed at every possible point?
|
|
22
|
+
3. Does re-execution converge to the same end state?
|
|
23
|
+
|
|
24
|
+
If any answer is "it depends on what state was left behind," the operation needs a reconciliation step.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Migrate callers then delete legacy APIs
|
|
2
|
+
|
|
3
|
+
When a new API replaces an old one, migrate callers and remove the old API in the same wave.
|
|
4
|
+
|
|
5
|
+
## When it applies
|
|
6
|
+
|
|
7
|
+
- You introduce a new internal API while old callers still exist.
|
|
8
|
+
- No external users depend on backward compatibility.
|
|
9
|
+
- The project can absorb coordinated breaking changes.
|
|
10
|
+
|
|
11
|
+
## The rule
|
|
12
|
+
|
|
13
|
+
Do not keep legacy API paths alive just because internal callers still use them. Inventory callers, migrate them, and delete the old API immediately. Treat temporary adapters as exceptional and time-boxed. Update tests to assert the new contract and delete tests that only protect pre-refactor details.
|
|
14
|
+
|
|
15
|
+
## Related
|
|
16
|
+
|
|
17
|
+
- [Full rule](SKILL.md)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-migrate-callers-then-delete-legacy-apis
|
|
3
|
+
description: "Apply when introducing a new internal API while old callers still exist. Migrate callers and delete the old API in the same wave instead of preserving compatibility layers."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Migrate Callers Then Delete Legacy APIs
|
|
8
|
+
|
|
9
|
+
When we decide a new API is the right design, migrate callers and remove the old API in the same refactor wave instead of preserving compatibility layers.
|
|
10
|
+
|
|
11
|
+
**Rule:**
|
|
12
|
+
- Do not keep legacy API paths alive only because internal callers still exist
|
|
13
|
+
- Inventory callers, migrate them, and delete the old API immediately
|
|
14
|
+
- Treat temporary adapters as exceptional and time-boxed, not default architecture
|
|
15
|
+
- Update tests to assert the new contract, and delete tests that only protect pre-refactor implementation details
|
|
16
|
+
|
|
17
|
+
**When this applies:**
|
|
18
|
+
- No external users depend on backward compatibility
|
|
19
|
+
- The project can absorb coordinated breaking changes
|
|
20
|
+
- The new API is part of a simplification or refactor initiative
|
|
21
|
+
|
|
22
|
+
Keeping both old and new APIs creates dual-path complexity, slows cleanup, and makes the codebase feel append-only.
|