ralphctl 0.25.0 → 0.27.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.
Files changed (59) hide show
  1. package/README.md +11 -5
  2. package/THIRD-PARTY-NOTICES.md +65 -2
  3. package/dist/agent-definitions/ralphctl-generator.md +3 -2
  4. package/dist/{cli-GQBXYNFN.mjs → cli-EYDXERW6.mjs} +9423 -6665
  5. package/dist/cli.mjs +1 -1
  6. package/dist/manifest.json +20 -3
  7. package/dist/prompts/_partials/approval-gate.md +5 -5
  8. package/dist/prompts/_partials/autonomous-operation.md +23 -6
  9. package/dist/prompts/_partials/conventions-agents-md.md +8 -20
  10. package/dist/prompts/_partials/conventions-claude-md.md +12 -15
  11. package/dist/prompts/_partials/conventions-copilot-instructions.md +6 -10
  12. package/dist/prompts/_partials/decisions.md +3 -9
  13. package/dist/prompts/_partials/evaluator-failure-modes.md +11 -5
  14. package/dist/prompts/_partials/evaluator-grading-rules.md +25 -10
  15. package/dist/prompts/_partials/evidence-bound.md +2 -2
  16. package/dist/prompts/_partials/git-boundary.md +7 -0
  17. package/dist/prompts/_partials/harness-context.md +1 -1
  18. package/dist/prompts/_partials/one-shot-operation.md +6 -0
  19. package/dist/prompts/_partials/question-format.md +7 -0
  20. package/dist/prompts/_partials/skill-body.md +5 -0
  21. package/dist/prompts/_partials/task-blocked.md +10 -0
  22. package/dist/prompts/_partials/task-fields.md +19 -3
  23. package/dist/prompts/_partials/task-sizing.md +2 -2
  24. package/dist/prompts/_partials/validation-checklist.md +6 -8
  25. package/dist/prompts/apply-feedback/template.md +24 -25
  26. package/dist/prompts/create-pr/template.md +21 -15
  27. package/dist/prompts/detect-scripts/template.md +10 -9
  28. package/dist/prompts/detect-skills/template.md +19 -23
  29. package/dist/prompts/distill-learnings/template.md +10 -8
  30. package/dist/prompts/evaluate/template.md +74 -93
  31. package/dist/prompts/evaluate-continuation/template.md +19 -22
  32. package/dist/prompts/ideate/template.md +36 -47
  33. package/dist/prompts/implement/template.md +59 -73
  34. package/dist/prompts/implement-continuation/template.md +21 -20
  35. package/dist/prompts/implement-crash-resume/template.md +13 -4
  36. package/dist/prompts/plan/template.md +75 -64
  37. package/dist/prompts/readiness/template.md +36 -27
  38. package/dist/prompts/refine/template.md +37 -50
  39. package/dist/prompts/reproduce/template.md +9 -7
  40. package/dist/prompts/select-candidate/template.md +17 -10
  41. package/dist/skills/ralphctl-api-and-interface-design/SKILL.md +117 -0
  42. package/dist/skills/ralphctl-code-review-and-quality/SKILL.md +119 -8
  43. package/dist/skills/ralphctl-code-simplification/SKILL.md +100 -0
  44. package/dist/skills/ralphctl-codebase-design/SKILL.md +82 -0
  45. package/dist/skills/ralphctl-debugging-and-error-recovery/SKILL.md +23 -5
  46. package/dist/skills/ralphctl-deprecation-and-migration/SKILL.md +106 -0
  47. package/dist/skills/ralphctl-frontend-ui-engineering/SKILL.md +94 -0
  48. package/dist/skills/ralphctl-humanizer/SKILL.md +137 -0
  49. package/dist/skills/ralphctl-idea-refinement/SKILL.md +2 -0
  50. package/dist/skills/ralphctl-iterative-review/SKILL.md +10 -4
  51. package/dist/skills/ralphctl-observability-and-instrumentation/SKILL.md +104 -0
  52. package/dist/skills/ralphctl-performance-optimization/SKILL.md +123 -0
  53. package/dist/skills/ralphctl-ponytail/SKILL.md +38 -28
  54. package/dist/skills/ralphctl-security-and-hardening/SKILL.md +259 -0
  55. package/dist/skills/ralphctl-source-driven-development/SKILL.md +103 -0
  56. package/dist/skills/ralphctl-spec-driven-development/SKILL.md +148 -0
  57. package/dist/skills/ralphctl-test-driven-development/SKILL.md +29 -2
  58. package/dist/skills/ralphctl-writing-for-agents/SKILL.md +113 -0
  59. package/package.json +10 -10
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: ralphctl-deprecation-and-migration
3
+ description: Discipline for removing or replacing code, interfaces, stored data shapes, and dependencies safely — confirm the replacement covers every consumer, migrate consumers incrementally behind an adapter or switch, change persisted data in additive expand-then-contract phases with a tested way back, and remove the old path only once nothing uses it. Use when retiring an API, module, feature, flag, or dependency, renaming or dropping a stored field, or moving callers from one implementation to another.
4
+ license: MIT
5
+ ---
6
+
7
+ # Deprecation and Migration
8
+
9
+ > Adapted from [addyosmani/agent-skills — "Deprecation and Migration"](https://github.com/addyosmani/agent-skills)
10
+ > (MIT). Adapted for ralphctl's harness contract.
11
+
12
+ Code is a liability, not an asset: every line needs tests, upgrades, and attention from anyone working
13
+ nearby. Deprecation removes code that no longer earns its keep; migration moves its consumers safely to
14
+ what replaces it. Most teams are good at adding things and bad at removing them — this skill is the
15
+ removal half.
16
+
17
+ ## When this applies
18
+
19
+ - **Plan** — sequence the work so each step ships on its own: the replacement first, consumers next,
20
+ removal last and alone. Give the removal task the verification criterion "no remaining consumers", and
21
+ keep each data-shape phase below a separate task.
22
+ - **Execute** — implement one phase per task. Do not fold an additive step and its destructive follow-up
23
+ into one change, and do not remove anything a consumer still reaches.
24
+
25
+ ## Before removing anything
26
+
27
+ Hyrum's law makes removal hard: consumers depend on behaviour the replacement may not reproduce —
28
+ ordering, defaults, error text, side effects. Answer first:
29
+
30
+ 1. Does the old thing still provide something nothing else does? If so, keep it.
31
+ 2. Who consumes it? Search code, configuration, scripts, docs, and tests, including dynamic lookups by
32
+ name. Consumers outside this repository may exist — say so rather than assume none.
33
+ 3. Does a replacement exist and cover every critical use? If not, build that first.
34
+ 4. What does each consumer's move cost, against the ongoing cost of keeping both?
35
+
36
+ ## The process
37
+
38
+ 1. **Replacement first.** It covers the critical cases and is proven, not just "theoretically better".
39
+ 2. **Mark the old path deprecated** with the project's own mechanism — a deprecation annotation, a
40
+ runtime warning, a changelog entry — when it has one. Do not invent a new notice file.
41
+ 3. **Migrate incrementally.** One consumer or area per change: find its touchpoints, switch it, confirm
42
+ behaviour matches with its tests, remove its reference to the old path. Whoever retires a thing
43
+ migrates its consumers or ships a compatible shim — never leave them to discover the break.
44
+ 4. **Remove only at zero.** Once no consumer remains: the code, its tests, docs, configuration, and the
45
+ deprecation markers themselves.
46
+
47
+ ## Migration patterns
48
+
49
+ - **Strangler** — run old and new side by side and route a growing share to the new path; remove the old
50
+ one when its share is zero.
51
+ - **Adapter** — keep the old interface as a thin layer over the new implementation, so consumers keep
52
+ working while the backend moves.
53
+ - **Switch per consumer** — cut consumers over one at a time with the project's existing flag or
54
+ configuration mechanism.
55
+
56
+ ## Persisted data: expand, then contract
57
+
58
+ A stored shape is the riskiest thing to change — reverting the code does not revert the data, and during a
59
+ rollout old and new code run against the same store. Never change a stored shape in place:
60
+
61
+ ```
62
+ EXPAND → MIGRATE → CONTRACT
63
+ add the new shape write both, backfill old records, stop writing the old shape,
64
+ beside the old one then switch reads to the new one then drop it in a later change
65
+ ```
66
+
67
+ - Additive first, destructive last and alone. Adds are safe in any release; drops and renames ship on
68
+ their own, after nothing reads the old shape.
69
+ - Every migration has a tested way back — a down migration, or readers that tolerate both shapes.
70
+ - A migration is safe to re-run and safe to interrupt; stamp what has been migrated.
71
+ - Backfill in batches, off the hot path, so it does not lock or starve the store.
72
+ - The same rules hold for files on disk: version the format, and keep readers tolerant of the old shape.
73
+
74
+ ## Zombie code
75
+
76
+ Code nobody owns but something still depends on — no maintainer, failing tests nobody fixes, outdated
77
+ dependencies. Either give it an owner and maintain it, or deprecate it with a concrete migration. It
78
+ cannot stay in limbo.
79
+
80
+ ## Common rationalisations
81
+
82
+ | Rationalisation | Reality |
83
+ | ------------------------------------------------- | ----------------------------------------------------------------------------------------- |
84
+ | "It still works, why remove it?" | Unmaintained working code accumulates risk and complexity silently. |
85
+ | "Someone might need it later" | It can be rebuilt if needed. Keeping it "just in case" costs more. |
86
+ | "Consumers will migrate on their own" | They will not. Migrate them, or ship a shim that needs no migration. |
87
+ | "Just rename the field, it's one line" | During rollout, old and new code run together and one of them reads a field that is gone. |
88
+ | "Add the new field and drop the old one together" | That couples a safe add to a destructive drop. Drops ship alone, later. |
89
+ | "We'll write the way back if we need it" | A migration with no way back is a release you cannot undo. |
90
+
91
+ ## Red flags
92
+
93
+ - A deprecation with no working replacement.
94
+ - Removal without a search for remaining consumers.
95
+ - New features added to the deprecated path.
96
+ - A stored field renamed or dropped in place.
97
+ - A schema change and the code that depends on it shipped as one step.
98
+ - A migration with no way back, or a backfill that locks the store.
99
+
100
+ ## Self-check
101
+
102
+ - [ ] The replacement covers every critical use of the old path.
103
+ - [ ] Every known consumer is migrated; unknown external consumers are named as a risk.
104
+ - [ ] Persisted-shape changes are phased: expand, migrate, contract.
105
+ - [ ] Each migration has a tested way back and is safe to re-run.
106
+ - [ ] Removal deletes the code, its tests, docs, configuration, and deprecation markers.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: ralphctl-frontend-ui-engineering
3
+ description: UI engineering discipline for user-facing interfaces — follow the project's design system and tokens instead of a generic look, handle loading, empty, error, and permission states, meet accessibility basics (keyboard access, labels, focus, contrast, never colour alone), and keep components focused with data loading separate from presentation. Use when building or changing screens, components, layouts, or interaction states in any UI stack.
4
+ license: MIT
5
+ ---
6
+
7
+ # Frontend UI Engineering
8
+
9
+ > Adapted from [addyosmani/agent-skills — "Frontend UI Engineering"](https://github.com/addyosmani/agent-skills)
10
+ > (MIT). Adapted for ralphctl's harness contract.
11
+
12
+ Build interfaces that look like a design-aware engineer made them for this product: the project's own
13
+ design system, every state handled, usable from a keyboard and a screen reader. The specifics differ by
14
+ stack — a component framework, server-rendered templates, a native toolkit — so learn this project's
15
+ before writing any UI.
16
+
17
+ ## When this applies
18
+
19
+ - **Execute** — whenever the task builds or changes something a user sees or operates. When reviewing a
20
+ UI change, use the self-check below as the lens: a missing state or an inaccessible control is a
21
+ finding, not a nit.
22
+
23
+ ## Discover the UI stack first
24
+
25
+ Find the component library, the theme or token file (colour, spacing, type, radius), the existing
26
+ components that already solve part of the task, and how the project tests UI (component tests,
27
+ accessibility checks, visual or browser tests). Reuse a house component before writing a new one.
28
+
29
+ ## Components
30
+
31
+ - **One job per component.** A component that fetches, transforms, and renders is three things.
32
+ - **Composition over configuration.** A growing list of layout and variant flags signals a component
33
+ that should accept children or slots instead.
34
+ - **Data apart from presentation.** A container loads data and decides which state to show; a
35
+ presentational piece renders what it is given. The presentational piece is then trivial to test.
36
+ - **The simplest state that works.** Local state first; lift it only when siblings share it; a shared
37
+ context for read-mostly app-wide values; the URL for shareable view state (filters, pagination); the
38
+ project's server-data layer for remote data; a global store only for complex client state many places
39
+ share. Use the mechanisms the project already has.
40
+
41
+ ## Follow the design system
42
+
43
+ - Use the project's tokens for colour, spacing, type, and radius — never a raw value off the scale.
44
+ - Keep the type hierarchy: heading levels in order, heading styles only on headings.
45
+ - Use realistic content when building, not placeholder text — real lengths reveal wrapping and overflow.
46
+ - Avoid the generic generated look: a default accent palette on everything, decorative gradients,
47
+ maximal rounding, uniform oversized padding, stock card grids, stacked shadows. Each one ignores the
48
+ product's real hierarchy; the project's system already decided these.
49
+
50
+ ## Handle every state
51
+
52
+ Each view that loads or changes data needs, where it applies:
53
+
54
+ - **Loading** — a placeholder that keeps the layout stable.
55
+ - **Empty** — what this is and the next action, never a blank area.
56
+ - **Error** — what went wrong in plain words and a way to retry.
57
+ - **Partial or not permitted** — what the user can still do.
58
+ - **Success** — feedback that the action happened.
59
+
60
+ Check long and short content, and the narrowest and widest layouts the product supports.
61
+
62
+ ## Accessibility basics
63
+
64
+ - Use native interactive elements (buttons, links, inputs) over clickable generic containers. A custom
65
+ control needs a role, keyboard focus, and the expected key handling.
66
+ - Every control is reachable and operable from the keyboard, in a sensible order.
67
+ - Every input has a label; an icon-only control has an accessible name.
68
+ - Move focus deliberately when content changes — into a dialog when it opens, back when it closes.
69
+ - Text meets WCAG AA contrast (4.5:1 for body text, 3:1 for large text).
70
+ - Never convey state by colour alone; pair it with text or an icon.
71
+
72
+ ## Verification
73
+
74
+ Extend the project's existing UI tests for the new states and controls. When the project has no way to
75
+ check something in this session (a visual check, a screen-reader pass), say what was not verified in a
76
+ `note` signal when the prompt's output-contract section lists it; otherwise fold it into the required
77
+ signal's own fields.
78
+
79
+ ## Red flags
80
+
81
+ - Raw colour or spacing values instead of tokens.
82
+ - A view with no loading, empty, or error state.
83
+ - A clickable element that the keyboard cannot reach.
84
+ - Colour as the only indicator of state.
85
+ - A new component that duplicates one the project already has.
86
+
87
+ ## Self-check
88
+
89
+ - [ ] Uses the project's components and tokens.
90
+ - [ ] Loading, empty, error, permission, and success states are handled where they apply.
91
+ - [ ] Every interactive element works from the keyboard and has an accessible name.
92
+ - [ ] Focus moves correctly when content changes.
93
+ - [ ] Contrast meets AA; no state is conveyed by colour alone.
94
+ - [ ] Works at the narrowest and widest supported layouts.
@@ -0,0 +1,137 @@
1
+ ---
2
+ name: ralphctl-humanizer
3
+ description: Edit prose so it reads like a specific person wrote it while keeping its meaning intact — remove staged contrasts, restating closers, run-up openers, reflexive lists of three, dash-chained clauses, inflated significance, promotional and stock model vocabulary, decorative bold and headings, and chat leftovers, while keeping every fact and the format the output contract requires. Use when writing or revising human-facing text such as a PR description, requirements prose, or a summary.
4
+ license: MIT
5
+ ---
6
+
7
+ # Humanizer
8
+
9
+ > Concept from [blader/humanizer](https://github.com/blader/humanizer) (MIT), which builds on Wikipedia's
10
+ > "Signs of AI writing" guide. The pattern catalogue below is written fresh for ralphctl, not copied.
11
+ > Adapted for ralphctl's harness contract.
12
+
13
+ Generated prose defaults to whatever suits the most readers, so the same safe moves recur in every text.
14
+ Someone writing for a particular reader makes particular choices. This skill strips the defaults and keeps
15
+ the content.
16
+
17
+ ## How this runs here
18
+
19
+ - Apply it while writing the prose your output signal carries. The signal gets only the final text — no
20
+ draft, no list of patterns found, no commentary about the edit.
21
+ - The prompt's output contract wins: keep its required headings, sections, field formats, and literal
22
+ values. Leave code, commands, paths, identifiers, and link targets exactly as they are.
23
+ - Add nothing. No fact, name, number, date, or claim that is not in your source material. If a sentence
24
+ only works with a detail you don't have, simplify the sentence instead.
25
+
26
+ ## When this applies
27
+
28
+ - **Create PR** — the title and the description body.
29
+ - **Refine** — the prose around the requirements. Plain wording never costs a criterion its precision; a
30
+ testable predicate stays testable.
31
+
32
+ ## Method
33
+
34
+ 1. **Spot the patterns.** Go through the full draft and mark each pattern listed below. They also show up
35
+ across sentences and paragraphs: a contrast spread over two sentences counts, and so does every section
36
+ ending on an identical wrap-up line.
37
+ 2. **Rewrite each point plainly.** State it directly. When a paragraph is awkward, restructure it from its
38
+ central point instead of patching phrases. Let sentence length vary.
39
+ 3. **Check the result.** Nothing added, nothing lost. Then look once more for the tells that survive a
40
+ rewrite most often: contrasts, closers, threes, dashes, and bold labels.
41
+
42
+ ## Patterns, strongest first
43
+
44
+ ### Staging instead of saying
45
+
46
+ 1. **Contrast with a claim nobody made.** "This isn't just X — it's Y", "rather than X", a "No, it's
47
+ not…" sentence followed by the real point, a trailing "— no X needed". The negative half inflates the
48
+ positive one. A contrast earns its place if it fixes a misconception your reader really has, or if each
49
+ side tells them something.
50
+ 2. **Closers that restate.** A last short line repeating the paragraph ("That's the whole point."), a
51
+ string of fragments for drama, emphasis by capitals or dotted words. Cut it unless it adds a fact.
52
+ 3. **Borrowed depth.** "At its heart", "the real question is", "X is the currency of Y". Drop the
53
+ aphorism and state the concrete point.
54
+ 4. **Run-ups.** Announcing what comes next ("Here's the thing", "Let's walk through it", "Quick note").
55
+ Start with the content.
56
+ 5. **Answering no one.** "To be clear", "This doesn't mean", "You might think". Remove the defence unless
57
+ the objection is real in context.
58
+
59
+ ### Rhythm by habit
60
+
61
+ 6. **Reflexive threes.** Three items because three sounds complete. Keep three only when there are three
62
+ distinct things.
63
+ 7. **Repeated openings.** Consecutive sentences that open with the same word or phrase. Merge them or
64
+ vary the subject.
65
+ 8. **Dashes as default glue.** Reach for ordinary punctuation first (full stop, comma, colon, brackets) and
66
+ use a dash only when none of those works. Never touch a dash that belongs to code, a command, a path, or
67
+ a URL.
68
+ 9. **Piled hedges.** "Could potentially perhaps". Keep one qualifier where the doubt is real.
69
+
70
+ ### Inflation
71
+
72
+ 10. **Stock model vocabulary.** Words that turn up far more in generated text than in people's: delve,
73
+ seamless, leverage and harness (as figurative verbs), robust (when not technical), crucial, pivotal,
74
+ myriad, realm, tapestry, landscape (abstract), foster, elevate, empower, unlock, streamline,
75
+ showcase, underscore, testament, meticulous, game-changing, cutting-edge. Use the plain word. One on
76
+ its own is weak evidence; a cluster is strong.
77
+ 11. **Inflated significance.** "Marks a turning point", "paves the way", "raises the bar", a closing
78
+ paragraph about what the future holds. Stop once the concrete facts run out.
79
+ 12. **Editorialising -ing tails.** "…, highlighting its importance", "…, ensuring a smooth experience".
80
+ Keep the fact; drop the tail unless the source supports it.
81
+ 13. **Promotional tone.** "Powerful", "effortless", "best-in-class", "beautifully". Say what the thing does.
82
+ 14. **Vague authority.** "Experts agree", "widely regarded". Name the source or drop the claim.
83
+ 15. **Dodging plain verbs.** "Serves as", "functions as", "boasts". Use is and has.
84
+ 16. **Vague links.** "Associated with", "tied to". Name the actual relation, or keep the vague wording
85
+ when the source gives nothing more.
86
+
87
+ ### Formatting by habit
88
+
89
+ 17. **Bold everywhere.** Bold on ordinary words, or a bolded label plus colon at the start of every
90
+ bullet. Remove the bold, and when the labels say nothing, rewrite the list as sentences.
91
+ 18. **Decorated headings.** Title Case, emoji, arrows, a rule between every section. Use sentence case and
92
+ plain headings, unless the contract prescribes the heading text.
93
+
94
+ ### Leftovers
95
+
96
+ 19. **Chat residue.** "I hope this helps", "Great question", "Happy to adjust this", offers to do
97
+ more. Remove the wrapper, keep the content.
98
+ 20. **Writing about the text.** "Below is a summary of", "this description was generated from",
99
+ narrating how the text was assembled. Describing what a change replaces is fine in a PR description —
100
+ that is its subject.
101
+ 21. **Knowledge-limit filler.** Conceding that information is missing, then papering over the hole with
102
+ something that merely sounds right. Say plainly what is unknown, or delete the sentence.
103
+
104
+ ### Wrong reader
105
+
106
+ 22. **Telling the reader what they already know.** A reviewer already has the ticket and the diff. Open with
107
+ the decision and include only the argument that could change their mind about it.
108
+
109
+ ## Before and after
110
+
111
+ Before:
112
+
113
+ > This PR doesn't just fix the retry loop — it fundamentally transforms how we handle 503 responses,
114
+ > ensuring a robust, seamless experience. Retries now stop at the configured limit.
115
+
116
+ After:
117
+
118
+ > Retries on a 503 response now stop at the configured limit instead of looping.
119
+
120
+ Before:
121
+
122
+ > **Performance:** Performance has been improved. **Reliability:** Reliability has been enhanced.
123
+
124
+ After: cut both lines. Neither says what changed; name the concrete changes from the diff instead.
125
+
126
+ ## When not to act
127
+
128
+ Don't rewrite a flagged phrase when it sits in a quotation, a name or title, or a passage about the phrase
129
+ itself. A single tell is weak evidence; act on clusters. Keep what carries a writer's voice — an unusual
130
+ specific detail, mixed feelings, a genuine aside.
131
+
132
+ ## Self-check
133
+
134
+ - [ ] Every fact, number, and name from the source survives; nothing new was added.
135
+ - [ ] The contract's required structure and literal values are untouched.
136
+ - [ ] No staged contrast, restating closer, or run-up remains.
137
+ - [ ] Code, commands, and paths are unchanged.
@@ -17,6 +17,8 @@ worth building — through structured divergent and convergent thinking, not a t
17
17
  - **Ideate** — the primary home: turning a raw prompt or hunch into evaluated, distinct directions.
18
18
  - **Refine** — when the input requirement is really an unshaped idea: run a compressed version of the phases below before writing acceptance criteria.
19
19
 
20
+ **Not for:** a direction that is already chosen and now needs sharp requirements — that is ralphctl-spec-driven-development when installed.
21
+
20
22
  ## Philosophy
21
23
 
22
24
  - Simplicity is the ultimate sophistication. Push toward the simplest version that still solves the real problem.
@@ -8,7 +8,8 @@ description: Cross-phase skill — treat AI output as a controlled feedback loop
8
8
  > Concept
9
9
  >
10
10
  > from [SPDD (Zhang & Xia, martinfowler.com) — "Iterative Review"](https://martinfowler.com/articles/structured-prompt-driven/iterative-review.html).
11
- > Adapted for ralphctl's three phases.
11
+ > Adapted for ralphctl's three phases. Risk-first slicing draws on
12
+ > [addyosmani/agent-skills — "Incremental Implementation"](https://github.com/addyosmani/agent-skills) (MIT).
12
13
 
13
14
  One-shot generation looks fast and is slow. The cheap review you skipped at iteration N becomes the expensive
14
15
  unwind at iteration N+5, when a regression that lived undetected through five steps surfaces only at the
@@ -32,11 +33,16 @@ deployed form — but the same posture also belongs **inside** each phase's work
32
33
 
33
34
  1. **Run the cheapest check first, often.** Lint, typecheck, narrow test runs — not the full suite — after
34
35
  each meaningful change. The point is to catch the regression at the seam, not to certify completion.
35
- 2. **Re-read your own output once before submitting.** Whether it is criteria, tasks, or a diff, the second
36
+ 2. **Slice risk-first, and stay buildable between slices.** When the work has several parts, take the
37
+ least certain one first — the unproven integration, the unfamiliar API — so a dead end surfaces before
38
+ anything is built on it; a plan orders its tasks the same way. When your session can run commands,
39
+ confirm after each slice that the project still builds and its existing checks still pass, so the next
40
+ slice never starts on a broken tree.
41
+ 3. **Re-read your own output once before submitting.** Whether it is criteria, tasks, or a diff, the second
36
42
  read catches what the first one missed. Cheap.
37
- 3. **Treat the check gate as a loop, not a finish line.** A failing gate is feedback, not a verdict. Apply
43
+ 4. **Treat the check gate as a loop, not a finish line.** A failing gate is feedback, not a verdict. Apply
38
44
  the fix and re-run; do not signal completion against a red gate.
39
- 4. **When a fix attempt repeats the same failure, escalate rather than retry.** Two iterations of the same
45
+ 5. **When a fix attempt repeats the same failure, escalate rather than retry.** Two iterations of the same
40
46
  error is a plateau — the next fix is a guess. Surface the blocker rather than burning the budget on a
41
47
  third attempt: write a `note` signal in `signals.json` when the prompt's output-contract section lists
42
48
  it as an accepted kind; when it does not, use whichever blocked or narrative signal the contract does
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: ralphctl-observability-and-instrumentation
3
+ description: Instrument code so its production behaviour can be diagnosed from the outside — start from the questions an operator will ask, then emit structured events with stable names, a correlation id, and an entry-point field, bounded-cardinality metrics with latency percentiles, traces across async boundaries, and symptom-based alerts, never secrets or personal data. Use when adding I/O, retries, queues, background jobs, external integrations, or endpoints, or when a reported problem could not be diagnosed from existing telemetry.
4
+ license: MIT
5
+ ---
6
+
7
+ # Observability and Instrumentation
8
+
9
+ > Adapted from [addyosmani/agent-skills — "Observability and Instrumentation"](https://github.com/addyosmani/agent-skills)
10
+ > (MIT). Adapted for ralphctl's harness contract.
11
+
12
+ Code you cannot observe is code you cannot operate. Instrumentation is written with the feature, the way
13
+ tests are — when it ships without telemetry, the first reported bug becomes archaeology instead of a
14
+ query.
15
+
16
+ **Not for:** diagnosing a failure happening now (ralphctl-debugging-and-error-recovery when installed),
17
+ or optimising measured slowness (ralphctl-performance-optimization when installed).
18
+
19
+ ## When this applies
20
+
21
+ - **Plan** — for tasks that add I/O, retries, queues, jobs, or integrations, put the telemetry in the
22
+ task's steps and add a verification criterion that the failure path is observable. Name the operator
23
+ questions it must answer.
24
+ - **Execute** — instrument as you build, with the logging, metrics, and tracing libraries the project
25
+ already uses. Adding a new telemetry stack is a decision for the task to make, not a side effect.
26
+
27
+ ## 1. Define "working" first
28
+
29
+ Telemetry without a question is noise. Before instrumenting, write down two to four questions an operator
30
+ will ask about this feature — what fraction succeeds first time, why permanent failures fail, whether a
31
+ dependency is slower than usual. Every signal you add must help answer one of them.
32
+
33
+ ## 2. Pick the signal per question
34
+
35
+ | Signal | Answers | Cost |
36
+ | -------------- | ---------------------------------------- | ----------------------------- |
37
+ | Structured log | What happened in this specific case? | Per event; grows with traffic |
38
+ | Metric | How often, how fast, in aggregate? | Fixed per series; cheap |
39
+ | Trace | Where did the time go across components? | Per request; usually sampled |
40
+
41
+ Metrics tell you _that_ something is wrong, traces tell you _where_, logs tell you _why_.
42
+
43
+ ## 3. Structured logging
44
+
45
+ - **Events, not prose.** A stable event name plus machine-readable fields — never a sentence built by
46
+ string interpolation that nobody can query.
47
+ - **Levels used consistently** — error: an invariant broke and someone may need to act; warn: degraded
48
+ but handled (a retry succeeded, a fallback ran); info: a significant business event; debug: diagnostic
49
+ detail, off in production by default.
50
+ - **A correlation id on everything.** Accept or create one at the system boundary and attach it to every
51
+ log line, span, and outbound call, so one request can be reconstructed from interleaved output.
52
+ - **Name the entry point** when several entry points (a scheduler, a replay endpoint, a manual run) feed
53
+ one log. Set it where the run starts and propagate it with the correlation id across the same
54
+ boundaries — queue metadata, headers — rather than re-deriving it downstream.
55
+ - **Never log secrets, tokens, passwords, or full personal data.** Log an allowlist of fields, never a
56
+ whole request body.
57
+
58
+ ## 4. Metrics
59
+
60
+ Instrument rate, errors, and duration for every request-driven endpoint and every external dependency;
61
+ utilisation, saturation, and errors for resources such as pools and queues. Labels come from small fixed
62
+ sets (route template, status class, dependency name) — never user ids, raw URLs, or message text, which
63
+ explode the number of series and belong in logs and traces. Record latency as a histogram and read
64
+ percentiles; an average hides the slowest users.
65
+
66
+ ## 5. Tracing
67
+
68
+ Prefer a vendor-neutral standard such as OpenTelemetry when choosing, and the project's existing setup
69
+ when there is one. Use auto-instrumentation where the stack offers it; add manual spans only around
70
+ meaningful units of work, with the attributes an operator will filter by. Propagate context across every
71
+ async boundary or the trace dies at the gap.
72
+
73
+ ## 6. Alerting
74
+
75
+ Alert on symptoms users feel (error rate, latency, queue age), not causes (CPU, one restart). Every alert
76
+ is actionable, has a threshold and duration justified by an objective or by history, and uses one of two
77
+ severities: act now, or act this week. When the project keeps runbooks, link each new alert to one; do
78
+ not create a runbook location the task did not ask for.
79
+
80
+ ## 7. Verify the telemetry itself
81
+
82
+ Instrumentation is code and can be wrong. Exercise the failure path in a test and assert the emitted
83
+ event and its fields — the project's logger or metrics library usually offers a capture or in-memory
84
+ sink. Checks that need a live environment (a dashboard, a tracing UI, firing an alert) cannot happen in
85
+ this session: list them as unverified in a `note` signal when the prompt's output-contract section lists
86
+ it; otherwise fold them into the required signal's own fields.
87
+
88
+ ## Red flags
89
+
90
+ - A change adding retries, queues, or external calls with no new telemetry.
91
+ - Log lines built by interpolation instead of structured fields.
92
+ - No correlation id, or one shared log fed by several entry points with nothing naming which.
93
+ - Metric labels carrying user ids, raw URLs, or error text.
94
+ - Latency tracked only as an average.
95
+ - Secrets, tokens, or whole request bodies in log output.
96
+
97
+ ## Self-check
98
+
99
+ - [ ] The operator questions are named, and each signal maps to one.
100
+ - [ ] Log output is structured, with stable event names and a correlation id.
101
+ - [ ] No secret or unredacted personal data reaches any log line.
102
+ - [ ] New endpoints and dependencies have rate, error, and duration metrics with bounded labels.
103
+ - [ ] Latency is a histogram with queryable percentiles.
104
+ - [ ] The failure path's telemetry is asserted in a test, or listed as unverified.
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: ralphctl-performance-optimization
3
+ description: Measure-first performance discipline — take a baseline with the project's own tooling, find the actual bottleneck, change one thing, re-measure the same way, and keep the change only when it beats run-to-run noise with the tests still green. Use when a task states a performance target, reports slowness or a regression, or touches a hot path, query, cache, or connection pool; not for speculative optimisation without evidence of a problem.
4
+ license: MIT
5
+ ---
6
+
7
+ # Performance Optimization
8
+
9
+ > Adapted from [addyosmani/agent-skills — "Performance Optimization"](https://github.com/addyosmani/agent-skills)
10
+ > (MIT). Adapted for ralphctl's harness contract.
11
+
12
+ Performance work without measurement is guessing, and guessing adds complexity that costs more than the
13
+ speed it buys. Measure, find the real bottleneck, fix that one thing, measure again — and keep only what
14
+ the numbers justify.
15
+
16
+ **When not to use:** there is no evidence of a problem. Optimising on a hunch is how neutral complexity
17
+ lands.
18
+
19
+ ## When this applies
20
+
21
+ - **Execute** — when the task carries a performance target or a slowness report, or the change touches a
22
+ hot path. The generator measures with the project's tooling; when reviewing, a performance claim with no
23
+ before-and-after numbers behind it is a finding, and so is an "optimisation" that changed behaviour.
24
+
25
+ ## The workflow
26
+
27
+ ```
28
+ MEASURE → IDENTIFY → FIX ONE THING → RE-MEASURE (keep or undo) → GUARD
29
+ ```
30
+
31
+ ### 1. Measure
32
+
33
+ Use what the repository already has — a benchmark target, a profiler, a timing harness, a query-plan
34
+ command, a load script — found in its manifest, scripts, or CI configuration. Fix the budget before you
35
+ start: the same command, the same input, the same conditions (warm or cold cache, sample count). Record
36
+ the baseline numbers.
37
+
38
+ ### 2. Identify
39
+
40
+ Let the symptom pick what to measure first:
41
+
42
+ - **Startup or first load is slow** — payload or bundle size, blocking work at start, slow first
43
+ response.
44
+ - **Interaction feels sluggish** — long synchronous work on the main thread or event loop, redundant
45
+ re-rendering or recomputation.
46
+ - **One operation is slow** — profile it; read the query plan of each query it runs.
47
+ - **Everything slows at once** — connection or thread pool exhaustion, memory pressure, CPU saturation.
48
+ - **Slowness is intermittent** — lock contention, garbage-collection pauses, a slow external dependency.
49
+ - **Memory keeps growing** — leaked references, unbounded caches or lists, retained payloads.
50
+
51
+ ### 3. Fix one thing
52
+
53
+ Fix only the bottleneck step 2 identified. The usual suspects:
54
+
55
+ - **Query per row (N+1).** Fetch the relation in the same query or one batched query, not in the loop.
56
+ - **Unbounded fetching.** Every list read has a limit and a stable order.
57
+ - **A query that ignores its index.** "Add an index" is the guess; the query plan before and after is the
58
+ measurement. A stale row estimate wants refreshed statistics, not a new index. Index for the query's
59
+ shape — equality columns first, then the range or sort column. An index that did not change the plan
60
+ is an undo, and every index taxes every write.
61
+ - **Pool exhaustion.** Every operation slows together and time goes to waiting for a connection. A bigger
62
+ pool only moves the queue somewhere harder to see — find what holds connections, and size pools so the
63
+ total across all processes stays under the server's limit.
64
+ - **Missing or wrong caching.** Cache only what is expensive to produce and read far more often than it
65
+ changes. Every input that changes the result belongs in the key (tenant, locale, permissions, flags) —
66
+ a key that omits the viewer serves one user's data to another. Pick one invalidation strategy and state
67
+ the acceptable staleness. Protect hot keys against a stampede (serve stale while one request
68
+ recomputes, or coalesce concurrent misses). Never cache what must be fresh.
69
+ - **Repeated work in a hot loop.** Hoist the invariant; memoise only what the profile shows is costly.
70
+
71
+ ### 4. Re-measure: keep or undo
72
+
73
+ A fix is a hypothesis until re-measured — the same way as the baseline. Change one thing at a time so the
74
+ number is attributable, and repeat the measurement to compare the delta against run-to-run variance.
75
+
76
+ | Result against the baseline | Action |
77
+ | ----------------------------- | ---------------------------------------- |
78
+ | Beyond the noise, tests green | Keep it. |
79
+ | Within the noise | Undo it. Neutral is not a keep. |
80
+ | Worse | Undo it. |
81
+ | Faster, but a test went red | Undo it — a regression dressed as a win. |
82
+
83
+ Correctness gates the metric: an "optimisation" that wins by skipping work the product needed (a
84
+ validation, a fresh read, an awaited step) is a regression.
85
+
86
+ **Record every attempt, kept and undone alike.** An undone attempt leaves no trace in the diff, which is
87
+ how the same dead idea gets tried again. Record idea, baseline and result, verdict, and why in a `note`
88
+ signal when the prompt's output-contract section lists it; otherwise fold it into the required signal's
89
+ own fields.
90
+
91
+ ### 5. Guard
92
+
93
+ Protect the metric that justified the work. When the project already has a benchmark, performance test,
94
+ or budget, extend it to cover this path. Do not invent a new gate or pipeline step the task did not ask
95
+ for — name the missing guard in the same signal guidance as above instead.
96
+
97
+ ## Common rationalisations
98
+
99
+ | Rationalisation | Reality |
100
+ | ------------------------------------------ | ----------------------------------------------------------------------------------- |
101
+ | "This optimisation is obvious" | If you did not measure, you do not know. Re-measuring an obvious win is cheap. |
102
+ | "The query is slow, add an index" | Read the plan first. The index may exist and be unusable; every index taxes writes. |
103
+ | "Just cache it" | Caching a cheap call buys a staleness bug and nothing else. |
104
+ | "Raise the pool size" | It relocates the queue. Find what holds the connections. |
105
+ | "It didn't help much, but it doesn't hurt" | Neutral changes are maintained forever and bought nothing. Undo them. |
106
+ | "We already wrote it, may as well keep it" | Sunk cost. The measurement does not care how long the change took. |
107
+
108
+ ## Red flags
109
+
110
+ - An optimisation with no profiling data or baseline behind it.
111
+ - Several optimisations measured as one number.
112
+ - An index added without a query plan before and after.
113
+ - A cache key that omits an input the result depends on, or a cache with no stated staleness.
114
+ - A pool size raised in response to exhaustion without finding the holder.
115
+ - A "win" that needed a test changed, skipped, or deleted.
116
+
117
+ ## Self-check
118
+
119
+ - [ ] Before-and-after numbers exist, taken the same way.
120
+ - [ ] The improvement exceeds run-to-run variance.
121
+ - [ ] Changes that did not beat the baseline were undone.
122
+ - [ ] Every attempt is recorded, including the undone ones.
123
+ - [ ] The existing tests still pass — behaviour did not change.