@mccune1224/pi-pstack 0.1.0 → 0.2.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/README.md +52 -100
- package/agents/comment-sicko.md +1 -1
- package/agents/poteto-agent.md +2 -2
- package/docs/compare.md +122 -0
- package/docs/guide/01-setup.md +37 -12
- package/docs/guide/02-poteto-mode.md +1 -1
- package/docs/guide/03-understand.md +0 -8
- package/docs/guide/05-build-and-clean.md +1 -1
- package/docs/guide/06-verify-and-ship.md +1 -1
- package/docs/guide/07-overnight.md +2 -2
- package/docs/guide/08-principles.md +4 -2
- package/docs/guide/10-recipes-and-pitfalls.md +2 -2
- package/docs/guide/README.md +2 -2
- package/extensions/compaction.test.ts +132 -0
- package/extensions/compaction.ts +183 -0
- package/extensions/context-guard.test.ts +53 -0
- package/extensions/context-guard.ts +65 -0
- package/extensions/doctor.test.ts +85 -0
- package/extensions/doctor.ts +100 -0
- package/extensions/index.ts +289 -26
- package/extensions/settings.test.ts +71 -16
- package/extensions/settings.ts +57 -9
- package/extensions/skill-budget.test.ts +110 -0
- package/extensions/skill-budget.ts +101 -0
- package/package.json +9 -4
- package/scripts/check-pi-isms.mjs +106 -0
- package/scripts/lib/pi-delta-rules.mjs +110 -0
- package/scripts/lib/pi-delta-rules.test.mjs +100 -0
- package/scripts/lib/upstream-vendor.mjs +32 -0
- package/scripts/pi-deltas.json +754 -0
- package/scripts/sync-upstream.mjs +117 -0
- package/scripts/verify-guards.mjs +132 -0
- package/scripts/verify-sync.mjs +206 -0
- package/skills/architect/SKILL.md +10 -10
- package/skills/architect/references/rationale-template.md +2 -2
- package/skills/architect/references/runner-prompt.md +7 -7
- package/skills/arena/SKILL.md +11 -11
- package/skills/automate-me/SKILL.md +21 -26
- package/skills/blast-radius/SKILL.md +5 -5
- package/skills/create-verification-skill/SKILL.md +5 -5
- package/skills/figure-it-out/SKILL.md +11 -13
- package/skills/how/SKILL.md +30 -104
- package/skills/how/references/explainer-prompt.md +6 -6
- package/skills/how/references/explorer-prompt.md +1 -1
- package/skills/interrogate/SKILL.md +13 -14
- package/skills/interrogate/references/code-quality-review.md +1 -1
- package/skills/interrogate/references/lead-judgment.md +1 -1
- package/skills/interrogate/references/rubric.md +2 -2
- package/skills/maintain-verification-skill/SKILL.md +5 -5
- package/skills/no-comments/SKILL.md +3 -3
- package/skills/poteto-mode/SKILL.md +9 -8
- package/skills/poteto-mode/playbooks/authoring-a-skill.md +4 -4
- package/skills/poteto-mode/playbooks/autonomous-run.md +4 -4
- package/skills/poteto-mode/playbooks/autopilot-full.md +9 -9
- package/skills/poteto-mode/playbooks/autopilot-stack.md +8 -8
- package/skills/poteto-mode/playbooks/babysit.md +17 -17
- package/skills/poteto-mode/playbooks/bug-fix.md +6 -6
- package/skills/poteto-mode/playbooks/eval.md +6 -8
- package/skills/poteto-mode/playbooks/feature.md +7 -7
- package/skills/poteto-mode/playbooks/hillclimb.md +10 -10
- package/skills/poteto-mode/playbooks/investigation.md +3 -3
- package/skills/poteto-mode/playbooks/multi-phase-plan.md +26 -25
- package/skills/poteto-mode/playbooks/opening-a-pr.md +17 -13
- package/skills/poteto-mode/playbooks/orchestrate.md +37 -39
- package/skills/poteto-mode/playbooks/pause-safely.md +4 -4
- package/skills/poteto-mode/playbooks/perf-issue.md +9 -9
- package/skills/poteto-mode/playbooks/prototype.md +5 -5
- package/skills/poteto-mode/playbooks/refactoring.md +9 -9
- package/skills/poteto-mode/playbooks/runtime-forensics.md +3 -3
- package/skills/poteto-mode/playbooks/session-pickup.md +4 -6
- package/skills/poteto-mode/playbooks/shipping.md +11 -14
- package/skills/poteto-mode/playbooks/trace-forensics.md +4 -4
- package/skills/poteto-mode/playbooks/visual-parity.md +3 -3
- package/skills/poteto-mode/playbooks/worktree-cleanup.md +4 -4
- package/skills/poteto-mode/references/bugbot-triage.md +3 -3
- package/skills/poteto-mode/scripts/worktree-audit.mjs +0 -7
- package/skills/principle-attack-the-premise/SKILL.md +23 -0
- package/skills/principle-boundary-discipline/SKILL.md +2 -2
- package/skills/principle-build-the-lever/SKILL.md +5 -5
- package/skills/principle-encode-lessons-in-structure/SKILL.md +3 -3
- package/skills/principle-experience-first/SKILL.md +5 -5
- package/skills/principle-fix-root-causes/SKILL.md +4 -4
- package/skills/principle-foundational-thinking/SKILL.md +3 -3
- package/skills/principle-guard-the-context-window/SKILL.md +2 -2
- package/skills/principle-laziness-protocol/SKILL.md +2 -2
- package/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +1 -1
- package/skills/principle-minimize-reader-load/SKILL.md +2 -2
- package/skills/principle-model-the-domain/SKILL.md +3 -3
- package/skills/principle-never-block-on-the-human/SKILL.md +4 -5
- package/skills/principle-prove-it-works/SKILL.md +3 -3
- package/skills/principle-redesign-from-first-principles/SKILL.md +3 -3
- package/skills/principle-separate-before-serializing-shared-state/SKILL.md +3 -3
- package/skills/principle-sequence-verifiable-units/SKILL.md +3 -3
- package/skills/principle-subtract-before-you-add/SKILL.md +3 -4
- package/skills/principle-test-behavior-not-implementation/SKILL.md +25 -0
- package/skills/principle-type-system-discipline/SKILL.md +5 -5
- package/skills/recall/SKILL.md +7 -7
- package/skills/reflect/SKILL.md +14 -20
- package/skills/reflect/references/divergent-reviewer.md +3 -3
- package/skills/reflect/references/judgment-reviewer.md +3 -3
- package/skills/reflect/references/synthesizer.md +2 -2
- package/skills/reflect/references/tooling-reviewer.md +4 -6
- package/skills/setup-pstack/SKILL.md +61 -49
- package/skills/show-me-your-work/SKILL.md +17 -17
- package/skills/show-me-your-work/scripts/log.mjs +2 -8
- package/skills/swarm/SKILL.md +6 -6
- package/skills/tdd/SKILL.md +2 -2
- package/skills/teach/SKILL.md +7 -7
- package/skills/technical-writing/SKILL.md +5 -8
- package/skills/typescript-best-practices/SKILL.md +6 -3
- package/skills/typescript-best-practices/references/patterns.md +35 -14
- package/skills/unslop/SKILL.md +8 -20
- package/skills/why/SKILL.md +27 -100
- package/skills/why/references/epistemics.md +6 -6
- package/skills/why/references/investigator-prompt.md +5 -5
- package/skills/why/references/source-playbook.md +1 -1
- package/skills/why/references/sources/databricks.md +7 -7
- package/skills/why/references/sources/datadog.md +5 -5
- package/skills/why/references/sources/incident-postmortem.md +2 -2
- package/skills/why/references/sources/linear.md +2 -2
- package/skills/why/references/sources/notion.md +3 -3
- package/skills/why/references/sources/sentry.md +4 -4
- package/skills/why/references/sources/slack.md +2 -2
- package/skills/why/references/synthesizer-prompt.md +3 -3
- package/skills/how/references/critic-prompt.md +0 -59
- package/skills/how/references/critique-rubric.md +0 -58
|
@@ -16,7 +16,7 @@ Three rules sit above the layers:
|
|
|
16
16
|
|
|
17
17
|
The codebase is the word list. Write the real symbol, file, flag, or command name, not a synonym or a description of it.
|
|
18
18
|
|
|
19
|
-
Don't invent jargon. Use the words a developer would say out loud: "move", "delete", "a budget that only decreases", not "evacuate", "ratchet", or "endgame". A named pattern is fine when the doc says what it means the first time.
|
|
19
|
+
Don't invent jargon. Use the words a developer would say out loud: "move", "delete", "a budget that only decreases", not "evacuate", "ratchet", or "endgame". A named pattern is fine when the doc says what it means the first time. Propose a new offender and its replacement as an addition to `unslop`'s abstract-metaphor rule in your reply, with the diff. Don't edit that skill.
|
|
20
20
|
|
|
21
21
|
## Vary the rhythm
|
|
22
22
|
|
|
@@ -36,13 +36,13 @@ One document, one mode. Two questions pick it: does the content inform action (d
|
|
|
36
36
|
- Understanding + work: **reference**.
|
|
37
37
|
- Understanding + learning: **explanation**.
|
|
38
38
|
|
|
39
|
-
Use the compass on a whole document or on one sentence.
|
|
39
|
+
Use the compass on a whole document or on one sentence.
|
|
40
40
|
|
|
41
41
|
**Tutorial: learning by doing.** You are the teacher. The learner's success is your job, not theirs. Open by saying what the learner will build, not what they will "learn". Every step produces a visible result, early and often. Tell them what they should see: the expected output, the prompt change, the log line. Cut explanation to one clause and a link. Teaching pauses break the lesson. Stay concrete. Write as "we", in commands: "First, do x. Now, do y."
|
|
42
42
|
|
|
43
43
|
**How-to: steps to a goal.** Solve a problem a person has, not an operation the machine can perform. Assume competence. Skip teaching. Action only: no digressions, no background, no completeness for its own sake. Link those instead. Allow forks and judgment: "If you want x, do y." Name the guide by the task: "How to calibrate the radar array", not "Radar array calibration".
|
|
44
44
|
|
|
45
|
-
**Reference: facts for lookup.** Describe. Only describe. No instruction, no persuasion, no opinion. Be dry, complete, and sure
|
|
45
|
+
**Reference: facts for lookup.** Describe. Only describe. No instruction, no persuasion, no opinion. Be dry, complete, and sure. State facts, options, limits, and errors with no hedging. Mirror the structure of the thing described, so code and docs can be navigated together. Put material where readers expect it. Generate from code where possible, so it stays true.
|
|
46
46
|
|
|
47
47
|
**Explanation: understanding and why.** One bounded topic, readable away from the product. Each title should tolerate an implicit "About..." in front. Anchor on a real why question. Give context: design decisions, history, constraints, alternatives. Opinion is allowed here and nowhere else.
|
|
48
48
|
|
|
@@ -59,7 +59,6 @@ Source: diataxis.fr, fetched 2026-07-18.
|
|
|
59
59
|
- Put the common case first. Exceptions after.
|
|
60
60
|
- Sound like a knowledgeable friend. No buzzwords, no figurative language, no "please" in instructions, and never "simply", "easy", or "quickly" in a procedure. If it were simple, the reader would not be here.
|
|
61
61
|
- Don't pre-announce ("we will soon support...") and don't start consecutive sentences with the same phrase.
|
|
62
|
-
- Read the awkward sentence aloud. If it stays awkward, rewrite it.
|
|
63
62
|
- Link with words that say where the link goes: the page title or a short description. Never "click here". Prefer a sentence of context on the page over a link off it.
|
|
64
63
|
- Headings carry the point, not just the topic ("Pick the mode first", not "Modes"). Sentence case. A task heading is a bare verb phrase ("Create an instance"). A concept heading is a noun phrase. One h1 per page, no skipped levels.
|
|
65
64
|
- Numbered lists for sequences, bullets for everything else. Introduce a list with a complete sentence. Keep items parallel.
|
|
@@ -92,7 +91,7 @@ Source: asd-ste100.org (Issue 9, 2025), fetched 2026-07-18. The numbered rules a
|
|
|
92
91
|
- Use periods, not semicolons. Replace an em dash with a new sentence.
|
|
93
92
|
- Make text in parentheses a full grammatical unit or its own sentence. Never form plurals with "(s)".
|
|
94
93
|
- No slashes: write "a, b, or both" instead of "a/b" or "and/or".
|
|
95
|
-
- Call each thing by one name, everywhere. A doc that says "the gate", "the ratchet", and "the budget check" for one thing teaches three things. Rewording an unchanged sentence between edits costs the same way
|
|
94
|
+
- Call each thing by one name, everywhere. A doc that says "the gate", "the ratchet", and "the budget check" for one thing teaches three things. Rewording an unchanged sentence between edits costs the same way. Don't churn what didn't change.
|
|
96
95
|
- Skip idioms, colloquialisms, Latin abbreviations, and metaphors. A non-native reader, a translator, and an agent all parse plain constructions best.
|
|
97
96
|
|
|
98
97
|
Source: Kohl, The Global English Style Guide (SAS Press). Guideline text fetched from the Internet Archive and the SAS sample chapter, 2026-07-18.
|
|
@@ -100,7 +99,7 @@ Source: Kohl, The Global English Style Guide (SAS Press). Guideline text fetched
|
|
|
100
99
|
## Voice and repo specifics
|
|
101
100
|
|
|
102
101
|
- Apply the **unslop** skill to every doc this skill touches. That skill owns the slop-pattern catalog: AI vocabulary, filler, hedging, formatting tells.
|
|
103
|
-
- PR descriptions and commit messages are writing too. Every layer except Diátaxis applies to them.
|
|
102
|
+
- PR descriptions and commit messages are writing too. Every layer except Diátaxis applies to them. A PR body is a briefing that a reviewer can read in under a minute. Do not paste swarm logs, SHA lists, or metric tables. Link them.
|
|
104
103
|
- Product UI strings are not documentation. Use your product's copy guidelines for those.
|
|
105
104
|
- Indent code snippets with tabs. Write real paths and real symbols. Make every count or tree claim true at the commit that lands it, and include the command that regenerates it.
|
|
106
105
|
|
|
@@ -114,8 +113,6 @@ After:
|
|
|
114
113
|
|
|
115
114
|
> `budget.mjs` reads the committed budget from `budget.json` and counts the files that import protos. If the count exceeds the budget, CI fails. Run `budget.mjs --write` only to lower the budget.
|
|
116
115
|
|
|
117
|
-
The fixes, by layer: "configuration is performed" becomes "`budget.mjs` reads", so someone does something (Google). "Ratchet" goes away. The script's real filename does the naming (jargon rule). The five-noun string breaks up into plain clauses (Global English). The hedge "note that it's important to remember" is deleted (cut every word that does no work). The failure condition moves ahead of the step it explains (STE). The buried "should only be done when lowering" becomes a command with "only" next to its verb (STE). "If exceeded" gets a subject: the count (Global English).
|
|
118
|
-
|
|
119
116
|
## Review checklist
|
|
120
117
|
|
|
121
118
|
Apply to any prose this skill covers. Item 1 applies only to document sets:
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: typescript-best-practices
|
|
3
3
|
description: TypeScript best practices. Use when reading or editing any .ts or .tsx file.
|
|
4
|
+
paths: ["**/*.ts", "**/*.tsx"]
|
|
5
|
+
disable-model-invocation: true
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# TypeScript best practices
|
|
7
9
|
|
|
8
|
-
Apply the **type-system-discipline** principle skill first
|
|
10
|
+
Apply the **type-system-discipline** principle skill first.
|
|
9
11
|
|
|
10
12
|
| Rule | Summary |
|
|
11
13
|
|------|---------|
|
|
12
14
|
| Discriminated unions | Model variants with a `kind` literal discriminant so impossible states can't be represented. No optional-field bags. |
|
|
13
|
-
| Branded types | Brand primitives with `& { readonly __brand: "X" }` so they can't be mixed up. Validate once at
|
|
15
|
+
| Branded types | Brand primitives with `& { readonly __brand: "X" }` so they can't be mixed up. Validate once at the boundary. |
|
|
14
16
|
| Constructive modeling | Build the shape so the illegal value can't be constructed. `[T, ...T[]]` for non-empty, `[T, T][]` for even length, `start` plus `duration` for a range. Not a runtime guard, not a wish for refinement types. |
|
|
15
17
|
| Simplest total type | Keep `T[]` while every operation on it stays total. Strengthen to `NonEmpty<T>` only where the loose type forces `!`, a cast, or a "should never happen" throw. |
|
|
16
|
-
| `unknown` over `any` | External data is `unknown`.
|
|
18
|
+
| `unknown` over `any` | External data is `unknown`. |
|
|
19
|
+
| Schemas before guards | Before hand-writing a property-by-property type guard, use the repository's runtime schema library and infer the type from the schema, such as `z.infer`. |
|
|
17
20
|
| No `as` casts | Every `as` is a runtime crash waiting. Cast only after validation. |
|
|
18
21
|
| Narrowing hierarchy | Discriminant switch > `in` operator > `typeof`/`instanceof` > user-defined type guard > `as`. |
|
|
19
22
|
| Type guards | Must verify the claim. A lying guard is worse than `as` because the bug hides behind a name that says it's safe. Name them `isX` or `hasX`. |
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# TypeScript patterns
|
|
2
2
|
|
|
3
|
-
Code examples for each rule in `SKILL.md`. The underlying principles are language-agnostic
|
|
3
|
+
Code examples for each rule in `SKILL.md`. The underlying principles are language-agnostic. See the **type-system-discipline** and **boundary-discipline** principle skills.
|
|
4
4
|
|
|
5
5
|
## Branded types
|
|
6
6
|
|
|
7
|
-
Brand primitives so they can't be mixed up. Validate once at
|
|
7
|
+
Brand primitives so they can't be mixed up. Validate once at the boundary. Downstream code trusts the type.
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
type AgentId = string & { readonly __brand: "AgentId" };
|
|
@@ -19,11 +19,11 @@ function focusAgent(id: AgentId): void {
|
|
|
19
19
|
}
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Match the `readonly __brand: 'X'` shape
|
|
22
|
+
Match the `readonly __brand: 'X'` shape. Don't invent a new convention.
|
|
23
23
|
|
|
24
24
|
## Discriminated unions
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
Model variants with a literal discriminant. Every variant shares the field name and each variant's value is unique, so impossible combos can't be represented.
|
|
27
27
|
|
|
28
28
|
```ts
|
|
29
29
|
// Don't. Boolean + optionals lets contradictory states exist.
|
|
@@ -40,7 +40,7 @@ Pick one discriminant name (`kind`, `type`, `tag`) and stick to it.
|
|
|
40
40
|
|
|
41
41
|
## Constructive modeling
|
|
42
42
|
|
|
43
|
-
Build the type from parts that are all legal instead of restricting a loose type with runtime checks.
|
|
43
|
+
Build the type from parts that are all legal instead of restricting a loose type with runtime checks.
|
|
44
44
|
|
|
45
45
|
Non-empty, via a variadic tuple:
|
|
46
46
|
|
|
@@ -65,7 +65,7 @@ Where a plain `T[]` arrives, narrow once with a guard. The fact then travels in
|
|
|
65
65
|
const isNonEmpty = <T>(arr: T[]): arr is NonEmpty<T> => arr.length > 0;
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
Even length, as pairs
|
|
68
|
+
Even length, as pairs:
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
71
|
type Pairs<T> = [T, T][];
|
|
@@ -81,7 +81,7 @@ type TimeRange = { start: Date; end: Date }; // start <= end
|
|
|
81
81
|
type TimeRange = { start: Date; durationMs: number };
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
Keep `durationMs` a plain number. Brand it (per Branded types) only if a raw number could be passed where a duration is expected, not by reflex.
|
|
84
|
+
Keep `durationMs` a plain number. Brand it (per Branded types) only if a raw number could be passed where a duration is expected, not by reflex. Pick the representation that makes the bad state unconstructable, then expose the reading you need on top (`pairs.flat()`, a `rangeEnd()` helper).
|
|
85
85
|
|
|
86
86
|
## Simplest total type
|
|
87
87
|
|
|
@@ -105,11 +105,11 @@ function newestSession(sessions: NonEmpty<Session>): Session {
|
|
|
105
105
|
}
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
Weakening the result to `Session | undefined` is the other total signature.
|
|
108
|
+
Weakening the result to `Session | undefined` is the other total signature.
|
|
109
109
|
|
|
110
110
|
## `unknown` over `any`
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
External data is always `unknown`. Narrow before use.
|
|
113
113
|
|
|
114
114
|
```ts
|
|
115
115
|
// Don't
|
|
@@ -127,6 +127,27 @@ function handle(input: unknown) {
|
|
|
127
127
|
|
|
128
128
|
External sources include RPC payloads, `JSON.parse`, `postMessage`, IPC, file contents, environment variables, database results.
|
|
129
129
|
|
|
130
|
+
## Schemas before hand-rolled guards
|
|
131
|
+
|
|
132
|
+
Before writing a property-by-property type guard for external data, look for the repository's runtime schema library and existing schemas. Let one schema own validation and derive the TypeScript type from it. Do not maintain a schema, a duplicate interface, and a guard that can drift apart.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { z } from "zod";
|
|
136
|
+
|
|
137
|
+
const UserSchema = z.object({
|
|
138
|
+
id: z.string().uuid(),
|
|
139
|
+
role: z.enum(["admin", "member"]),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
type User = z.infer<typeof UserSchema>;
|
|
143
|
+
|
|
144
|
+
function parseUser(input: unknown): User {
|
|
145
|
+
return UserSchema.parse(input);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Use `safeParse` when failure is an expected branch. Use the equivalent inference helper when the repository uses another schema library. Do not add a new schema dependency for one guard. This rule prefers the schema system the codebase already trusts.
|
|
150
|
+
|
|
130
151
|
## No `as` casts
|
|
131
152
|
|
|
132
153
|
Every `as` is a potential runtime crash. Cast only after the type system has verified the claim.
|
|
@@ -174,7 +195,7 @@ function area(s: Shape): number {
|
|
|
174
195
|
|
|
175
196
|
## Type guards
|
|
176
197
|
|
|
177
|
-
A guard must actually verify the claim. A lying guard is worse than `as
|
|
198
|
+
A guard must actually verify the claim. A lying guard is worse than `as`.
|
|
178
199
|
|
|
179
200
|
```ts
|
|
180
201
|
function isCircle(s: Shape): s is Shape & { kind: "circle" } {
|
|
@@ -182,11 +203,11 @@ function isCircle(s: Shape): s is Shape & { kind: "circle" } {
|
|
|
182
203
|
}
|
|
183
204
|
```
|
|
184
205
|
|
|
185
|
-
Prefer discriminant narrowing when possible.
|
|
206
|
+
Prefer discriminant narrowing when possible.
|
|
186
207
|
|
|
187
208
|
## Exhaustiveness
|
|
188
209
|
|
|
189
|
-
In default arms, assign the discriminant to a `never`-typed local.
|
|
210
|
+
In default arms, assign the discriminant to a `never`-typed local.
|
|
190
211
|
|
|
191
212
|
```ts
|
|
192
213
|
// Value-returning switch
|
|
@@ -220,7 +241,7 @@ function handle(s: Shape): void {
|
|
|
220
241
|
}
|
|
221
242
|
```
|
|
222
243
|
|
|
223
|
-
Return-style in value-returning switches
|
|
244
|
+
Return-style in value-returning switches, void-style in statement switches.
|
|
224
245
|
|
|
225
246
|
## `satisfies` over `as`
|
|
226
247
|
|
|
@@ -237,7 +258,7 @@ const config = { theme: "dark", cols: 3 } satisfies Config;
|
|
|
237
258
|
|
|
238
259
|
## Boundary validation
|
|
239
260
|
|
|
240
|
-
Validate once where data crosses in
|
|
261
|
+
Validate once where data crosses in. Trust types inside. See the **boundary-discipline** principle skill.
|
|
241
262
|
|
|
242
263
|
- **Wire formats** (proto, JSON-RPC): parse with `ignoreUnknownFields` so forward-compatible changes don't break old clients.
|
|
243
264
|
- **Persisted JSON:** versioned blob with a try/catch around the parse.
|
package/skills/unslop/SKILL.md
CHANGED
|
@@ -1,40 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: unslop
|
|
3
3
|
description: Cut AI tells from any writing. Must always apply.
|
|
4
|
+
disable-model-invocation: true
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Unslop
|
|
7
8
|
|
|
8
|
-
Edit text to remove AI patterns
|
|
9
|
+
Edit text to remove AI patterns.
|
|
9
10
|
|
|
10
11
|
## Process
|
|
11
12
|
|
|
12
13
|
1. Scan for the patterns below.
|
|
13
14
|
2. Rewrite. Preserve meaning, match intended tone.
|
|
14
|
-
3.
|
|
15
|
-
4. Self-audit: "What makes this obviously AI generated?" Fix remaining tells.
|
|
16
|
-
|
|
17
|
-
## Adding soul
|
|
18
|
-
|
|
19
|
-
Removing patterns is half the job. Sterile, voiceless writing is just as obvious.
|
|
20
|
-
|
|
21
|
-
- **Have opinions.** React to facts instead of neutrally listing pros and cons.
|
|
22
|
-
- **Vary rhythm.** Short sentences. Then longer ones that take their time. Mix it up.
|
|
23
|
-
- **Acknowledge complexity.** "Impressive but also kind of unsettling" beats "impressive."
|
|
24
|
-
- **Use "I" when it fits.** First person isn't unprofessional.
|
|
25
|
-
- **Let some mess in.** Perfect structure looks machine-made.
|
|
26
|
-
- **Be specific.** Not "this is concerning" but "there's something unsettling about agents churning away at 3am."
|
|
15
|
+
3. Self-audit: "What makes this obviously AI generated?" Fix remaining tells.
|
|
27
16
|
|
|
28
17
|
## Patterns to detect and fix
|
|
29
18
|
|
|
19
|
+
Rule numbers are stable ids that other skills cite. A removed rule leaves a gap.
|
|
20
|
+
|
|
30
21
|
### Content
|
|
31
22
|
|
|
32
|
-
1. **Puffery.** "pivotal moment", "testament to", "evolving landscape", "setting the stage for", "indelible mark", "deeply rooted". Cut puffery, state what happened.
|
|
33
|
-
2. **Name-dropping.** Listing media outlets without context. Pick one, say what was said.
|
|
34
23
|
3. **Superficial -ing phrases.** "highlighting...", "ensuring...", "reflecting...", "showcasing...", "fostering...". Delete or expand with real sources.
|
|
35
|
-
4. **Promotional language.** "nestled", "vibrant", "breathtaking", "groundbreaking", "renowned", "stunning", "must-visit". Use neutral descriptions.
|
|
36
24
|
5. **Vague attributions.** "Experts believe", "Industry reports suggest", "Some critics argue". Name the source or delete.
|
|
37
|
-
6. **Formulaic challenges.** "Despite challenges... continues to thrive." Replace with specific facts.
|
|
38
25
|
|
|
39
26
|
### Language
|
|
40
27
|
|
|
@@ -47,7 +34,7 @@ Removing patterns is half the job. Sterile, voiceless writing is just as obvious
|
|
|
47
34
|
|
|
48
35
|
### Style
|
|
49
36
|
|
|
50
|
-
13. **Em dash overuse.** Avoid em dashes entirely. Use periods or commas only (no parentheses, no en dashes, no hyphen-as-dash substitutes).
|
|
37
|
+
13. **Em dash overuse.** Avoid em dashes entirely. Use periods or commas only (no parentheses, no en dashes, no hyphen-as-dash substitutes). If a thought needs separation, end the sentence or use a comma.
|
|
51
38
|
14. **Colon overuse.** Colons are fine before a list or example. Not as mid-sentence connectors. "If you're coming from traditional automation: instead of registering event handlers, you describe conditions" adds nothing with the colon. Rewrite to let the point stand on its own without comparison framing. "Describing when the scheduler should fire works best as plain English." Same meaning, no crutch punctuation.
|
|
52
39
|
15. **Boldface overuse.** Don't bold every proper noun or acronym.
|
|
53
40
|
16. **Inline-header lists.** The tell is a bold label and colon that restates the line: "**Performance:** Performance improved...". Convert those to prose. A bold lead-in that ends in a period, names the item, and is followed by genuinely new detail ("**Schema in TypeScript.** Tables live in one file.") is fine, not a tell.
|
|
@@ -58,7 +45,6 @@ Removing patterns is half the job. Sterile, voiceless writing is just as obvious
|
|
|
58
45
|
### Communication artifacts
|
|
59
46
|
|
|
60
47
|
20. **Chatbot phrases.** "I hope this helps!", "Let me know if...", "Of course!", "Certainly!", "Found the smoking gun!" Remove.
|
|
61
|
-
21. **Cutoff disclaimers.** "While specific details are limited..." Find sources or remove.
|
|
62
48
|
22. **Sycophantic tone.** "Great question! You're absolutely right!" Respond directly.
|
|
63
49
|
|
|
64
50
|
### Filler
|
|
@@ -78,3 +64,5 @@ Removing patterns is half the job. Sterile, voiceless writing is just as obvious
|
|
|
78
64
|
29. **Active voice.** Prefer it. Catch "is/are/was/were + past participle" and name the actor: "queries are validated" becomes "the compiler validates queries", "the file is parsed by the loader" becomes "the loader parses the file". Passive is fine only when the actor is unknown or genuinely doesn't matter.
|
|
79
65
|
30. **Cut adverbs, or use a stronger verb.** "runs quickly" becomes "is fast" or the number. "significantly improves" becomes the measured delta. An adverb propping up a weak verb means the verb is wrong.
|
|
80
66
|
31. **Prefer the plain word.** "utilize" becomes "use", "leverage" becomes "use", "facilitate" becomes "help", "numerous" becomes "many", "in the event that" becomes "if". The fancier synonym is rarely clearer.
|
|
67
|
+
32. **Mannered prose.** Metaphor or flourish where a literal phrase exists: aphorisms ("wire it or delete it"), rhetorical fragments for effect, personified code ("the plan holds it"), figurative verbs ("rides along", "stands on"), stock framing phrases. "A dial worth turning" becomes "a parameter worth varying". Say what you mean. Rule 26 covers the metaphor nouns.
|
|
68
|
+
33. **Over-compression.** Dropped articles, verbless fragments, symbol-speak, and abbreviations that make the reader decode instead of read. "Parser rejects bad date → exit 2, no write" becomes "The parser rejects a bad date, exits with code 2, and writes nothing." Write whole sentences with their articles and verbs, and spell out arrows and abbreviations.
|
package/skills/why/SKILL.md
CHANGED
|
@@ -1,60 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: why
|
|
3
3
|
description: "Use for 'why does X work this way', 'why we picked Y', design rationale, regressions, postmortems, or data-backed thresholds. Discovers available MCPs and queries each evidence category (source control, issue tracker, long-form docs, real-time chat, infrastructure observability, error tracking, product analytics warehouse) in parallel, then returns a cited read on decisions and tradeoffs. Use how for runtime behavior."
|
|
4
|
+
disable-model-invocation: true
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Why
|
|
7
8
|
|
|
8
|
-
Investigate the motivation and intent behind code.
|
|
9
|
+
Investigate the motivation and intent behind code.
|
|
9
10
|
|
|
10
11
|
Companion to the `how` skill. `how` answers what the code does and how it works. `why` answers what forces led to its shape.
|
|
11
12
|
|
|
12
|
-
## How this skill works
|
|
13
|
-
|
|
14
|
-
Historical context spreads across seven evidence categories: source control history, issue or ticket tracking, long-form documents, real-time team chat, infrastructure observability, error or exception tracking, and product analytics warehouses. You cannot predict from the question alone which one holds the answer, so the skill enumerates available MCPs at run time, maps each to a category, queries all seven in parallel, then synthesizes with explicit confidence calibration. Null results from searched categories are first-class evidence about how the decision was made; report them alongside positive findings. The default is coverage, not minimalism.
|
|
15
|
-
|
|
16
13
|
## Operating Posture
|
|
17
14
|
|
|
18
|
-
Operate as a careful, cautious, precise investigator
|
|
19
|
-
|
|
20
|
-
Concretely:
|
|
21
|
-
|
|
22
|
-
- **Evidence before narrative.** Collect the pieces first, then see what story they support. Never pick a story and recruit the evidence that fits it.
|
|
23
|
-
- **Precision over polish.** Prefer the exact quote and citation over a smooth paraphrase. A reader should be able to follow any claim back to its source and verify it in under a minute.
|
|
24
|
-
- **Consider what you haven't seen.** The evidence you find is a sample, not the whole truth. Before concluding, ask what you would expect to see if an alternative explanation were true, and whether you looked for it.
|
|
25
|
-
- **Name the gaps.** If a thread goes cold, a source isn't searchable, or a question has no answer, document the gap. Don't paper it over with an authoritative-sounding guess.
|
|
26
|
-
- **Hedge on purpose.** When evidence is indirect, your language should signal it ("appears to", "likely", "suggests"). Confidence-matching phrasing is a feature of the output, not a stylistic choice the synthesizer may override.
|
|
27
|
-
- **No shortcut by code-reading.** The code tells you what it does, rarely why it exists. Resist inferring intent from code shape.
|
|
28
|
-
|
|
29
|
-
This posture is the working method, not a disclaimer.
|
|
30
|
-
|
|
31
|
-
## Core Epistemics
|
|
32
|
-
|
|
33
|
-
This skill builds a **patchwork understanding** from fragmented historical evidence. Tickets go stale. Chat threads get deleted. Commit messages lie. People change their minds between the PR description and the implementation. The original author may have left the company.
|
|
34
|
-
|
|
35
|
-
Be ruthlessly honest about what you know versus what you're inferring. The goal is not a satisfying story; it is to surface evidence, calibrate confidence, and let the user decide.
|
|
36
|
-
|
|
37
|
-
Principles:
|
|
38
|
-
|
|
39
|
-
- **Cite everything.** Every claim about intent should reference a specific commit hash, PR number, ticket ID, doc URL, chat permalink, or code comment. If you can't cite it, it's inference, not fact, and must be labeled as such.
|
|
40
|
-
- **Prefer "appears to" over "because".** Hedge when evidence is indirect. Reserve confident language for direct, explicit evidence.
|
|
41
|
-
- **Surface contradictions.** If two sources disagree, show both. Don't quietly pick the one that fits your narrative.
|
|
42
|
-
- **Acknowledge gaps.** If a question has no answer in any source you searched, say so. An honest "we couldn't find out why" beats a confident guess.
|
|
43
|
-
- **Multiple hypotheses are valid.** When the evidence fits several stories, present them all with the evidence for each. Let the user triangulate.
|
|
44
|
-
- **Beware rationalization.** Code that makes sense today may have been written for reasons that no longer apply, or for no good reason at all. Don't retrofit intent.
|
|
45
|
-
|
|
46
|
-
Read `references/epistemics.md` for the full confidence framework and phrasing guide. The synthesizer must follow it.
|
|
15
|
+
Operate as a **careful, cautious, and precise investigator**. Be honest about what you know vs what you're inferring. Read `references/epistemics.md` for the full confidence framework and phrasing guide. The synthesizer must follow it.
|
|
47
16
|
|
|
48
17
|
## Step 1. Understand the Target and the Question
|
|
49
18
|
|
|
50
|
-
Parse what the user is asking. The **target** is usually a chunk of code, a pattern, a feature, or a named design decision. The **question** is usually
|
|
51
|
-
|
|
52
|
-
- "Why was X designed this way?" Design rationale.
|
|
53
|
-
- "Why do we do X instead of Y?" Tradeoff or alternatives.
|
|
54
|
-
- "What edge cases motivated this?" Defensive reasoning.
|
|
55
|
-
- "What business or product constraint led to this?" External forcing function.
|
|
56
|
-
- "Why does this code still exist?" Dead-code territory.
|
|
57
|
-
- "What's the history of X?" Broad archaeological sweep.
|
|
19
|
+
Parse what the user is asking. The **target** is usually a chunk of code, a pattern, a feature, or a named design decision. The **question** is usually a design rationale, a tradeoff, a motivating edge case, an external constraint, dead code, or a broad history sweep.
|
|
58
20
|
|
|
59
21
|
If the target is vague ("why do we do it this way?" with no clear referent), make your best guess from conversation context (open files, recent edits, cursor location, what was just discussed). State your interpretation briefly so the user can redirect if you're off, then proceed.
|
|
60
22
|
|
|
@@ -67,7 +29,7 @@ Before spawning investigators, anchor the investigation in concrete code. You ne
|
|
|
67
29
|
- An initial commit list. The last few commits touching the target.
|
|
68
30
|
- PR numbers from merge commits (pattern `(#1234)` in the subject line)
|
|
69
31
|
|
|
70
|
-
Build this inline.
|
|
32
|
+
Build this inline.
|
|
71
33
|
|
|
72
34
|
```bash
|
|
73
35
|
# Blame target lines for last-touch commits
|
|
@@ -89,15 +51,15 @@ Pull PR bodies and discussion via `gh` for any substantive commits:
|
|
|
89
51
|
gh pr view <number> --json title,body,author,createdAt,mergedAt,labels,closingIssuesReferences,comments,reviews
|
|
90
52
|
```
|
|
91
53
|
|
|
92
|
-
Capture this as seed context (file paths, symbols, commits, PR numbers, linked ticket IDs). Pass it to the investigators
|
|
54
|
+
Capture this as seed context (file paths, symbols, commits, PR numbers, linked ticket IDs). Pass it to the investigators.
|
|
93
55
|
|
|
94
56
|
## Step 3. Spawn Parallel Investigators (default posture)
|
|
95
57
|
|
|
96
|
-
**Default to the full parallel investigation.**
|
|
58
|
+
**Default to the full parallel investigation.**
|
|
97
59
|
|
|
98
60
|
### Discovery
|
|
99
61
|
|
|
100
|
-
Before spawning investigators, list the available MCPs
|
|
62
|
+
Before spawning investigators, list the available MCPs from the Pi session. Use the available-tools map when present. Otherwise inspect the MCP configuration Pi loads.
|
|
101
63
|
|
|
102
64
|
Map each available MCP to one evidence category:
|
|
103
65
|
|
|
@@ -111,14 +73,14 @@ Map each available MCP to one evidence category:
|
|
|
111
73
|
|
|
112
74
|
Source control is always available through git and `gh`. For the other six, classify using the MCP name, server instructions, tool names, and resource descriptors. If an MCP could fit more than one category, choose the one matching its primary evidence. Record ambiguous cases in the coverage map.
|
|
113
75
|
|
|
114
|
-
Aim for a complete **coverage map**, not a minimal one.
|
|
76
|
+
Aim for a complete **coverage map**, not a minimal one. Document the null, don't skip the search.
|
|
115
77
|
|
|
116
|
-
Launch all matching investigators in a single message so they run concurrently.
|
|
78
|
+
Launch all matching investigators in a single message so they run concurrently. Don't ask one agent to cover multiple MCPs.
|
|
117
79
|
|
|
118
80
|
Subagent config (each):
|
|
119
|
-
- `agent`: `
|
|
120
|
-
- `model`: your configured why-investigators model (default
|
|
121
|
-
-
|
|
81
|
+
- `agent`: the one `/pstack-setup` assigned this role
|
|
82
|
+
- `model`: your configured why-investigators model (default: inherit, the parent session model)
|
|
83
|
+
- `readonly`: `false` (agent mode). **Do not use readonly/Ask mode.** It strips MCP access, which disables MCP-backed investigators entirely. Investigators still shouldn't write anything.
|
|
122
84
|
|
|
123
85
|
Each investigator gets:
|
|
124
86
|
1. The base prompt from `references/investigator-prompt.md`
|
|
@@ -131,30 +93,28 @@ Each investigator gets:
|
|
|
131
93
|
|
|
132
94
|
Spawn one investigator per category that has a matching MCP. Each owns exactly one tool or MCP.
|
|
133
95
|
|
|
134
|
-
Each entry
|
|
96
|
+
Each entry names the category and the kind of "why" it uniquely surfaces. Use it to know what to expect back, how to name a gap when a category returns empty, and (only in the rare provably-irrelevant case) to justify a skip.
|
|
135
97
|
|
|
136
|
-
1. **Source control investigator**. Git history, `gh` for PRs, code comments, tests. Always spawn
|
|
98
|
+
1. **Source control investigator**. Git history, `gh` for PRs, code comments, tests. Always spawn. The only guaranteed source. Best at surfacing *implementation-time rationale captured during review*.
|
|
137
99
|
|
|
138
|
-
2. **Issue / ticket tracker investigator** (e.g. Linear, Jira, GitHub Issues, Plane, Shortcut MCP).
|
|
100
|
+
2. **Issue / ticket tracker investigator** (e.g. Linear, Jira, GitHub Issues, Plane, Shortcut MCP). Best at surfacing *the product or business forcing function*. Strongest when the why is external to engineering.
|
|
139
101
|
|
|
140
|
-
3. **Long-form documents investigator** (e.g. Notion, Confluence, Google Docs, Coda MCP).
|
|
102
|
+
3. **Long-form documents investigator** (e.g. Notion, Confluence, Google Docs, Coda MCP). Best at surfacing *long-form design rationale*. Where the why is written out before it becomes code.
|
|
141
103
|
|
|
142
|
-
4. **Real-time team chat investigator** (e.g. Slack, Discord, Microsoft Teams, Mattermost MCP).
|
|
104
|
+
4. **Real-time team chat investigator** (e.g. Slack, Discord, Microsoft Teams, Mattermost MCP). Best at surfacing *real-time deliberation that never reached a doc*. Especially important when the source control, ticket, and doc paper trail is thin.
|
|
143
105
|
|
|
144
|
-
5. **Infrastructure observability investigator** (e.g. Datadog, New Relic, Honeycomb, Grafana, Splunk MCP).
|
|
106
|
+
5. **Infrastructure observability investigator** (e.g. Datadog, New Relic, Honeycomb, Grafana, Splunk MCP). Infra/runtime view. Best at surfacing *infrastructure and runtime reality that motivated the code*. Strongest when the target reacts to an infra signal (timeouts, retries, rate limits, circuit breakers).
|
|
145
107
|
|
|
146
|
-
6. **Error / exception tracking investigator** (e.g. Sentry, Rollbar, Bugsnag, Airbrake MCP).
|
|
108
|
+
6. **Error / exception tracking investigator** (e.g. Sentry, Rollbar, Bugsnag, Airbrake MCP). Best at surfacing *the specific exceptions and error trajectories that motivated defensive or corrective code*. Strongest for catch blocks, null guards, type checks, retries, and other defenses.
|
|
147
109
|
|
|
148
|
-
7. **Product analytics warehouse investigator** (e.g. Databricks, Snowflake, BigQuery, ClickHouse, dbt, Redshift MCP). Product
|
|
110
|
+
7. **Product analytics warehouse investigator** (e.g. Databricks, Snowflake, BigQuery, ClickHouse, dbt, Redshift MCP). Product/data view. Best at surfacing *product and data reality that shaped the code*. Strongest for flag-gated code, experiment-driven ships, data migrations, and "where did this number come from" questions.
|
|
149
111
|
|
|
150
112
|
### When to skip an investigator
|
|
151
113
|
|
|
152
114
|
Only skip with an **explicit, written justification** that goes in the final "Sources Consulted" section. Two valid reasons:
|
|
153
115
|
|
|
154
116
|
- **No MCP is available for that category** in this environment. Flag this as a gap, not a choice. Example: "Real-time team chat skipped. No matching MCP available, so the conversational record was not searchable."
|
|
155
|
-
- **The source is provably irrelevant**, not just "probably irrelevant." A high bar. Example: "Error / exception tracking skipped. Target is a build-time script with no runtime code path."
|
|
156
|
-
|
|
157
|
-
"It's pure feature code, error tracking won't have anything" is **not** sufficient, and neither is "I doubt long-form docs would have this." Run the search; let the null result speak. The cost of an investigator returning empty is one subagent. The cost of missing a design doc that actually exists is a wrong answer.
|
|
117
|
+
- **The source is provably irrelevant**, not just "probably irrelevant." A high bar. Example: "Error / exception tracking skipped. Target is a build-time script with no runtime code path."
|
|
158
118
|
|
|
159
119
|
If your scope assessment suggests a single-commit trivial target where the PR description already contains the complete answer, you may answer inline **only after** confirming all seven available category searches would be redundant. Say so explicitly. This should be rare.
|
|
160
120
|
|
|
@@ -162,9 +122,9 @@ If your scope assessment suggests a single-commit trivial target where the PR de
|
|
|
162
122
|
|
|
163
123
|
Spawn one synthesizer subagent:
|
|
164
124
|
|
|
165
|
-
- `agent`: `
|
|
166
|
-
- `model`: your configured why-synthesizer model (default
|
|
167
|
-
-
|
|
125
|
+
- `agent`: the one `/pstack-setup` assigned this role
|
|
126
|
+
- `model`: your configured why-synthesizer model (default: inherit, the parent session model)
|
|
127
|
+
- `readonly`: `false` (agent mode). The synthesizer's quality check spot-verifies citations, which can require MCP access. Readonly/Ask mode strips MCPs and defeats that.
|
|
168
128
|
|
|
169
129
|
The synthesizer gets:
|
|
170
130
|
1. The investigator findings, including any null results and any categories skipped with justification
|
|
@@ -173,52 +133,19 @@ The synthesizer gets:
|
|
|
173
133
|
4. The epistemics framework from `references/epistemics.md`
|
|
174
134
|
5. The synthesizer prompt template from `references/synthesizer-prompt.md`
|
|
175
135
|
|
|
176
|
-
Its job is the final output: a confidence-weighted, evidence-cited narrative with clearly separated "what we know" and "what we're inferring" sections, plus honest acknowledgment of gaps and null-result sources.
|
|
177
|
-
|
|
178
136
|
## Step 5. Present
|
|
179
137
|
|
|
180
|
-
Take the synthesizer's output and present it to the user. You may lightly edit for clarity or add context from the conversation, but **do not rewrite the confidence language**.
|
|
138
|
+
Take the synthesizer's output and present it to the user. You may lightly edit for clarity or add context from the conversation, but **do not rewrite the confidence language**.
|
|
181
139
|
|
|
182
140
|
## Output Format
|
|
183
141
|
|
|
184
|
-
The
|
|
185
|
-
|
|
186
|
-
**The Question**. Restate what the user asked, concisely.
|
|
187
|
-
|
|
188
|
-
**The Code in Question**. File paths, line ranges, and key symbols. One or two lines so the reader is anchored.
|
|
189
|
-
|
|
190
|
-
**What We Found (direct evidence)**. Claims with explicit citations (PR #, ticket ID, doc URL, chat permalink, commit hash, code comment with file:line). Each bullet is a thing we have textual evidence for. Use present tense and quote or paraphrase the source.
|
|
191
|
-
|
|
192
|
-
**What We Can Reasonably Infer**. Claims well-supported by indirect evidence or combinations of signals, but not explicitly stated anywhere. Each bullet must explain the inference chain: "Given A and B, it's likely that C." Use hedged language ("appears to", "likely", "suggests").
|
|
193
|
-
|
|
194
|
-
**Competing Hypotheses**. If the evidence fits multiple stories, list them. For each, give the hypothesis, the evidence for it, and the evidence against it. Don't force a winner when the record doesn't support one. (Skip this section if there's a clear answer.)
|
|
195
|
-
|
|
196
|
-
**What We Don't Know**. Explicit gaps. Questions the user asked that the evidence didn't answer. Sources we searched and came up empty. Be specific. "We searched the issue tracker for 'rate limit' and found no ticket discussing this specific threshold" is more useful than "we don't know why."
|
|
197
|
-
|
|
198
|
-
**Sources Consulted**. One line per investigator, including the ones that returned nothing. The reader should see at a glance (a) which MCPs were queried, (b) which came back empty, and (c) which were skipped and why. This coverage map lets the user judge breadth and redirect if something obvious was missed.
|
|
199
|
-
|
|
200
|
-
Format each line as: `- <Source>: <what was searched>. <what was found, or "no relevant results," or "skipped. reason">.`
|
|
201
|
-
|
|
202
|
-
Example:
|
|
203
|
-
- Source control (git/gh): `git log --follow backend/retry.ts`, PRs #49074, #47812. Found PR #49074 introduced exponential backoff and linked ENG-4421.
|
|
204
|
-
- Issue tracker (Linear): searched for "retry" and ENG-4421. Found ENG-4421 parent issue but no discussion of backoff parameters.
|
|
205
|
-
- Long-form docs (Notion): searched for "retry policy," "backend retries," "ENG-4421." No relevant results.
|
|
206
|
-
- Real-time team chat (Slack): skipped. No matching MCP available in this environment. Gap: conversational record not searched.
|
|
207
|
-
- Infrastructure observability (Datadog): searched for `retry_count` metric and monitors around 2024-08-14. Found monitor "Upstream 5xx rate > 1%" created same day as PR #49074.
|
|
208
|
-
- Error / exception tracking (Sentry): searched for issues first-seen in Aug 2024 with stack through `retry.ts`. Found issue SENTRY-3821 spiking in the week before the PR.
|
|
209
|
-
- Product analytics warehouse (Databricks): queried `<your_analytics_db>.<schema>.stg_backend_upstream_retry` for the 30-day window around 2024-08-14. Daily failure-classified event count fell from ~1.2k/day pre-PR to <50/day post-PR. Also checked `system.query.history` for relevant migration queries. None found.
|
|
142
|
+
The output structure is the one in `references/synthesizer-prompt.md`: The Question, The Code in Question, What We Found, What We Can Reasonably Infer, Competing Hypotheses, What We Don't Know, Sources Consulted, Confidence Summary. Adapt as needed, but keep the confidence separation intact, and keep Sources Consulted as one line per investigator, including the ones that returned nothing or were skipped, with the reason.
|
|
210
143
|
|
|
211
144
|
After the Sources Consulted block, if the user's `why` question is a precursor to actually changing this code, convert the lineage findings into a Preserve / Change / Avoid / Risk constraint set suitable for planning the change.
|
|
212
145
|
|
|
213
146
|
## Common Failure Modes to Avoid
|
|
214
147
|
|
|
215
|
-
- **Confident storytelling**. A plausible narrative built from thin evidence. A bullet with no citation goes in "inferred" or "hypotheses," not "what we found."
|
|
216
|
-
- **Citing the code as evidence for its own intent**. "Handles the null case because it checks for null" is mechanics, not motivation. Motivation comes from an external source (PR discussion, ticket, comment, conversation) or is labeled as inference.
|
|
217
148
|
- **Recency bias**. Assuming the most recent commit is authoritative. The current shape is often the accretion of many earlier decisions. Trace back.
|
|
218
|
-
- **Sycophantic agreement**. If the user suggests a reason ("I assume this is for performance?"), treat it as a hypothesis and check the evidence independently, don't just confirm it.
|
|
219
|
-
- **Skipping the gaps section**. An honest accounting of what you couldn't find out is part of the value.
|
|
220
|
-
- **Skipping investigators by anticipation**. Deciding up front that "long-form docs probably don't have this" or "this isn't an error tracking thing" without searching. The default-to-all-seven posture prevents this. A null result is a data point; a skipped search is a blind spot.
|
|
221
|
-
- **Collapsing investigators into one agent**. Each MCP has its own query vocabulary, result shape, and pitfalls; pooling them dilutes specialization and makes coverage harder to reason about. Always one investigator per category.
|
|
222
149
|
|
|
223
150
|
## Reference Files
|
|
224
151
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
How to reason about confidence when evidence is historical, fragmentary, and sometimes contradictory, and how to communicate it without flattening it into false certainty.
|
|
4
4
|
|
|
5
|
-
Code doesn't carry its own motivation. You can read what code does
|
|
5
|
+
Code doesn't carry its own motivation. You can read what code does. You can't read *why it exists*. That lives in commits, PRs, tickets, docs, and conversations, all incomplete, biased, and sometimes missing entirely. Pretending otherwise produces confident-sounding guesses that mislead the user.
|
|
6
6
|
|
|
7
7
|
## Confidence Tiers
|
|
8
8
|
|
|
@@ -38,7 +38,7 @@ A reasonable reading of the context, but nothing explicitly supports it. The rea
|
|
|
38
38
|
|
|
39
39
|
Examples:
|
|
40
40
|
- The PR doesn't say why, but given the error was happening in production (per the incident channel timing) and the fix was rushed (merged the same day), it was likely a hotfix.
|
|
41
|
-
- The function name suggests retry logic
|
|
41
|
+
- The function name suggests retry logic. The retry count is 3. This matches the team's general convention of "3 retries" seen elsewhere in the codebase.
|
|
42
42
|
|
|
43
43
|
Phrasing: hedged. "It appears", "likely", "suggests", "is consistent with", "one reading is". Make the inference chain explicit: "Given A and B, C seems likely because D."
|
|
44
44
|
|
|
@@ -56,7 +56,7 @@ Phrasing: explicitly speculative. "One possibility is X, but we have no direct e
|
|
|
56
56
|
|
|
57
57
|
You looked and couldn't find out. A valid and important outcome. Document it.
|
|
58
58
|
|
|
59
|
-
Phrasing: "We searched X, Y, and Z and found no evidence of why." Be specific about *what* you searched. "We couldn't find out" is less useful than "we searched the ticket tracker with keywords A and B, scanned the 6 PRs that touched this file since 2023, and grep'd the repo for string literals matching the threshold
|
|
59
|
+
Phrasing: "We searched X, Y, and Z and found no evidence of why." Be specific about *what* you searched. "We couldn't find out" is less useful than "we searched the ticket tracker with keywords A and B, scanned the 6 PRs that touched this file since 2023, and grep'd the repo for string literals matching the threshold. None surfaced a rationale."
|
|
60
60
|
|
|
61
61
|
## Phrasing Guide
|
|
62
62
|
|
|
@@ -105,7 +105,7 @@ Resist the urge to:
|
|
|
105
105
|
|
|
106
106
|
## The Sycophancy Trap
|
|
107
107
|
|
|
108
|
-
Users often phrase `why` questions with an embedded hypothesis: "Why do we do it this way, I assume it's for performance?" Don't simply confirm it. Treat it as one candidate among others and check the evidence independently. If the evidence supports it, say so with citations
|
|
108
|
+
Users often phrase `why` questions with an embedded hypothesis: "Why do we do it this way, I assume it's for performance?" Don't simply confirm it. Treat it as one candidate among others and check the evidence independently. If the evidence supports it, say so with citations. If not, say so and present what the evidence *does* support.
|
|
109
109
|
|
|
110
110
|
The user's guess is a prompt for investigation, not a conclusion to validate.
|
|
111
111
|
|
|
@@ -126,7 +126,7 @@ An honest "we don't know" is one of the most valuable outputs this skill can pro
|
|
|
126
126
|
- They'll need to ask a human (the original author, the product owner, the team lead) to find out
|
|
127
127
|
- Or they can decide the question isn't worth pursuing further
|
|
128
128
|
|
|
129
|
-
Failing to mark a gap and filling it with a confident guess actively harms the user
|
|
129
|
+
Failing to mark a gap and filling it with a confident guess actively harms the user. They'll act on the guess.
|
|
130
130
|
|
|
131
131
|
When you hit a gap, name it concretely:
|
|
132
132
|
- What question you were trying to answer
|
|
@@ -139,6 +139,6 @@ When you hit a gap, name it concretely:
|
|
|
139
139
|
Before delivering the output, the synthesizer should review every claim in "What We Found" and "What We Can Reasonably Infer" and ask:
|
|
140
140
|
|
|
141
141
|
1. Does this claim have a citation? If not, either add one or move it to "Inferred" / "Hypotheses".
|
|
142
|
-
2. Is the phrasing calibrated to the tier? (A Direct claim can use "because"
|
|
142
|
+
2. Is the phrasing calibrated to the tier? (A Direct claim can use "because". An Inferred claim cannot.)
|
|
143
143
|
3. Am I treating the code itself as evidence for its own intent? If so, that's not evidence. Remove or reclassify.
|
|
144
144
|
4. Does the output include a "What We Don't Know" section? If no gaps are mentioned, that's suspicious. Either the evidence was unusually complete or something is being swept under the rug.
|