@krtclcdy/tersio 2.25.6 → 2.25.7
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/README.md +30 -7
- package/dist/bench/code-out/pfull-0/debounce.js +13 -0
- package/dist/bench/code-out/pfull-0/deepClone.js +18 -0
- package/dist/bench/code-out/pfull-0/groupBy.js +15 -0
- package/dist/bench/code-out/pfull-1/debounce.js +13 -0
- package/dist/bench/code-out/pfull-1/deepClone.js +17 -0
- package/dist/bench/code-out/pfull-1/groupBy.js +14 -0
- package/dist/bench/code-out/pfull-2/debounce.js +13 -0
- package/dist/bench/code-out/pfull-2/deepClone.js +18 -0
- package/dist/bench/code-out/pfull-2/groupBy.js +15 -0
- package/dist/bench/code-out/pfull-3/debounce.js +12 -0
- package/dist/bench/code-out/pfull-3/deepClone.js +17 -0
- package/dist/bench/code-out/pfull-3/groupBy.js +7 -0
- package/dist/bench/code-out/pfull-4/debounce.js +10 -0
- package/dist/bench/code-out/pfull-4/deepClone.js +17 -0
- package/dist/bench/code-out/pfull-4/groupBy.js +14 -0
- package/dist/bench/code-out/plite-0/debounce.js +13 -0
- package/dist/bench/code-out/plite-0/deepClone.js +18 -0
- package/dist/bench/code-out/plite-0/groupBy.js +15 -0
- package/dist/bench/code-out/plite-1/debounce.js +13 -0
- package/dist/bench/code-out/plite-1/deepClone.js +17 -0
- package/dist/bench/code-out/plite-1/groupBy.js +11 -0
- package/dist/bench/code-out/plite-2/debounce.js +12 -0
- package/dist/bench/code-out/plite-2/deepClone.js +17 -0
- package/dist/bench/code-out/plite-2/groupBy.js +14 -0
- package/dist/bench/code-out/plite-3/debounce.js +12 -0
- package/dist/bench/code-out/plite-3/deepClone.js +17 -0
- package/dist/bench/code-out/plite-3/groupBy.js +14 -0
- package/dist/bench/code-out/plite-4/debounce.js +12 -0
- package/dist/bench/code-out/plite-4/deepClone.js +17 -0
- package/dist/bench/code-out/plite-4/groupBy.js +14 -0
- package/dist/bench/code-out/pultra-0/debounce.js +12 -0
- package/dist/bench/code-out/pultra-0/deepClone.js +20 -0
- package/dist/bench/code-out/pultra-0/groupBy.js +14 -0
- package/dist/bench/code-out/pultra-1/debounce.js +10 -0
- package/dist/bench/code-out/pultra-1/deepClone.js +17 -0
- package/dist/bench/code-out/pultra-1/groupBy.js +7 -0
- package/dist/bench/code-out/pultra-2/debounce.js +13 -0
- package/dist/bench/code-out/pultra-2/deepClone.js +18 -0
- package/dist/bench/code-out/pultra-2/groupBy.js +15 -0
- package/dist/bench/code-out/pultra-3/debounce.js +13 -0
- package/dist/bench/code-out/pultra-3/deepClone.js +18 -0
- package/dist/bench/code-out/pultra-3/groupBy.js +15 -0
- package/dist/bench/code-out/pultra-4/debounce.js +13 -0
- package/dist/bench/code-out/pultra-4/deepClone.js +18 -0
- package/dist/bench/code-out/pultra-4/groupBy.js +15 -0
- package/dist/bench/code-out/run-0/debounce.js +12 -0
- package/dist/bench/code-out/run-0/deepClone.js +17 -0
- package/dist/bench/code-out/run-0/groupBy.js +14 -0
- package/dist/bench/code-out/run-1/debounce.js +13 -0
- package/dist/bench/code-out/run-1/deepClone.js +15 -0
- package/dist/bench/code-out/run-1/groupBy.js +13 -0
- package/dist/bench/code-out/run-2/debounce.js +12 -0
- package/dist/bench/code-out/run-2/deepClone.js +18 -0
- package/dist/bench/code-out/run-2/groupBy.js +13 -0
- package/dist/bench/code-out/run-3/debounce.js +12 -0
- package/dist/bench/code-out/run-3/deepClone.js +18 -0
- package/dist/bench/code-out/run-3/groupBy.js +14 -0
- package/dist/bench/code-out/run-4/debounce.js +12 -0
- package/dist/bench/code-out/run-4/deepClone.js +16 -0
- package/dist/bench/code-out/run-4/groupBy.js +13 -0
- package/dist/cli/banner.js +1 -2
- package/dist/cli/common.js +1 -1
- package/dist/cli/doctor.js +48 -12
- package/dist/cli/hosts.js +1 -2
- package/dist/cli/install.js +7 -2
- package/dist/cli/manifest.js +25 -5
- package/dist/cli/uninstall.js +1 -1
- package/dist/extensions/caveman/index.js +6 -2
- package/dist/extensions/caveman/rule-lite.md +77 -0
- package/dist/extensions/caveman/rule-megacave-lite.md +59 -0
- package/dist/extensions/caveman/rule-megacave-ultra.md +59 -0
- package/dist/extensions/caveman/rule.md +1 -1
- package/dist/extensions/combo/index.js +26 -7
- package/dist/extensions/pstack/index.js +3 -1
- package/dist/extensions/pstack/rule.md +88 -12
- package/dist/extensions/rtk/session.js +18 -10
- package/dist/extensions/shared/rtk-eligible.js +84 -0
- package/dist/extensions/shared/rtk-gain.js +1 -1
- package/dist/extensions/shared/sqlite.js +7 -13
- package/dist/extensions/shared/status.js +1 -2
- package/dist/extensions/shared/usage-ledger.js +102 -20
- package/extensions/caveman/index.ts +6 -2
- package/extensions/caveman/rule-lite.md +77 -0
- package/extensions/caveman/rule-megacave-lite.md +59 -0
- package/extensions/caveman/rule-megacave-ultra.md +59 -0
- package/extensions/caveman/rule.md +1 -1
- package/extensions/combo/index.ts +27 -7
- package/extensions/pstack/index.ts +3 -1
- package/extensions/pstack/playbooks/authoring-a-skill.md +12 -0
- package/extensions/pstack/playbooks/autonomous-run.md +13 -0
- package/extensions/pstack/playbooks/autopilot-full.md +13 -0
- package/extensions/pstack/playbooks/autopilot-stack.md +16 -0
- package/extensions/pstack/playbooks/babysit.md +23 -0
- package/extensions/pstack/playbooks/bug-fix.md +15 -0
- package/extensions/pstack/playbooks/eval.md +25 -0
- package/extensions/pstack/playbooks/feature.md +21 -0
- package/extensions/pstack/playbooks/hillclimb.md +21 -0
- package/extensions/pstack/playbooks/investigation.md +14 -0
- package/extensions/pstack/playbooks/multi-phase-plan.md +155 -0
- package/extensions/pstack/playbooks/opening-a-pr.md +34 -0
- package/extensions/pstack/playbooks/orchestrate.md +111 -0
- package/extensions/pstack/playbooks/pause-safely.md +10 -0
- package/extensions/pstack/playbooks/perf-issue.md +25 -0
- package/extensions/pstack/playbooks/prototype.md +14 -0
- package/extensions/pstack/playbooks/refactoring.md +16 -0
- package/extensions/pstack/playbooks/runtime-forensics.md +11 -0
- package/extensions/pstack/playbooks/session-pickup.md +11 -0
- package/extensions/pstack/playbooks/shipping.md +17 -0
- package/extensions/pstack/playbooks/trace-forensics.md +14 -0
- package/extensions/pstack/playbooks/visual-parity.md +11 -0
- package/extensions/pstack/playbooks/worktree-cleanup.md +12 -0
- package/extensions/pstack/principles/attack-the-premise.md +22 -0
- package/extensions/pstack/principles/boundary-discipline.md +33 -0
- package/extensions/pstack/principles/build-the-lever.md +22 -0
- package/extensions/pstack/principles/encode-lessons-in-structure.md +10 -0
- package/extensions/pstack/principles/exhaust-the-design-space.md +8 -0
- package/extensions/pstack/principles/experience-first.md +18 -0
- package/extensions/pstack/principles/explain-the-number.md +16 -0
- package/extensions/pstack/principles/fix-root-causes.md +23 -0
- package/extensions/pstack/principles/foundational-thinking.md +20 -0
- package/extensions/pstack/principles/guard-the-context-window.md +11 -0
- package/extensions/pstack/principles/laziness-protocol.md +9 -0
- package/extensions/pstack/principles/make-operations-idempotent.md +23 -0
- package/extensions/pstack/principles/migrate-callers-then-delete-legacy-apis.md +21 -0
- package/extensions/pstack/principles/minimize-reader-load.md +17 -0
- package/extensions/pstack/principles/model-the-domain.md +23 -0
- package/extensions/pstack/principles/never-block-on-the-human.md +14 -0
- package/extensions/pstack/principles/outcome-oriented-execution.md +20 -0
- package/extensions/pstack/principles/prove-it-works.md +21 -0
- package/extensions/pstack/principles/redesign-from-first-principles.md +15 -0
- package/extensions/pstack/principles/separate-before-serializing-shared-state.md +15 -0
- package/extensions/pstack/principles/sequence-verifiable-units.md +16 -0
- package/extensions/pstack/principles/subtract-before-you-add.md +17 -0
- package/extensions/pstack/principles/test-behavior-not-implementation.md +20 -0
- package/extensions/pstack/principles/type-system-discipline.md +17 -0
- package/extensions/pstack/references/bugbot-triage.md +142 -0
- package/extensions/pstack/rule.md +88 -12
- package/extensions/pstack/skills/architect/SKILL.md +78 -0
- package/extensions/pstack/skills/architect/references/design-red-flags.md +57 -0
- package/extensions/pstack/skills/architect/references/rationale-template.md +35 -0
- package/extensions/pstack/skills/architect/references/runner-prompt.md +20 -0
- package/extensions/pstack/skills/arena/SKILL.md +47 -0
- package/extensions/pstack/skills/benchmark-checklist/SKILL.md +38 -0
- package/extensions/pstack/skills/blast-radius/SKILL.md +49 -0
- package/extensions/pstack/skills/bro/SKILL.md +6 -0
- package/extensions/pstack/skills/correct/SKILL.md +31 -0
- package/extensions/pstack/skills/figure-it-out/SKILL.md +51 -0
- package/extensions/pstack/skills/how/SKILL.md +35 -0
- package/extensions/pstack/skills/how/references/explainer-prompt.md +55 -0
- package/extensions/pstack/skills/how/references/explorer-prompt.md +35 -0
- package/extensions/pstack/skills/interrogate/SKILL.md +73 -0
- package/extensions/pstack/skills/interrogate/references/code-quality-review.md +47 -0
- package/extensions/pstack/skills/interrogate/references/lead-judgment.md +58 -0
- package/extensions/pstack/skills/interrogate/references/reviewer-prompt.md +62 -0
- package/extensions/pstack/skills/interrogate/references/rubric.md +77 -0
- package/extensions/pstack/skills/no-comments/SKILL.md +23 -0
- package/extensions/pstack/skills/reflect/SKILL.md +66 -0
- package/extensions/pstack/skills/reflect/references/divergent-reviewer.md +38 -0
- package/extensions/pstack/skills/reflect/references/judgment-reviewer.md +37 -0
- package/extensions/pstack/skills/reflect/references/synthesizer.md +56 -0
- package/extensions/pstack/skills/reflect/references/tooling-reviewer.md +48 -0
- package/extensions/pstack/skills/show-me-your-work/SKILL.md +81 -0
- package/extensions/pstack/skills/swarm/SKILL.md +45 -0
- package/extensions/pstack/skills/tdd/SKILL.md +41 -0
- package/extensions/pstack/skills/technical-writing/SKILL.md +105 -0
- package/extensions/pstack/skills/unslop/SKILL.md +61 -0
- package/extensions/pstack/skills/why/SKILL.md +97 -0
- package/extensions/pstack/skills/why/references/epistemics.md +71 -0
- package/extensions/pstack/skills/why/references/investigator-prompt.md +84 -0
- package/extensions/pstack/skills/why/references/source-playbook.md +17 -0
- package/extensions/pstack/skills/why/references/sources/code-archaeology.md +51 -0
- package/extensions/pstack/skills/why/references/sources/databricks.md +70 -0
- package/extensions/pstack/skills/why/references/sources/datadog.md +97 -0
- package/extensions/pstack/skills/why/references/sources/incident-postmortem.md +5 -0
- package/extensions/pstack/skills/why/references/sources/linear.md +48 -0
- package/extensions/pstack/skills/why/references/sources/notion.md +55 -0
- package/extensions/pstack/skills/why/references/sources/sentry.md +66 -0
- package/extensions/pstack/skills/why/references/sources/slack.md +17 -0
- package/extensions/pstack/skills/why/references/synthesizer-prompt.md +129 -0
- package/extensions/rtk/session.ts +17 -9
- package/extensions/shared/rtk-eligible.ts +83 -0
- package/extensions/shared/rtk-gain.ts +1 -1
- package/extensions/shared/sqlite.ts +7 -13
- package/extensions/shared/status.ts +1 -2
- package/extensions/shared/usage-ledger.ts +97 -19
- package/extensions/timing/index.ts +1 -2
- package/package.json +7 -4
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: principle-type-system-discipline
|
|
3
|
+
description: "Apply when designing types, reviewing a function signature, or writing code in any statically-typed language. Make illegal states unrepresentable, brand semantic primitives, parse external data at boundaries, refuse to lie to the compiler, exhaust variants, derive from authoritative schemas."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Type System Discipline
|
|
7
|
+
|
|
8
|
+
Make the compiler reject impossible states, mismatched primitives, and unhandled variants. Prefer defining errors and special cases out of existence over proliferating handlers. For TypeScript syntax, see the `typescript-best-practices` skill.
|
|
9
|
+
|
|
10
|
+
- **Make illegal states unrepresentable.** Model variants as sum types (discriminated unions, enums with payloads, sealed classes), not as a bag of optional fields where contradictory combinations compile. `{ completed: boolean; completedAt?: Date }` admits `completed: true` with no date. Derive the boolean from `completedAt`, or model `{ kind: 'open' } | { kind: 'done'; at: Date }`. If you can write a comment explaining when a combination of fields is valid, split it into a sum type.
|
|
11
|
+
- **Types are constructions, not restrictions.** Build the type up from the values you want instead of carving them out of a looser type with checks. A non-empty list is a head plus a rest. A valid time range is a start plus a duration. Choose the shape that cannot build the illegal value and expose the interface callers need on top.
|
|
12
|
+
- **Brand semantic primitives.** `UserId` and `OrderId` are strings underneath but should not be interchangeable. Give each its own type, such as a branded intersection in TypeScript or a newtype elsewhere. Validate once at creation, trust the type downstream. If two arguments share a primitive type but mean different things, brand them.
|
|
13
|
+
- **External data is untyped until parsed.** RPC payloads, JSON, IPC messages, CLI args, config files, environment variables, database rows. Have a parse function at every boundary that turns unstructured input into the typed model. The **boundary-discipline** principle skill says where to put validation.
|
|
14
|
+
- **Don't lie to the type system.** Casts, unsafe coercions, and assertion functions that bypass the compiler are latent runtime crashes. If the compiler can't prove a fact, prove it (validate, narrow, refine the model) or accept that the cast is a hazard. Trace each `any`, `as`, or `assertNotNull` to the boundary and validate there.
|
|
15
|
+
- **Exhaustive matching is the compiler's job.** A match on a sum type must fail compilation when a new variant is added without handling, so the compiler tells the next agent where to add a case. Use your language's idiom: a `never`-typed binding in TypeScript, an unannotated `match` in Rust, `-Wincomplete-patterns` in Haskell, sealed-class match exhaustiveness in Kotlin.
|
|
16
|
+
- **Derive types from authoritative schemas.** When a protocol buffer, OpenAPI spec, GraphQL schema, database migration, design-token file, or another file owns a shape, derive from it instead of hand-rolling a parallel type. See the **encode-lessons-in-structure** principle skill.
|
|
17
|
+
- **Strengthen a type only where partiality appears.** A runtime assertion, null check, or "this should never happen" throw marks the place a type is too weak. Push that check up into the type. Then stop. The type system's job is to track the cases each use site must handle, not to describe the data as precisely as possible. Prefer total functions. `sum` of an empty list is 0, so it takes the plain list. `head` of an empty list has no answer, so it demands the non-empty one. If nothing would otherwise panic, keep the plain type.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Bugbot triage
|
|
2
|
+
|
|
3
|
+
Use this reference when the Babysit playbook (`../playbooks/babysit.md`) handles Bugbot or review-automation comments. The goal is not to ignore Bugbot by default. The goal is to stop treating every comment as a required code change.
|
|
4
|
+
|
|
5
|
+
## Decision rubric
|
|
6
|
+
|
|
7
|
+
Classify each Bugbot thread before acting:
|
|
8
|
+
|
|
9
|
+
- `fix`: The comment identifies a plausible correctness, security, privacy, data loss, auth, billing, migration, idempotency, race, or shipped-behavior issue. Fix it in the lowest owning PR, then reply with the commit SHA and resolve the thread.
|
|
10
|
+
- `dismiss`: The comment matches a documented low-risk noisy pattern, and the current code/context proves the concern does not need a code change. Reply with a short reason and resolve the thread.
|
|
11
|
+
- `ask`: The comment is novel, high-severity, security/privacy/data-related, or ambiguous. Ask the user instead of guessing.
|
|
12
|
+
|
|
13
|
+
When in doubt, ask. Skipping a noisy code-quality comment is cheap; skipping a real data or security bug is not.
|
|
14
|
+
|
|
15
|
+
## Learned pattern format
|
|
16
|
+
|
|
17
|
+
Add future patterns in this shape:
|
|
18
|
+
|
|
19
|
+
```markdown
|
|
20
|
+
### <short pattern name>
|
|
21
|
+
|
|
22
|
+
- Confidence: candidate | recurring | strong
|
|
23
|
+
- Skip when: <conditions that must be true>
|
|
24
|
+
- Do not skip when: <risk boundaries>
|
|
25
|
+
- Example signal: <phrases or code context that identify the pattern>
|
|
26
|
+
- Source: <PR/comment URL or short historical note>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use `candidate` for one or two examples. Use `recurring` after multiple real dismissals. Use `strong` only when the pattern is narrow, repeatedly verified, and low-risk.
|
|
30
|
+
|
|
31
|
+
## Recurring skip candidates
|
|
32
|
+
|
|
33
|
+
### Intentional UI or design-system visual changes
|
|
34
|
+
|
|
35
|
+
- Confidence: candidate
|
|
36
|
+
- Skip when: The PR description, screenshots, design review, or nearby code makes the visual change explicit, and the Bugbot comment is only restating that a shared visual default changed.
|
|
37
|
+
- Do not skip when: The comment points to accessibility, focus visibility, keyboard navigation, color contrast, or a component API contract that the PR did not intentionally change.
|
|
38
|
+
- Example signal: Comments about focus outlines, button sizes, spacing, or shared component visual defaults where the owner replies "intentional" or "intended".
|
|
39
|
+
|
|
40
|
+
### Upstack or stack-local usage Bugbot cannot see
|
|
41
|
+
|
|
42
|
+
- Confidence: candidate
|
|
43
|
+
- Skip when: Bugbot flags an export, component, helper, or file as unused, and the active forge's PR list and diffs, upper-stack diffs, or PR context show it is used by a later PR in the stack.
|
|
44
|
+
- Do not skip when: The current PR is not part of a stack, the symbol is public API, or the supposed upstack use cannot be verified.
|
|
45
|
+
- Example signal: "Exported component is never used" with a human reply like "used upstack".
|
|
46
|
+
|
|
47
|
+
### Temporary duplication during parallel implementation
|
|
48
|
+
|
|
49
|
+
- Confidence: candidate
|
|
50
|
+
- Skip when: The PR intentionally duplicates a small amount of code to keep a new path parallel to an old path that is being deleted, replaced, or proven out.
|
|
51
|
+
- Do not skip when: The duplicated code changes security, billing, data access, API behavior, or a long-lived shared abstraction would clearly reduce risk.
|
|
52
|
+
- Example signal: "Significant duplication" or "duplicated validation logic" where the owner explains the old path will be deleted or the duplicate logic is intentionally local.
|
|
53
|
+
|
|
54
|
+
### Existing framework or component invariant covers the warning
|
|
55
|
+
|
|
56
|
+
- Confidence: candidate
|
|
57
|
+
- Skip when: The concern is already guaranteed by a shared component, framework contract, type invariant, or single source of truth visible in the current diff or nearby code.
|
|
58
|
+
- Do not skip when: The invariant is assumed but not enforced, depends on timing, or crosses async/state boundaries where values can diverge.
|
|
59
|
+
- Example signal: Comments about missing max-height on an inner popover when the shared popover enforces viewport bounds, or nullable values where the local checked value and passed value share the same source.
|
|
60
|
+
|
|
61
|
+
### Owner-declared follow-up or deferred cleanup
|
|
62
|
+
|
|
63
|
+
- Confidence: candidate
|
|
64
|
+
- Skip when: The PR owner explicitly says the issue is a known follow-up, the behavior is not made worse by the current PR, and the comment is not about a high-risk area.
|
|
65
|
+
- Do not skip when: The agent is acting without owner input, the issue is medium/high severity product behavior, or deferring would merge a new regression.
|
|
66
|
+
- Example signal: "I'll worry about that later" or "we'll delete this eventually".
|
|
67
|
+
|
|
68
|
+
### Self-withdrawn or explicit false-positive rule comments
|
|
69
|
+
|
|
70
|
+
- Confidence: recurring
|
|
71
|
+
- Skip when: The comment body or a later Bugbot reply explicitly says the finding is withdrawn, compliant, or a false positive, and the agent can verify the relevant rule locally.
|
|
72
|
+
- Do not skip when: The only evidence is a human saying "false positive" on a high-risk issue without explanation.
|
|
73
|
+
- Example signal: A file-naming rule comment whose body says the file is already compliant.
|
|
74
|
+
|
|
75
|
+
## Ask by default
|
|
76
|
+
|
|
77
|
+
Do not auto-skip these categories, even if a previous PR dismissed something similar:
|
|
78
|
+
|
|
79
|
+
- Security, privacy, auth, billing, data retention, training-data, and permission-boundary findings.
|
|
80
|
+
- High-severity findings.
|
|
81
|
+
- Migration, schema, idempotency, concurrency, and cross-system behavior findings.
|
|
82
|
+
- Comments where the suggested fix is small and clearly reduces risk without changing product intent.
|
|
83
|
+
|
|
84
|
+
Historical data showed humans sometimes dismiss security/data-flow comments. Treat those as owner judgment calls, not team-wide skip rules.
|
|
85
|
+
|
|
86
|
+
## Candidate learnings from recent babysits
|
|
87
|
+
|
|
88
|
+
Append new candidate learnings here during or after babysitting when they look team-useful but not yet mature. Prefer promoting recurring candidates into the section above once several PRs confirm the pattern.
|
|
89
|
+
|
|
90
|
+
### Manual reimplementations of native browser behavior
|
|
91
|
+
|
|
92
|
+
- Confidence: candidate
|
|
93
|
+
- Skip when: Practically never. When a diff replaces native browser behavior with a manual equivalent (native sticky → JS-positioned clones, native scroll targeting → forwarded wheel/touch events, paint-order occlusion → masks/clip-path), Bugbot's logic-bug findings against that code have been consistently legitimate.
|
|
94
|
+
- Do not skip when: The finding concerns event-forwarding gaps (wheel deltaMode, touch pans, scroll-chaining at edges, tap slop), mask/clip hit-testing divergence, or observer-vs-React state timing races in such code. Default to fix.
|
|
95
|
+
- Example signal: "masks do not affect hit-testing", "overlay blocks wheel scroll", "ignores deltaMode", "runs in the IntersectionObserver callback before React applies state".
|
|
96
|
+
- Source: one sticky-occlusion PR: six Bugbot passes, roughly eighteen findings, every one fixed rather than dismissed.
|
|
97
|
+
|
|
98
|
+
### Contract-test drift claims are cheaply verifiable — run the test first
|
|
99
|
+
|
|
100
|
+
- Confidence: candidate
|
|
101
|
+
- Skip when: Never skip the verification itself; it costs one command. When a PR
|
|
102
|
+
ships a contract test that pins protocol or documentation prose (regexes over
|
|
103
|
+
a SKILL.md, snapshot of doc wording), and Bugbot claims "the test no longer
|
|
104
|
+
matches the doc" (or vice versa), run that test on the PR tip before
|
|
105
|
+
classifying. A red run confirms the claim empirically; a green run is a
|
|
106
|
+
concrete disproof for the dismissal reply.
|
|
107
|
+
- Do not skip when: n/a — this is a verification shortcut, not a dismissal
|
|
108
|
+
pattern. Note that repeat-pass lean-dismiss heuristics would misfire here:
|
|
109
|
+
prose-pinning tests drift precisely BECAUSE earlier fix rounds edit the prose.
|
|
110
|
+
- Example signal: "Contract test omits the pre-fix wait" on a PR whose earlier
|
|
111
|
+
fix commits reworded the pinned passage; the test run on the tip failed on
|
|
112
|
+
exactly the cited assertion.
|
|
113
|
+
- Source: one prose-pinning PR with eight Bugbot passes; the claim was real on
|
|
114
|
+
pass 7 despite every earlier pass being fixed-and-resolved.
|
|
115
|
+
|
|
116
|
+
### Stale security-review finding already fixed later in the same PR
|
|
117
|
+
|
|
118
|
+
- Confidence: candidate
|
|
119
|
+
- Skip when: An agentic security review (or similar) claims a missing authz/validation call, and the current PR tip clearly includes that exact gate (with tests), typically added in a later hardening commit after the review ran.
|
|
120
|
+
- Do not skip when: The cited helper is a no-op for the principal under discussion, the check runs after the side effect it guards, or coverage for the claimed principal is missing.
|
|
121
|
+
- Example signal: A HIGH "missing authorization check" finding while the exact guard is already called before the side effect on the tip.
|
|
122
|
+
- Source: one webhook-endpoint PR whose hardening commit postdated the review run.
|
|
123
|
+
|
|
124
|
+
### Widening a deliberately narrow error condition would mask the real error
|
|
125
|
+
|
|
126
|
+
- Confidence: candidate
|
|
127
|
+
- Skip when: The finding asks to broaden a narrow error condition (a specific
|
|
128
|
+
`errno`, error code, or status class) into a catch-all, and that narrowness
|
|
129
|
+
encodes a real distinction. The canonical shape is a dependency fallback
|
|
130
|
+
gated on `ENOENT`: "binary is not installed" is a different situation from
|
|
131
|
+
"the command ran and failed". Retrying on any non-zero exit would re-run a
|
|
132
|
+
legitimate failure (not found, expired auth, network) against the fallback
|
|
133
|
+
and then report the fallback's error, hiding the true one.
|
|
134
|
+
- Do not skip when: The narrow condition misses a case in the SAME category
|
|
135
|
+
(another "binary unusable" errno such as `EACCES`, another transport-level
|
|
136
|
+
failure), the unhandled path loses data or leaves partial state, or the retry
|
|
137
|
+
is idempotent AND the original error is still surfaced.
|
|
138
|
+
- Example signal: "only retries when X fails with ENOENT … never tries the
|
|
139
|
+
fallback even when a working Y exists", pointing at code whose fallback
|
|
140
|
+
exists for a missing dependency rather than a failed operation.
|
|
141
|
+
- Source: one CLI-rename PR whose fallback existed for a missing binary rather
|
|
142
|
+
than a failed command.
|
|
@@ -1,43 +1,61 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pstack
|
|
3
3
|
description: >
|
|
4
|
-
Rigor mode: apply the named principle at the moment it fits,
|
|
5
|
-
|
|
6
|
-
"poteto mode". Stays on until "
|
|
4
|
+
Rigor mode: apply the named principle at the moment it fits, verify against the
|
|
5
|
+
real artifact, and read the playbook for the task. Use for /pstack, "pstack",
|
|
6
|
+
"poteto mode". Stays on until "pstack off" or "normal mode".
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# pstack
|
|
10
10
|
|
|
11
|
-
Stay in this mode for every response of the session, until the user says
|
|
11
|
+
Stay in this mode for every response of the session, until the user says `pstack off` or `normal mode`.
|
|
12
12
|
|
|
13
13
|
This mode owns the work, not the voice: where an active style mode disagrees with these rules about the shape of the reply, the style mode wins.
|
|
14
14
|
|
|
15
15
|
Where ponytail disagrees with these rules about how much to change, ponytail wins. The change is the size the task requires, and no larger. These rules own the approach, the verification, and the design.
|
|
16
16
|
|
|
17
|
+
Read the file for any entry you apply: `principles/<title>.md`, `playbooks/<title>.md`, `skills/<name>/SKILL.md`, `references/<title>.md` under this skill's own directory.
|
|
18
|
+
|
|
17
19
|
## Non-negotiables
|
|
18
20
|
|
|
19
|
-
- About to ask the user to pick an approach → classify the fork first. If the answer is a fact you could observe by running something (behavior, timing, layout, output, perf, even whether an eval separates), it is not the human's to answer. Sketch it and let the result decide. Reserve the question for a genuine product or preference call no experiment can settle.
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
21
|
+
- About to ask the user to pick an approach → classify the fork first. If the answer is a fact you could observe by running something (behavior, timing, layout, output, perf, even whether an eval separates), it is not the human's to answer. Sketch it and let the result decide. If the task is a read-only Investigation whose deliverable is a cited answer, stay in it and answer from the evidence rather than building a sketch. Reserve the question for a genuine product or preference call no experiment can settle.
|
|
22
|
+
- Any code → name the data shape first, and choose its organizing structure per **principle-model-the-domain**.
|
|
23
|
+
- Code crossing a function boundary → the **architect** skill, with parallel design exploration before implementing.
|
|
24
|
+
- Parallel fan-out → the **swarm** skill for coverage matrices, races, gauntlets, and exploration partitions. Use **arena** for design or code bakeoffs with base selection and grafting.
|
|
25
|
+
- Contested design → the **interrogate** skill (multi-model adversarial) before shipping.
|
|
26
|
+
- Nontrivial multi-step → write the throughput checkpoint (the Feature playbook, step 3).
|
|
27
|
+
- Any prose surface, your reply to the user included → the **unslop** skill, and the reply rules below.
|
|
28
|
+
- Docs, RFCs, readmes, PR descriptions, or commit messages → the **technical-writing** skill.
|
|
29
|
+
- Before review → the **no-comments** skill.
|
|
30
|
+
- Shipping UI, IDE, or CLI → the matching control skill. For bug fixes, reproduce first on the same surface yourself. Hand to the user only under the narrow Bug fix step 1 exception.
|
|
31
|
+
- Running a benchmark, measuring perf yourself, or reporting a speedup or regression you measured → the **benchmark-checklist** skill before you report or act on the number.
|
|
32
|
+
- Any PR-status request ("babysit this", "get it green", "address the review comments", "check on PR X") → the **Babysit** playbook, not the host's built-in equivalent, whose description matches the same words. Never triggered by merely opening a PR. Declare its mode before polling. Its step 1 owns the request-to-mode mapping.
|
|
33
|
+
- Asked to land or ship a green stack → the **Shipping** playbook. Green is not safe. Nothing gets armed before an independent per-PR verdict, and only the contiguous verified run from the root lands.
|
|
34
|
+
- Bugbot or the agentic security review commented → skeptical posture. They catch real bugs and also file non-issues and nitpicks. Assess each on its merits and dismiss noise with a concrete reason instead of churning code. Triage fix, dismiss, or ask per `references/bugbot-triage.md`.
|
|
35
|
+
- Broken skill mid-task → fix it in its own PR. Don't block. Don't silently work around it.
|
|
36
|
+
- Long, autonomous, or multi-phase work, or any task the user steps away from to review later → a decision trail via the **show-me-your-work** skill. Commit it when stakes need an auditable record. Keep it local otherwise.
|
|
24
37
|
|
|
25
38
|
## Principles
|
|
26
39
|
|
|
27
|
-
|
|
40
|
+
Read the leaf in full for any principle you apply. Each entry names when it applies. The leaf is `principles/<title-in-kebab-case>.md` under this skill's own directory.
|
|
28
41
|
|
|
29
42
|
**Core**
|
|
30
43
|
|
|
44
|
+
- **Laziness Protocol.** Refactoring, sizing a diff, or tempted to add abstractions, layers, or signal threading. Bias to deletion and the smallest change that solves the problem.
|
|
31
45
|
- **Foundational Thinking.** Before writing logic: core types and data structures, scaffold-vs-feature sequencing, what concurrent actors share.
|
|
46
|
+
- **Redesign from First Principles.** Integrating a new requirement into an existing design. Redesign as if it had been foundational from day one.
|
|
32
47
|
- **Attack the Premise.** Two or more fixes that share one premise have failed the same gate. Take a census of which actors hold the imbalance before the next fix, then question the premise instead of writing another fix that assumes it.
|
|
48
|
+
- **Subtract Before You Add.** Sequencing an addition, refactor, or rewrite. Remove dead weight first, then build on the simpler base.
|
|
33
49
|
- **Minimize Reader Load.** Reviewing or shaping code that's hard to trace. Count layers and hidden state, collapse one-caller wrappers, shrink mutable scope.
|
|
34
50
|
- **Outcome-Oriented Execution.** Planned rewrites and migrations with explicit phase boundaries. Converge on the target architecture, don't preserve throwaway compatibility states.
|
|
35
51
|
- **Experience First.** Product, UX, or feature-scope tradeoffs. Choose user delight over implementation convenience.
|
|
36
52
|
- **Exhaust the Design Space.** A novel interaction or architectural decision with no precedent. Build 2-3 competing prototypes and compare before committing.
|
|
53
|
+
- **Build the Lever.** Any non-trivial work. Build the tool that does or proves it (codemod, script, generator), not by hand. The tool is the artifact a reviewer reruns.
|
|
37
54
|
|
|
38
55
|
**Architecture**
|
|
39
56
|
|
|
40
57
|
- **Model the Domain.** Writing stateful logic, or code that branches a lot or repeats a shape assumption across files. Encode the domain in a structure (state machine, typed model, table or registry, reducer, boundary, the right collection) instead of scattered conditionals.
|
|
58
|
+
- **Boundary Discipline.** Wiring validation, error handling, or framework adapters. Guards at system boundaries, trust internal types, keep business logic pure.
|
|
41
59
|
- **Type System Discipline.** Designing types or a signature in any typed language. Make illegal states unrepresentable, brand primitives, parse external data at boundaries.
|
|
42
60
|
- **Make Operations Idempotent.** Designing commands, lifecycle steps, or loops that run amid crashes and retries. Converge to the same end state.
|
|
43
61
|
- **Migrate Callers Then Delete Legacy APIs.** Introducing a new internal API while old callers exist. Migrate and delete in one wave.
|
|
@@ -45,7 +63,9 @@ Apply the entry whose trigger matches the moment.
|
|
|
45
63
|
|
|
46
64
|
**Verification**
|
|
47
65
|
|
|
48
|
-
- **
|
|
66
|
+
- **Prove It Works.** After a task, before declaring done. Verify against the real artifact, not a proxy or "it compiles".
|
|
67
|
+
- **Fix Root Causes.** Debugging. Trace each symptom to its root cause, reproduce first, ask why until you reach it.
|
|
68
|
+
- **Sequence Work into Verifiable Units.** Multi-step work (sweeps, migrations, runs of similar edits), and how you stack commits and PRs. Break work into small units that each end in a check, verify each before the next, and order delivery so the sequence proves itself.
|
|
49
69
|
- **Test Behavior, Not Implementation.** Writing, changing, or keeping a test. Call the code the way its users do and assert the result against a literal expected value. If the test would still pass when every imported function returns `undefined`, rewrite the assertion or delete the test.
|
|
50
70
|
- **Explain the Number.** Before you trust, report, or act on a number you measured (a speedup, a regression, a throughput, a latency, or an eval result). Find what limits it, and rule out that it measured something other than the work you think.
|
|
51
71
|
|
|
@@ -60,6 +80,62 @@ Apply the entry whose trigger matches the moment.
|
|
|
60
80
|
|
|
61
81
|
## Autonomy
|
|
62
82
|
|
|
83
|
+
**Just do it.** Reversible work and external actions proceed without asking.
|
|
84
|
+
|
|
85
|
+
**Always pause** for irreversible writes: force-push to shared branches, deploys, data deletion, customer messages.
|
|
86
|
+
|
|
87
|
+
**Session overrides:** "Don't stop" / "going to bed" / "run until done" / "be fully autonomous" → keep going.
|
|
88
|
+
|
|
63
89
|
**No is an acceptable answer.** Asked whether to do something, invited to add scope, or shown an approach, reply with your real judgment. Decline, push back, or say "this doesn't earn its place" when true. A recommendation is a judgment, not a validation. Agreement is not the default, candor over sycophancy.
|
|
64
90
|
|
|
65
|
-
|
|
91
|
+
## Subagents
|
|
92
|
+
|
|
93
|
+
**You own every subagent's work.** Review the diff and write your own summary, don't pass through what it said. A second opinion is the same prompt against a different model. Agreement is high-signal.
|
|
94
|
+
|
|
95
|
+
**Fresh subagents by default.** Give new work to a fresh subagent with consolidated scope: the original brief, every later directive, and the prior agent's report and branch. This holds for a fix round, a follow-up, a retry, and the next queue item. Resume or message an existing subagent only when the new work strictly needs state that lives in that agent and is costly to move: its local checkout, its uncommitted changes, or a process it still runs. A stop or hold order to a running agent is not reuse. A role such as a PR owner outlives its agent. Interrupt-chained resumes silently drop directives, so fire a fresh subagent with consolidated scope rather than trusting a "done" summary.
|
|
96
|
+
|
|
97
|
+
## Writing the reply
|
|
98
|
+
|
|
99
|
+
Write the reply clean as you draft it. A cleanup pass after drafting does not remove these patterns.
|
|
100
|
+
|
|
101
|
+
- **Short declarative sentences.** One thought per sentence, ended with a period.
|
|
102
|
+
- **No long-dash character anywhere.** Write a file-list bullet as a sentence ("`main.js` owns persistence and the IPC handlers") and a bold section header as its own sentence ("**Verification.** End to end via CDP").
|
|
103
|
+
- **A colon as a mid-sentence connector is also out.** A colon before a list is fine.
|
|
104
|
+
- **Terse is not an excuse to drop content.** Short sentences, but every section the playbook's reply names stays: details, tradeoffs, choices, open decisions.
|
|
105
|
+
- **Frame impact for the consumer and the maintainer.** Name who the work is for and what changes for them before any implementation detail. Then what the next engineer who owns this code inherits. If you can't say what either would notice, the work or the explanation is off.
|
|
106
|
+
- **Never fabricate a link, citation, or transcript reference.** Link only artifacts you produced or read this session.
|
|
107
|
+
- **Every claim carries its evidence or its label in the same sentence.** Measured, inferred, or guess. A prediction or an unseen cause is a guess. Never hand the human a check you could run.
|
|
108
|
+
|
|
109
|
+
## Comments
|
|
110
|
+
|
|
111
|
+
Comments follow the same rule as the reply. Write them clean as you go. Keep a comment only for a non-obvious *why* the code can't show. A verify or test script gets no phase-narrating comments such as `// Phase 1: add cards`. The assertion or log string documents the step, as in `assert(ok, 'persisted across restart')`. This applies to every file you produce, including a subagent's diff.
|
|
112
|
+
|
|
113
|
+
## Playbooks
|
|
114
|
+
|
|
115
|
+
Open a todolist whose first items are the matched playbook's steps, copied in verbatim, before any task-specific todos. A step you choose not to do stays in the list with a one-line `skip: <reason>`. Open `playbooks/<title>.md` for the full steps. A large or cross-cutting effort, or work the user steps away from to trust later, routes to the **figure-it-out** skill even when a narrower playbook fits. A standing project-scale program routes to **Orchestrate** instead.
|
|
116
|
+
|
|
117
|
+
- **Investigation.** Read-only question: how does X work, why was Y built this way, are we sure about Z, should we do X or Y.
|
|
118
|
+
- **Bug fix.** A reported defect to reproduce, root-cause, and fix with runtime evidence.
|
|
119
|
+
- **Perf issue.** A measured slowness to trace and improve against a baseline.
|
|
120
|
+
- **Hillclimb.** Sustained, scientific improvement of one metric against a target. Distinct from Perf issue, a one-off fix.
|
|
121
|
+
- **Runtime forensics.** Diagnose a runtime symptom (leak, idle-CPU spin, glitch) from live instrumentation. The deliverable is a diagnosis, not a fix.
|
|
122
|
+
- **Trace forensics.** Diagnose a captured profiling artifact handed to you after the fact. The deliverable is a diagnosis, not a fix.
|
|
123
|
+
- **Feature.** New or changed behavior, built from a named data shape.
|
|
124
|
+
- **Refactoring.** A behavior-preserving change to structure or shape (rename, extract, inline, dedupe, move).
|
|
125
|
+
- **Prototype.** A throwaway sketch to make a design or behavioral decision cheaply, or to settle an empirical fork by observing it.
|
|
126
|
+
- **Visual parity.** Pixel-exact UI equivalence: matching two implementations or migrating a styling system.
|
|
127
|
+
- **Authoring or modifying a skill.** Writing or editing a SKILL.md.
|
|
128
|
+
- **Eval.** Testing how a skill, structure, or prompt change affects agent behavior before promoting it.
|
|
129
|
+
- **Babysit.** Driving a PR or a stack to merge-ready: conflicts, review threads, CI.
|
|
130
|
+
- **Shipping.** The half after Babysit. Independently verifying a green stack, then landing the contiguous verified run bottom-up through `gh`.
|
|
131
|
+
- **Autonomous run.** A long task to drive to completion without stopping ("run until done").
|
|
132
|
+
- **Orchestrate.** A standing project handed to one coordinator chat. Distinct from Autonomous run, which drives one task to a predicate.
|
|
133
|
+
- **Autopilot-full.** A queue of independent PRs run to merged with full autonomy. One owner per PR carries build through merge, and the root swarm-verifies each PR before its owner merges.
|
|
134
|
+
- **Autopilot-stack.** A queue of changes built and verified with full autonomy, delivered as one linear reviewed base-branch stack the operator lands.
|
|
135
|
+
- **Session pickup.** Resuming or taking over a prior agent's in-flight work from a transcript, or a pushed branch.
|
|
136
|
+
- **Pause safely.** Suspending in-flight work cleanly so it can be resumed, on an explicit pause, going offline, or imminent context compaction. The complement to Session pickup.
|
|
137
|
+
- **Multi-phase or multi-PR plan.** Work that spans phases or stacked PRs.
|
|
138
|
+
- **Worktree and simulator cleanup.** Reclaiming local disk by pruning merged or abandoned git worktrees and stale simulators.
|
|
139
|
+
- **Opening a PR.** Invoked at the end of every other playbook.
|
|
140
|
+
|
|
141
|
+
Forked from pstack's poteto-mode skill by Lauren Tan, MIT Licence. Source: cursor/plugins at commit dbf4981, path pstack/skills/poteto-mode/SKILL.md. Every rule and entry above is that skill's own text, with its Cursor surface removed: no subagent_type, no MCP, no per-role model names, and no slash commands. The leaf skills, playbooks, and references under this directory are its files, carried over with the same removal. The precedence lines above are Tersio's own, and they resolve the one real conflict: a style mode still owns the shape of the reply, and ponytail still owns how large a change is.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architect
|
|
3
|
+
description: "Sketch types, signatures, and module structure before code, then stay in the loop while implementation fills in. Use for the architect skill, 'architect this', 'design this', or non-trivial work where jumping to code would lock in the wrong shape."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Architect
|
|
7
|
+
|
|
8
|
+
Sketch types, function signatures, class shapes, and module boundaries with `not implemented` bodies and pseudocode. Synthesize across multiple model perspectives, then fill in code against the chosen sketch.
|
|
9
|
+
|
|
10
|
+
## Start
|
|
11
|
+
|
|
12
|
+
Open a todolist with one entry per phase before starting.
|
|
13
|
+
|
|
14
|
+
1. Ground
|
|
15
|
+
2. Sketch
|
|
16
|
+
3. Agree
|
|
17
|
+
4. Implement
|
|
18
|
+
5. Scrap
|
|
19
|
+
|
|
20
|
+
## Phase A: Ground the problem
|
|
21
|
+
|
|
22
|
+
Build a real mental model of every system the new code touches. Run the **how** skill over the relevant subsystems. Naming a file isn't grounding. Produce the architectural explanation `how` prescribes. If the design redefines ownership or layering, also run the **why** skill on the existing shape so the rationale becomes a constraint, not a guess.
|
|
23
|
+
|
|
24
|
+
Skip Phase A only when the work is genuinely greenfield with no surrounding system to integrate.
|
|
25
|
+
|
|
26
|
+
## Phase B: Sketch
|
|
27
|
+
|
|
28
|
+
Run the **arena** skill with the design-sketch task and the Phase A grounding artifacts. Pass `references/runner-prompt.md` as each runner's prompt.
|
|
29
|
+
|
|
30
|
+
Take the runners from your configured `architect runners` line. If the line is missing, use the strongest model and a fast model. Alias and rejected entries follow the runner rules in the **arena** skill's Phase A.
|
|
31
|
+
|
|
32
|
+
Design it twice. Require at least two structurally distinct candidates before synthesis, even when the first looks sufficient. This is the **exhaust-the-design-space** principle skill made concrete. Whole-shape alternatives, not point fixes inside one shape.
|
|
33
|
+
|
|
34
|
+
Screen every candidate against [`references/design-red-flags.md`](references/design-red-flags.md) before synthesis. Assume the next contributor is an agent that sees only the files it opened, copies the nearest example, and takes the shortest path that compiles. Prefer the design where a change that looks right from one file is right for the whole repo.
|
|
35
|
+
|
|
36
|
+
Compare viable candidates on interface depth. Prefer the design that hides more complexity behind a smaller, simpler public surface. A rich interface can keep call chains short by concentrating capability instead of scattering it across layers.
|
|
37
|
+
|
|
38
|
+
Arena returns one synthesized design package. Its synthesis decision fills the rationale's "Synthesis decision" section.
|
|
39
|
+
|
|
40
|
+
## Phase C: Agree (opt-in)
|
|
41
|
+
|
|
42
|
+
Default: proceed directly to implementation with the synthesized design. No human checkpoint.
|
|
43
|
+
|
|
44
|
+
Opt in to a checkpoint when the invoker explicitly asks: "the architect skill with checkpoint," "stop and show me before implementing," or similar. Then surface the synthesized design and pause for sign-off.
|
|
45
|
+
|
|
46
|
+
The synthesis can ship as its own commit either way, as the "scaffold first" mode of the **foundational-thinking** principle skill. Planned and scoped breakage during fill-in is fine, per the **outcome-oriented-execution** principle skill. For adversarial pressure on the design before implementing, run the **interrogate** skill on the synthesized sketch.
|
|
47
|
+
|
|
48
|
+
If the human pushes back on the shape (in a checkpoint or after the fact), treat that as Phase A evidence. Re-ground and re-run Phase B before writing more code.
|
|
49
|
+
|
|
50
|
+
## Phase D: Implement against the sketch
|
|
51
|
+
|
|
52
|
+
Replace `not implemented` bodies with code, pseudocode with logic. The synthesized sketch is the contract. Deviations from it are signal to surface, not friction to absorb silently. If a function needs a parameter the sketch didn't anticipate, ask whether the sketch was wrong, the requirement was missed, or the implementation is overreaching.
|
|
53
|
+
|
|
54
|
+
## Phase E: Scrap when the architecture is wrong
|
|
55
|
+
|
|
56
|
+
If implementation keeps producing friction the sketch can't absorb, throw the sketch out. Don't bolt fixes onto a wrong design, per the **redesign-from-first-principles** and **fix-root-causes** principle skills.
|
|
57
|
+
|
|
58
|
+
The signal is a *pattern*, not single instances. Tells:
|
|
59
|
+
|
|
60
|
+
- The same shape of workaround appearing repeatedly across unrelated code.
|
|
61
|
+
- Multiple unrelated edge cases that all need special-case branches.
|
|
62
|
+
- Types that need escape hatches (`any`, casts, optional fields always set in practice) to compile.
|
|
63
|
+
- The "we need a lock" reflex when the sketch said the state wasn't shared.
|
|
64
|
+
- Callers having to know the abstraction's internal rules to use it.
|
|
65
|
+
- Two or more independent Phase D deviations of the same shape across the implementation.
|
|
66
|
+
|
|
67
|
+
Use judgment. A few edge cases don't condemn an architecture. Some problems are legitimately complex. Complexity in the data is not complexity in the design.
|
|
68
|
+
|
|
69
|
+
When you scrap:
|
|
70
|
+
|
|
71
|
+
1. Re-run the **how** skill over what's been built.
|
|
72
|
+
2. Redesign as if the new constraints had been day-one assumptions, per redesign-from-first-principles.
|
|
73
|
+
3. Subtract before adding, per the **subtract-before-you-add** principle skill. The new sketch should be smaller than the old one before it grows.
|
|
74
|
+
4. Return to Phase B and re-run arena.
|
|
75
|
+
|
|
76
|
+
## Outputs
|
|
77
|
+
|
|
78
|
+
The caller's usage is written first and the type sketch derived from it. One file with new types and signatures for small changes. Module map plus type definitions for larger work. The rationale ships alongside, shaped per `references/rationale-template.md`, including the usage sketch and the synthesis decision.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Design red flags
|
|
2
|
+
|
|
3
|
+
Screen every candidate before synthesis. A red flag is a reason to revise or reject the shape.
|
|
4
|
+
|
|
5
|
+
## Shallow module
|
|
6
|
+
|
|
7
|
+
A shallow module exposes a large interface while hiding little complexity. Judge depth by the capability and policy hidden behind the public surface relative to the size of that surface. Prefer a simple interface backed by substantial behavior.
|
|
8
|
+
|
|
9
|
+
Do not confuse a deep module with a deep call chain. A deep call chain scatters understanding across layers. A deep module concentrates capability behind one interface.
|
|
10
|
+
|
|
11
|
+
Look for these signs:
|
|
12
|
+
|
|
13
|
+
- Callers coordinate several methods to complete one operation.
|
|
14
|
+
- Public options expose internal stages or implementation choices.
|
|
15
|
+
- Learning the interface does not save the caller from learning the implementation.
|
|
16
|
+
|
|
17
|
+
## Information leakage
|
|
18
|
+
|
|
19
|
+
Information leakage makes multiple modules depend on the same internal decision. A representation, policy, or protocol detail appears in more than one place, so changing it requires coordinated edits.
|
|
20
|
+
|
|
21
|
+
Public re-exports of transport or wire types are leakage. Parse external data into domain types behind the interface. Keep storage schemas, framework objects, and protocol details private.
|
|
22
|
+
|
|
23
|
+
## Temporal decomposition
|
|
24
|
+
|
|
25
|
+
Temporal decomposition organizes modules by execution order instead of the knowledge they own. Separate load, validate, transform, and save stages often repeat one representation and its invariants across several boundaries.
|
|
26
|
+
|
|
27
|
+
Group code around domain knowledge and ownership. Methods that run at different times can still belong to one module when they protect the same decisions.
|
|
28
|
+
|
|
29
|
+
## Pass-through method
|
|
30
|
+
|
|
31
|
+
A pass-through method forwards the same arguments to another method with the same shape. It adds a layer without hiding complexity.
|
|
32
|
+
|
|
33
|
+
Remove it or move responsibility to the module that can complete the operation. Keep a forwarding boundary only when it adds policy, adaptation, or a distinct abstraction.
|
|
34
|
+
|
|
35
|
+
## Split ownership
|
|
36
|
+
|
|
37
|
+
More than one module writes the same state or keeps its own copy of it. An agent that edits one writer can't see the others, so their rules diverge.
|
|
38
|
+
|
|
39
|
+
Give each piece of state one owner. Other modules read it or ask the owner to change it.
|
|
40
|
+
|
|
41
|
+
## Two ways to do one task
|
|
42
|
+
|
|
43
|
+
The design supports more than one way to do the same task. An agent copies whichever way it finds first, so every way keeps gaining callers.
|
|
44
|
+
|
|
45
|
+
Keep one way. Move callers off the others and delete them in the same change.
|
|
46
|
+
|
|
47
|
+
## Importable internals
|
|
48
|
+
|
|
49
|
+
A caller can import a module's internals. An agent takes the shortest path that compiles, so it imports them directly and they become part of the interface.
|
|
50
|
+
|
|
51
|
+
Make internals unreachable from outside the module, so an import from outside fails the build.
|
|
52
|
+
|
|
53
|
+
## Hand-synced list
|
|
54
|
+
|
|
55
|
+
Two or more places list the same items, and adding an item means editing every list. An agent that sees one list updates only that one.
|
|
56
|
+
|
|
57
|
+
Keep one list and derive the others from it. If a list can't be derived, make the build fail when the lists disagree.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Rationale template
|
|
2
|
+
|
|
3
|
+
The prose that ships alongside the type sketch. One page. Sentence-case headings, no boilerplate. Replace the italic notes with actual content.
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
*One paragraph. What we're trying to do, and what about the existing system or constraints makes the shape non-obvious. If [Phase A](../SKILL.md#phase-a-ground-the-problem) surfaced constraints the design must honor (existing types to interop with, callers we can't break, invariants that crossed our boundary), name them here so the reader sees the same constraints you saw.*
|
|
8
|
+
|
|
9
|
+
## Usage (caller's view)
|
|
10
|
+
|
|
11
|
+
*Write this first, before the type sketch. Show the README or quickstart the consumer reads, plus two or three realistic call sites in their own code. What they import, what they call, what comes back. The type sketch in [Shape](#shape) is derived from this. The two must agree. When they diverge, reconcile the sketch to the usage, not the reverse. The caller's experience is the spec. The types serve it.*
|
|
12
|
+
|
|
13
|
+
## Shape
|
|
14
|
+
|
|
15
|
+
*The recommended architecture. Data structures first. Then how data flows through the signatures. Name the load-bearing decisions. State which invariants are encoded in types, where validation lives, and what the system deliberately does not do. Judge interface depth explicitly. State what complexity the public surface hides, what remains exposed to callers, and why the interface is no larger than needed. Cite the principle behind each decision (e.g., `per boundary-discipline`). Don't restate it.*
|
|
16
|
+
|
|
17
|
+
## Synthesis decision
|
|
18
|
+
|
|
19
|
+
*Filled in by [arena](../../arena/SKILL.md). Records which candidate became the base and why, what was adapted from each of the others, and what was rejected and why.*
|
|
20
|
+
|
|
21
|
+
## Tradeoffs accepted
|
|
22
|
+
|
|
23
|
+
*One bullet per tradeoff the chosen shape makes. Form: "we accept X in exchange for Y." Name anything a future reader might mistake for an oversight, including things that look like premature optimization or premature simplification.*
|
|
24
|
+
|
|
25
|
+
## Alternatives considered
|
|
26
|
+
|
|
27
|
+
*Required. Name at least one concrete alternative shape, with one line on why it lost. Judge each alternative on interface depth, not implementation simplicity alone. Name the complexity it exposes to callers and the complexity it hides. Two or three alternatives belong here when the design space had real contenders. One is fine when the constraints forced the answer, with the conclusion phrased as "this was the only viable shape because..." Avoid listing flavors of the same shape. This section covers design alternatives the chosen shape considered and rejected, not other runner candidates.*
|
|
28
|
+
|
|
29
|
+
## Open questions and risks
|
|
30
|
+
|
|
31
|
+
*Things you noticed during the sketch that the human needs to weigh in on, and risks worth flagging before implementation starts. Phrase as questions, not assertions, so the human's answer is the resolution rather than a comment.*
|
|
32
|
+
|
|
33
|
+
## Next implementation step
|
|
34
|
+
|
|
35
|
+
*The first thing to build against the sketch. One sentence. What you'd start writing immediately after synthesis (or after Phase D sign-off, if a checkpoint was opted into).*
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Architect runner prompt
|
|
2
|
+
|
|
3
|
+
The orchestrator passes this file through to every parallel candidate runner during Phase B and fills in the variable inputs around it: the task, the Phase A grounding artifacts, the isolated working directory, and the path to write outputs. The working directory is a git worktree when available, otherwise a per-runner subdirectory under the sketch dir. What matters is independence between candidates.
|
|
4
|
+
|
|
5
|
+
You are producing one candidate design in architect's parallel exploration. Read the **architect** skill in full first. That's the workflow you're inside. Output a candidate design package: type sketch, function signatures, module map, and prose rationale shaped per [`rationale-template.md`](rationale-template.md).
|
|
6
|
+
|
|
7
|
+
Apply the following discipline. The orchestrator compares candidates on these axes to pick a base.
|
|
8
|
+
|
|
9
|
+
- Caller's usage first. Write the README-style usage and two or three real call sites before the types, then derive the type sketch from them. The usage is the spec. The two must agree, so reconcile the sketch to the usage, not the reverse.
|
|
10
|
+
- Data structures first. Get the core types right and the code becomes obvious. Trace each dominant access pattern through the proposed structure. If the answer is "we'll add a map / index / cache later," the structure is wrong.
|
|
11
|
+
- Interface depth. Compare the capability hidden behind the public surface relative to the size of that surface. Prefer a simple interface that pulls complexity into the callee, even when the implementation becomes less simple. Do not put transport or wire types on the public API. Parse into domain types behind the interface.
|
|
12
|
+
- Shared state: if two actors might both write, ask "what happens?" If the answer isn't "nothing," default to per-actor state with a merge at the read boundary, per the **separate-before-serializing-shared-state** principle skill.
|
|
13
|
+
- Make boundaries visible. `not implemented` errors for bodies, `// TODO` pseudocode for tricky logic, doc comments stating intent and invariants. A reader should trace data from input to output by reading types and signatures alone.
|
|
14
|
+
- Encode invariants in types: hard-to-misuse types > runtime checks > prose comments, per the **encode-lessons-in-structure** principle skill.
|
|
15
|
+
- Validate at boundaries, trust types inside, per the **boundary-discipline** principle skill. Business logic as pure functions. The shell stays thin.
|
|
16
|
+
- Single source of truth per invariant. Derive instead of sync.
|
|
17
|
+
- Idempotent state transitions where applicable, per the **make-operations-idempotent** principle skill. Ask what happens if the operation runs twice or crashes halfway.
|
|
18
|
+
- Short call chains. If tracing the flow needs more than three files, flatten the hierarchy, per the **laziness-protocol** and **minimize-reader-load** principle skills.
|
|
19
|
+
|
|
20
|
+
You are one of the parallel runners, each on a different model. Produce the best design your model can make. Don't hedge against the others. Differences between candidates are the signal used to pick a base and graft. Converging on a safe-looking middle defeats the exploration.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arena
|
|
3
|
+
description: "Spawn N parallel candidates at the same task, pick a base, graft the strongest parts of the losers into it. Use for the arena skill, 'arena this', 'throw it in the arena', or when one attempt at a non-trivial artifact would lock in the wrong shape."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Arena
|
|
7
|
+
|
|
8
|
+
Open a todolist with one entry per phase (Frame, Fan out, Cross-judge, Pick, Graft, Verify) before launching anything.
|
|
9
|
+
|
|
10
|
+
## Phase A: Frame
|
|
11
|
+
|
|
12
|
+
Every candidate gets the same prompt, so the prompt is the contract.
|
|
13
|
+
|
|
14
|
+
1. State the artifact each candidate is producing.
|
|
15
|
+
2. Derive the rubric, 3-6 concrete gradeable criteria for what success looks like on *this* task. It is the picker's tool in Phase D. Candidates only see the task.
|
|
16
|
+
3. Pick the runners from your configured `arena runners` line. If the line is missing, default to one each on the strongest model and a fast model. An `auto` or `inherit-parent` entry in this line or the cross-judge line means the parent model, so omit `model` for it. If the Task tool rejects a configured entry, run that seat on its family's default and say so. Families go by prefix: `claude-*` and `grok-*`. With no family match, use the strongest model. If it rejects a default, use the closest valid slug of the same family from its error message. Spawn more runners when the arena covers multiple design directions. Use the same model N times when the work is generation-bound rather than judgment-sensitive.
|
|
17
|
+
4. Give each candidate its own output location (a git worktree where possible, otherwise `/tmp/arena-<slug>/candidate-<n>/`), per the **separate-before-serializing-shared-state** principle skill.
|
|
18
|
+
|
|
19
|
+
## Phase B: Fan out
|
|
20
|
+
|
|
21
|
+
Spawn all N subagents in one message with `run_in_background: true`, each with the task, the path to the shared grounding, its own output path, and instructions to produce the artifact and a short rationale naming the alternatives it considered and what it rejected.
|
|
22
|
+
|
|
23
|
+
If a candidate produces no output, proceed with N-1 and note the dropout.
|
|
24
|
+
|
|
25
|
+
## Phase C: Cross-judge
|
|
26
|
+
|
|
27
|
+
After all Phase B candidates complete, choose one model from your configured `arena cross-judge pool` line. If the line is missing, choose from the strongest model and a fast model. Prefer a different model family from the parent's. Spawn one readonly judge subagent on that model. It sees the rubric and the candidates by path label, scores each criterion, and recommends a base with rationale. It runs in parallel with your reading in Phase D. Don't spawn it while candidates are still writing.
|
|
28
|
+
|
|
29
|
+
## Phase D: Pick a base
|
|
30
|
+
|
|
31
|
+
Read every candidate end to end before picking. Score each against the rubric criterion by criterion, not on holistic feel, and compare with the cross-judge. Agreement on the base confirms the pick. Disagreement means one of you is biased or the rubric was ambiguous. Read both rationales before deciding.
|
|
32
|
+
|
|
33
|
+
Pick the base a future maintainer can extend most easily without breaking invariants. When two feel tied, prefer the cleaner boundary or smaller API, per the Laziness Protocol.
|
|
34
|
+
|
|
35
|
+
## Phase E: Graft
|
|
36
|
+
|
|
37
|
+
Walk each losing candidate once more for what is worth porting into the base, usually one or two things per candidate, not most of it. Fold each graft in by hand, per the **redesign-from-first-principles** principle skill, so the result stays coherent under one mental model. Don't paste mechanically.
|
|
38
|
+
|
|
39
|
+
If the candidates converge on one shape, that is strong agreement. Note it and ship the consensus shape. No graft is needed. If they wildly diverge, Phase A was under-specified. Reframe and re-run rather than averaging the divergence.
|
|
40
|
+
|
|
41
|
+
## Phase F: Verify
|
|
42
|
+
|
|
43
|
+
Verify the synthesized artifact like any other output, per the **prove-it-works** principle skill. If verification finds a problem the arena missed, either Phase A was wrong (re-frame and re-run) or a candidate caught it and you missed the graft (go back to Phase E). Don't paper over it.
|
|
44
|
+
|
|
45
|
+
## Outputs
|
|
46
|
+
|
|
47
|
+
One synthesized artifact, with a short synthesis note alongside naming the base and why, the cross-judge's verdict, each graft with its source candidate, what was rejected and why, any convergence or dropouts, and the verification result.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: benchmark-checklist
|
|
3
|
+
description: "Vet a perf measurement (limiter, tuning, limits, errors, repeatability, relevance, and whether the work happened) before you report or act on it. Use when you run a benchmark or report a speedup or regression you measured."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Benchmark checklist
|
|
7
|
+
|
|
8
|
+
Use this when you produce a performance number: a PR's before and after, a regression claim, a hillclimb harness, or a library or config choice. Answer each question with evidence from a run, not a guess about the code.
|
|
9
|
+
|
|
10
|
+
For a quick ballpark the user asked for, one run is enough. Still check questions 4 and 7, and say that it is one run. Skip the rest unless that run looks wrong. A choice between options is never a ballpark.
|
|
11
|
+
|
|
12
|
+
## Before you run anything
|
|
13
|
+
|
|
14
|
+
- Write down the claim you expect to make, in the words you would ship ("export is 30% faster at p50 on the 60k-row dataset"). The questions test that sentence.
|
|
15
|
+
- Read the measurement script. Note what it times, counts, and ignores.
|
|
16
|
+
- Check the load average with `uptime` and the core count with `nproc`. If the machine is busy, find out what is running. If you cannot stop it, interleave the sides so both see the same noise, and say so in the report.
|
|
17
|
+
|
|
18
|
+
## The questions
|
|
19
|
+
|
|
20
|
+
1. **Why not double?** Name the limiter. Profile in a run you do not report, because profilers and tracers slow the work down. Use CPU per process (`top`, `pidstat`), a runtime profiler (`node --cpu-prof`, `py-spy`, `perf`), I/O wait, and syscall counts (`strace -c` on Linux), then map the hot spot to source. Watch the load generator too: if it saturates first, you measured the load generator. If a change did not move the number, the limiter explains why, so find it before you call the change useless.
|
|
21
|
+
2. **Was it tuned?** Run every side the way production runs it: release builds, production flags and env, batching and transaction settings, connection pools, caches as warm or cold as production sees them, and the same versions and data. If one side runs on defaults, you compared configurations, not implementations. A limiter that is a setting (a commit per row, a debug build, a missing index) means that side is untuned. Tune it and measure again before you pick a winner. If you cannot tune it, do not pick a winner from that run. When the user is choosing what to adopt, narrowing the claim to the code as it ships today does not fix this, because they adopt the option, not today's settings.
|
|
22
|
+
3. **Did it break limits?** Do the arithmetic. Compare bytes per second with disk and network bandwidth, operations per second times cost per operation with your cores, and the time saved with the time the changed piece took. Removing a piece that takes 10% of the run can make the run at most about 11% faster. A result past a limit measured something other than the work, such as a cache, a no-op, or a bug.
|
|
23
|
+
4. **Did it error?** Count failures and non-success responses, and check that outputs are correct, not just present. Rejections are often fast, and timeouts and retries are slow. If the script does not count errors, add the count.
|
|
24
|
+
5. **Does it reproduce?** Run each side at least 5 times, alternating (A, B, A, B, and so on) so warmup, lazy initialization, caches, and drift favor neither. Report the median and range. A gap smaller than the run-to-run variation is no measurable difference. When the call is close, use a rank-sum test or the harness's own statistics.
|
|
25
|
+
6. **Does it matter?** Next to any micro result, measure the end-to-end path a user waits on, with realistic data sizes and concurrency, and report the micro result as a share of the whole. A helper that takes 1% of a request can make the request at most 1% faster, however fast the helper gets.
|
|
26
|
+
7. **Did it even happen?** Confirm the work ran inside the timed region: the request reached the server, the rows were written, the bytes were read, and the code used the result. Lazy code (generators nobody iterates, promises nobody awaits, results the JIT can discard) and timeouts produce numbers for work that never happened.
|
|
27
|
+
|
|
28
|
+
## Report
|
|
29
|
+
|
|
30
|
+
- Lead with the verdict: faster, slower, no measurable difference, or inconclusive.
|
|
31
|
+
- Give the number with its unit, the run count, the range, and the limiter. For example, "p50 41 ms → 33 ms, median of 7 runs per side, range 32 to 35 ms after, bound by JSON parsing on one core."
|
|
32
|
+
- Call the verdict inconclusive when you claim a difference but cannot name the limiter, when a side ran untuned, or when you could not check questions 4 and 7. Name the gap.
|
|
33
|
+
- Keep a PR body to one primary number, per the **Opening a PR** playbook. Put the runs, range, and limiter evidence in a linked artifact or notes file.
|
|
34
|
+
|
|
35
|
+
## Other perf material
|
|
36
|
+
|
|
37
|
+
- Vet the **Perf issue** playbook's baseline before the playbook plans from it, and every number after that.
|
|
38
|
+
- Vet the **Hillclimb** playbook's harness before it is frozen. The frozen harness then prints error and work counts, so each keep-or-revert checks questions 4 and 7 for free.
|