@bompus/house-rules 0.0.0-stage → 0.11.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/CONTRIBUTING.md +54 -0
- package/LICENSE +21 -0
- package/README.md +347 -2
- package/THIRD_PARTY_NOTICES.md +188 -0
- package/compose.mjs +119 -0
- package/composition.mjs +353 -0
- package/config-view.mjs +194 -0
- package/config.mjs +320 -0
- package/docs/assets/banner-dark.png +0 -0
- package/docs/assets/banner-light.png +0 -0
- package/docs/assets/overview.png +0 -0
- package/docs/configuration.md +193 -0
- package/docs/npm-release.md +45 -0
- package/docs/skill-names.md +50 -0
- package/examples/person/house-rules.json +15 -0
- package/examples/person/rules/10-tooling.md +8 -0
- package/examples/person/rules/20-reporting.md +9 -0
- package/examples/project/AGENTS.md +18 -0
- package/package.json +40 -4
- package/rule-references.mjs +91 -0
- package/rules/core.md +431 -0
- package/rules/modifiers/coded-offers.md +40 -0
- package/rules/modifiers/effort-estimates.md +41 -0
- package/rules/modifiers/land-when-done.md +12 -0
- package/rules/modifiers/low-quota-handoff.md +19 -0
- package/rules/modifiers/multi-agent.md +34 -0
- package/rules/modifiers/no-attribution.md +10 -0
- package/rules/modifiers/plan-files.md +50 -0
- package/rules/modifiers/question-cards.md +48 -0
- package/rules/modifiers/release-batching.md +13 -0
- package/rules/modifiers/scratch-on-disk.md +15 -0
- package/rules/modifiers/shared-host-load.md +48 -0
- package/rules/modifiers/solo-operator.md +13 -0
- package/rules/modifiers/squash-landing.md +22 -0
- package/rules/modifiers/swarmail.md +12 -0
- package/rules/references/github-actions.md +45 -0
- package/rules/references/landing.md +39 -0
- package/rules/references/multi-agent.md +47 -0
- package/rules/references/release-batching.md +43 -0
- package/rules/references/squash-landing.md +44 -0
- package/setup.mjs +375 -0
- package/skills/hr-agent-guidance-audit/LICENSE +21 -0
- package/skills/hr-agent-guidance-audit/SKILL.md +86 -0
- package/skills/hr-agent-guidance-audit/agents/openai.yaml +2 -0
- package/skills/hr-agent-guidance-audit/references/records-and-lessons.md +60 -0
- package/skills/hr-agent-guidance-refresh/LICENSE +21 -0
- package/skills/hr-agent-guidance-refresh/SKILL.md +68 -0
- package/skills/hr-agent-guidance-refresh/agents/openai.yaml +2 -0
- package/skills/hr-agent-guidance-refresh/references/verification.md +47 -0
- package/skills/hr-api-exposure-check/SKILL.md +159 -0
- package/skills/hr-api-exposure-check/agents/openai.yaml +3 -0
- package/skills/hr-audit-choices/SKILL.md +67 -0
- package/skills/hr-audit-choices/agents/openai.yaml +2 -0
- package/skills/hr-benchmarking/NOTICE.md +36 -0
- package/skills/hr-benchmarking/SKILL.md +316 -0
- package/skills/hr-benchmarking/agents/openai.yaml +2 -0
- package/skills/hr-benchmarking/references/javascript.md +17 -0
- package/skills/hr-benchmarking/references/priority-findings-20261006.md +115 -0
- package/skills/hr-benchmarking/references/tools.md +160 -0
- package/skills/hr-benchmarking/scripts/process-attribution.ps1 +20 -0
- package/skills/hr-benchmarking/scripts/process-attribution.py +107 -0
- package/skills/hr-better-accessibility/LICENSE +22 -0
- package/skills/hr-better-accessibility/NOTICE.md +46 -0
- package/skills/hr-better-accessibility/SKILL.md +119 -0
- package/skills/hr-better-accessibility/agents/openai.yaml +3 -0
- package/skills/hr-better-accessibility/focus-and-keyboard.md +130 -0
- package/skills/hr-better-accessibility/forms.md +82 -0
- package/skills/hr-better-accessibility/hit-areas.md +98 -0
- package/skills/hr-better-accessibility/motion-and-zoom.md +81 -0
- package/skills/hr-better-accessibility/screen-readers.md +101 -0
- package/skills/hr-better-accessibility/semantics-and-aria.md +84 -0
- package/skills/hr-better-colors/LICENSE +21 -0
- package/skills/hr-better-colors/NOTICE.md +37 -0
- package/skills/hr-better-colors/SKILL.md +114 -0
- package/skills/hr-better-colors/agents/openai.yaml +3 -0
- package/skills/hr-better-colors/color-formats.md +90 -0
- package/skills/hr-better-colors/color-usage.md +140 -0
- package/skills/hr-better-colors/contrast.md +80 -0
- package/skills/hr-better-colors/palette-generation.md +104 -0
- package/skills/hr-better-colors/palette-structure.md +76 -0
- package/skills/hr-better-colors/token-naming.md +97 -0
- package/skills/hr-better-layout/LICENSE +22 -0
- package/skills/hr-better-layout/NOTICE.md +48 -0
- package/skills/hr-better-layout/SKILL.md +92 -0
- package/skills/hr-better-layout/agents/openai.yaml +3 -0
- package/skills/hr-better-layout/grouping-and-alignment.md +144 -0
- package/skills/hr-better-layout/spacing-and-adaptivity.md +215 -0
- package/skills/hr-better-typography/LICENSE +22 -0
- package/skills/hr-better-typography/NOTICE.md +46 -0
- package/skills/hr-better-typography/SKILL.md +172 -0
- package/skills/hr-better-typography/agents/openai.yaml +3 -0
- package/skills/hr-better-typography/choosing-fonts.md +69 -0
- package/skills/hr-better-typography/css-cheat-sheet.md +65 -0
- package/skills/hr-better-typography/details-and-accessibility.md +119 -0
- package/skills/hr-better-typography/spacing-and-sizing.md +131 -0
- package/skills/hr-better-typography/variable-fonts-and-opentype.md +105 -0
- package/skills/hr-better-typography/wrapping-and-punctuation.md +57 -0
- package/skills/hr-better-writing/LICENSE +22 -0
- package/skills/hr-better-writing/NOTICE.md +46 -0
- package/skills/hr-better-writing/SKILL.md +122 -0
- package/skills/hr-better-writing/agents/openai.yaml +3 -0
- package/skills/hr-change-impact/SKILL.md +113 -0
- package/skills/hr-change-impact/agents/openai.yaml +5 -0
- package/skills/hr-code-review/LICENSE +21 -0
- package/skills/hr-code-review/NOTICE.md +26 -0
- package/skills/hr-code-review/SKILL.md +147 -0
- package/skills/hr-code-review/agents/openai.yaml +3 -0
- package/skills/hr-code-review/references/evidence.md +57 -0
- package/skills/hr-design-exploration/SKILL.md +82 -0
- package/skills/hr-design-exploration/agents/openai.yaml +4 -0
- package/skills/hr-diagnosing-bugs/NOTICE.md +45 -0
- package/skills/hr-diagnosing-bugs/SKILL.md +108 -0
- package/skills/hr-diagnosing-bugs/agents/openai.yaml +3 -0
- package/skills/hr-diagnosing-bugs/references/reporting.md +72 -0
- package/skills/hr-explain-code/NOTICE.md +37 -0
- package/skills/hr-explain-code/SKILL.md +110 -0
- package/skills/hr-explain-code/agents/openai.yaml +5 -0
- package/skills/hr-explain-code/references/helper-brief.md +39 -0
- package/skills/hr-extract-shared-steps/SKILL.md +134 -0
- package/skills/hr-extract-shared-steps/agents/openai.yaml +3 -0
- package/skills/hr-handoff/SKILL.md +91 -0
- package/skills/hr-handoff/agents/openai.yaml +5 -0
- package/skills/hr-handoff/assets/ledger.example.json +10 -0
- package/skills/hr-handoff/assets/receipt.example.json +76 -0
- package/skills/hr-handoff/assets/source.example.json +20 -0
- package/skills/hr-handoff/references/reconciliation.md +105 -0
- package/skills/hr-handoff/scripts/check-reconciliation.mjs +282 -0
- package/skills/hr-house-rules-setup/SKILL.md +100 -0
- package/skills/hr-house-rules-setup/agents/openai.yaml +5 -0
- package/skills/hr-issue-tracker-setup/SKILL.md +49 -0
- package/skills/hr-issue-tracker-setup/agents/openai.yaml +5 -0
- package/skills/hr-lean-plan/SKILL.md +142 -0
- package/skills/hr-lean-plan/agents/openai.yaml +5 -0
- package/skills/hr-maintainability-review/SKILL.md +176 -0
- package/skills/hr-maintainability-review/agents/openai.yaml +5 -0
- package/skills/hr-manual-qa/NOTICE.md +36 -0
- package/skills/hr-manual-qa/SKILL.md +37 -0
- package/skills/hr-manual-qa/agents/openai.yaml +3 -0
- package/skills/hr-navigation-retro/LICENSE +21 -0
- package/skills/hr-navigation-retro/NOTICE.md +5 -0
- package/skills/hr-navigation-retro/SKILL.md +86 -0
- package/skills/hr-navigation-retro/agents/openai.yaml +4 -0
- package/skills/hr-navigation-retro/references/inputs.md +67 -0
- package/skills/hr-navigation-retro/scripts/retro.py +552 -0
- package/skills/hr-navigation-retro/scripts/transcripts.py +205 -0
- package/skills/hr-ordering-tests/SKILL.md +51 -0
- package/skills/hr-ordering-tests/agents/openai.yaml +2 -0
- package/skills/hr-plain-prose/SKILL.md +261 -0
- package/skills/hr-plain-prose/agents/openai.yaml +3 -0
- package/skills/hr-plain-prose/scripts/check.mjs +331 -0
- package/skills/hr-pr-followup/LICENSE +21 -0
- package/skills/hr-pr-followup/NOTICE.md +9 -0
- package/skills/hr-pr-followup/SKILL.md +71 -0
- package/skills/hr-pr-followup/agents/openai.yaml +2 -0
- package/skills/hr-pr-followup/references/review-helpers.md +90 -0
- package/skills/hr-pr-followup/scripts/check-pr-review.ts +510 -0
- package/skills/hr-pr-followup/scripts/resolve-pr-thread.ts +219 -0
- package/skills/hr-progress-report/SKILL.md +49 -0
- package/skills/hr-progress-report/agents/openai.yaml +5 -0
- package/skills/hr-read-reddit/SKILL.md +44 -0
- package/skills/hr-read-reddit/agents/openai.yaml +2 -0
- package/skills/hr-read-reddit/scripts/reddit.ts +252 -0
- package/skills/hr-read-x-links/SKILL.md +42 -0
- package/skills/hr-read-x-links/agents/openai.yaml +2 -0
- package/skills/hr-read-x-links/scripts/x-post.ts +264 -0
- package/skills/hr-split-to-prs/LICENSE +21 -0
- package/skills/hr-split-to-prs/NOTICE.md +9 -0
- package/skills/hr-split-to-prs/SKILL.md +61 -0
- package/skills/hr-split-to-prs/agents/openai.yaml +2 -0
- package/skills/hr-stock-ui-audit/SKILL.md +132 -0
- package/skills/hr-stock-ui-audit/agents/openai.yaml +3 -0
- package/skills/hr-stock-ui-audit/scripts/scan.mjs +619 -0
- package/skills/hr-tdd/LICENSE +21 -0
- package/skills/hr-tdd/NOTICE.md +10 -0
- package/skills/hr-tdd/SKILL.md +40 -0
- package/skills/hr-tdd/agents/openai.yaml +3 -0
- package/skills/hr-tdd/mocking.md +39 -0
- package/skills/hr-tdd/tests.md +77 -0
- package/skills/hr-test-audit/SKILL.md +146 -0
- package/skills/hr-test-audit/agents/openai.yaml +3 -0
- package/skills/hr-test-audit/scripts/floor-guard.ts +137 -0
- package/skills/hr-what-next/SKILL.md +61 -0
- package/skills/hr-what-next/agents/openai.yaml +4 -0
- package/skills/hr-what-next/references/reporting.md +68 -0
- package/skills/hr-writing-for-agents/NOTICE.md +46 -0
- package/skills/hr-writing-for-agents/SKILL-MECHANICS.md +83 -0
- package/skills/hr-writing-for-agents/SKILL.md +108 -0
- package/skills/hr-writing-for-agents/agents/openai.yaml +3 -0
- package/skills/hr-writing-pr/NOTICE.md +48 -0
- package/skills/hr-writing-pr/SKILL.md +104 -0
- package/skills/hr-writing-pr/agents/openai.yaml +2 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hr-explain-code
|
|
3
|
+
description: "Explain how existing code works by tracing it from trigger to effect, read-only, so the reader can change it with confidence. Use when the user asks how a part of the codebase works, or wants a walkthrough or trace of a flow. Not for designing new code or critiquing existing code."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Explain code
|
|
8
|
+
|
|
9
|
+
The goal is a reader who can open the right files and predict what the code
|
|
10
|
+
will do before they touch it. This skill reads and reports. It edits nothing,
|
|
11
|
+
runs nothing that changes state and offers no verdicts on quality.
|
|
12
|
+
|
|
13
|
+
## Pin down the question
|
|
14
|
+
|
|
15
|
+
Restate the question in one or two lines before reading far: which behavior,
|
|
16
|
+
which entry point, and where you will stop. "How does login work?" might mean
|
|
17
|
+
the form submit, the token exchange, session storage or all three. Pick the
|
|
18
|
+
reading that best fits what the user said, say which one you picked, and start.
|
|
19
|
+
Do not wait for confirmation; the user can redirect you.
|
|
20
|
+
|
|
21
|
+
If the question names something that does not exist in the code, say so early
|
|
22
|
+
and offer the nearest real thing.
|
|
23
|
+
|
|
24
|
+
## Trace the behavior
|
|
25
|
+
|
|
26
|
+
Start where the behavior starts: a route, a command, an event handler, a
|
|
27
|
+
scheduled job, a public function. Follow calls forward until you reach the
|
|
28
|
+
effects the question cares about, such as a write, a response, a message sent
|
|
29
|
+
or a value returned.
|
|
30
|
+
|
|
31
|
+
- Use the project's code search or code index when it has one. It follows
|
|
32
|
+
calls and dispatch that plain text search misses.
|
|
33
|
+
- Read the code that runs. A function name, a config key or a package
|
|
34
|
+
description says what someone intended, not what happens. Confirm by
|
|
35
|
+
reading the body, the call site and the value actually passed.
|
|
36
|
+
- Follow indirection to its target: dependency injection, registries, event
|
|
37
|
+
buses, plugin loading, dynamic imports, overrides. Name the mechanism when
|
|
38
|
+
it is the reason the path is hard to see.
|
|
39
|
+
- Separate the normal path from code that exists but is not wired in: dead
|
|
40
|
+
branches, disabled flags, handlers nobody registers, fallbacks that only
|
|
41
|
+
fire on a specific error. An exported or configured function not called on
|
|
42
|
+
the normal path is an optional capability, not a step in that flow.
|
|
43
|
+
- Distinguish a configured provider, an injected adapter, a local stub and a
|
|
44
|
+
durable service. Name only the runtime role the wiring and code support.
|
|
45
|
+
- For a state change, trace to the line that performs the write and the
|
|
46
|
+
conditions that permit it. Finding a caller alone does not prove a write.
|
|
47
|
+
- Check configuration and environment that change the path, and say which
|
|
48
|
+
values you assumed.
|
|
49
|
+
- When you cannot close a gap (generated code, a closed dependency, runtime
|
|
50
|
+
data you cannot see), write the open question right beside the claim it
|
|
51
|
+
weakens. Do not collect unknowns in a footnote far from what they affect.
|
|
52
|
+
|
|
53
|
+
The trace is done when every step from trigger to effect is either read in
|
|
54
|
+
the code or marked unverified at that step.
|
|
55
|
+
|
|
56
|
+
## Split a large area
|
|
57
|
+
|
|
58
|
+
When the area is too wide for one careful pass and the host can run helper
|
|
59
|
+
agents, divide it into slices that do not overlap, for example one per
|
|
60
|
+
service, layer or entry point. Give each helper a single slice, read-only
|
|
61
|
+
access and the brief in [`references/helper-brief.md`](references/helper-brief.md).
|
|
62
|
+
Run them in parallel.
|
|
63
|
+
|
|
64
|
+
Merge the results yourself. Where two slices meet, check that one helper's
|
|
65
|
+
outgoing call matches the other's entry point. Re-read the code for any claim
|
|
66
|
+
that surprises you or that the explanation depends on; a helper's summary is
|
|
67
|
+
a lead, not proof.
|
|
68
|
+
|
|
69
|
+
## Match depth to the question
|
|
70
|
+
|
|
71
|
+
A narrow question gets a short answer. "Where is the retry count set?" needs
|
|
72
|
+
a file reference and a sentence, not a tour. A request for a walkthrough of a
|
|
73
|
+
subsystem gets the full shape below.
|
|
74
|
+
|
|
75
|
+
- Cite files and functions as `path/to/file.ext:function` or with line
|
|
76
|
+
numbers, so the reader can open each one.
|
|
77
|
+
- Quote code only when the exact line carries the point: an off-by-one
|
|
78
|
+
boundary, an unusual default, a condition that decides the branch.
|
|
79
|
+
- Choose the smallest view that explains the behavior clearly. Use pseudocode
|
|
80
|
+
for decisions, a call tree for execution order, or a component/file tree for
|
|
81
|
+
ownership. Use a diagram for interactions or state transitions when it is
|
|
82
|
+
clearer than prose. Keep the conditions, side effects and unverified links
|
|
83
|
+
that affect the answer, with source references beside them.
|
|
84
|
+
|
|
85
|
+
## Shape the answer
|
|
86
|
+
|
|
87
|
+
Cover these in whatever order and form suits the question. Skip a part only
|
|
88
|
+
when it has nothing to say.
|
|
89
|
+
|
|
90
|
+
1. **Purpose.** What the code is for and who or what triggers it.
|
|
91
|
+
2. **Terms.** The few names, types or ideas the reader must know to follow
|
|
92
|
+
the rest. Three to five is usually enough.
|
|
93
|
+
3. **The flow.** The path from trigger to effect, using prose or the selected
|
|
94
|
+
view, with a source reference for each step. Explain any assumption or
|
|
95
|
+
omitted branch that changes the reader's understanding.
|
|
96
|
+
4. **Where to start reading.** The two or three files that repay opening
|
|
97
|
+
first, and in what order.
|
|
98
|
+
5. **Surprises.** Behavior a careful reader would not expect: side effects,
|
|
99
|
+
ordering dependencies, silent fallbacks, caching, code that looks live but
|
|
100
|
+
is not, and history that explains why code looks odd.
|
|
101
|
+
6. **Unverified.** What you could not confirm and what would confirm it,
|
|
102
|
+
if any of it is not already noted next to its claim.
|
|
103
|
+
|
|
104
|
+
## Stay descriptive
|
|
105
|
+
|
|
106
|
+
Describe what the code does, not whether it should. If you notice a likely
|
|
107
|
+
bug, mention it once as a fact with its location and move on. For a critique
|
|
108
|
+
of the design, point to `hr-maintainability-review`. For what a planned change
|
|
109
|
+
would affect, point to `hr-change-impact`. For a failure being chased, point to
|
|
110
|
+
`hr-diagnosing-bugs`.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Helper brief for one slice
|
|
2
|
+
|
|
3
|
+
Fill in the bracketed parts and send this to each helper agent.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
You are reading code to help answer: [the user's question, as restated].
|
|
7
|
+
|
|
8
|
+
Your slice: [service, directory, entry point or layer]. Stay inside it.
|
|
9
|
+
Where the code calls out of your slice, note the call and stop there.
|
|
10
|
+
|
|
11
|
+
Read only. Do not edit files, run migrations, start services or change
|
|
12
|
+
any state.
|
|
13
|
+
|
|
14
|
+
Trace behavior by reading code bodies and call sites. Do not infer what
|
|
15
|
+
something does from its name, a config key or a package description.
|
|
16
|
+
Use the project's code search or index if it has one.
|
|
17
|
+
|
|
18
|
+
Distinguish a configured provider, an injected adapter, a local stub and a
|
|
19
|
+
durable service. Name only the runtime role the wiring and code support.
|
|
20
|
+
An exported or configured function not called on the normal path is an
|
|
21
|
+
optional capability, not a step in that flow. For a state change, trace to
|
|
22
|
+
the line that performs the write and the conditions that permit it.
|
|
23
|
+
Finding a caller alone does not prove a write.
|
|
24
|
+
|
|
25
|
+
Return:
|
|
26
|
+
1. Entry points into your slice that matter to the question, with file
|
|
27
|
+
and function.
|
|
28
|
+
2. The path through your slice, step by step, each step with a file and
|
|
29
|
+
function or line reference.
|
|
30
|
+
3. Calls leaving your slice: what is called, with what, and where.
|
|
31
|
+
4. Code that exists but is not on the normal path (disabled, unregistered,
|
|
32
|
+
error-only), marked as such.
|
|
33
|
+
5. Anything surprising.
|
|
34
|
+
6. Gaps you could not close, each next to the step it affects, and what
|
|
35
|
+
would close it.
|
|
36
|
+
7. Every file you read.
|
|
37
|
+
|
|
38
|
+
Facts only, with references. No suggestions for changes.
|
|
39
|
+
```
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hr-extract-shared-steps
|
|
3
|
+
description: Pull operational steps that several workflows repeat into shared functions with explicit inputs and results, leaving each workflow's own decisions with its caller. Use when the same low-level operation (a provider call, a command run, a message sent, a resource provisioned) appears in two or more callers, when a fix landed in one copy but not the others, or when a new feature needs mechanics an existing flow already has. Not for single-caller logic, naming, or general interface design.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Extract shared steps
|
|
7
|
+
|
|
8
|
+
Several workflows often perform the same operation with slightly different
|
|
9
|
+
code around it: one checkout path and one renewal job both charge a card, two
|
|
10
|
+
handlers both run the same CLI command. The copies drift, and a fix applied to
|
|
11
|
+
one leaves the others broken. This skill moves the operation into one shared
|
|
12
|
+
function and leaves every decision about when, whether and what next with the
|
|
13
|
+
workflow that owns it.
|
|
14
|
+
|
|
15
|
+
## Confirm it applies
|
|
16
|
+
|
|
17
|
+
Extract when at least one of these is true, and you can point to the lines:
|
|
18
|
+
|
|
19
|
+
- Two or more callers perform the same low-level operation with the same
|
|
20
|
+
inputs, calls and error handling, give or take naming.
|
|
21
|
+
- A bug fix or provider change landed in one copy and the others still carry
|
|
22
|
+
the old behavior.
|
|
23
|
+
- A new feature is about to copy mechanics that an existing flow already has.
|
|
24
|
+
|
|
25
|
+
Stop and leave the code alone when the logic has one caller, when the copies
|
|
26
|
+
only look alike but encode different product rules, or when the real question
|
|
27
|
+
is naming or how a module's interface should look.
|
|
28
|
+
|
|
29
|
+
## Draw the line between policy and operation
|
|
30
|
+
|
|
31
|
+
Go through the repeated code line by line and sort each line with this test:
|
|
32
|
+
would a second caller ever want this line to behave differently? If yes, it is
|
|
33
|
+
policy and stays in the caller. If no, it is part of the operation.
|
|
34
|
+
|
|
35
|
+
Policy, which stays with each caller:
|
|
36
|
+
|
|
37
|
+
- who may trigger the action, and any permission or plan checks
|
|
38
|
+
- state transitions on the caller's own records (order paid, subscription past due)
|
|
39
|
+
- which failures reach the user, and the wording they see
|
|
40
|
+
- whether to retry, when, and how many times
|
|
41
|
+
- logging or metrics that name the workflow
|
|
42
|
+
|
|
43
|
+
Operation, which moves into the shared function:
|
|
44
|
+
|
|
45
|
+
- building the request, calling the provider or command, parsing the response
|
|
46
|
+
- mapping raw provider errors into a small, stable set of failure kinds
|
|
47
|
+
- anything that must be identical everywhere for correctness, such as an
|
|
48
|
+
idempotency key format or a required header
|
|
49
|
+
|
|
50
|
+
## Shape the shared function
|
|
51
|
+
|
|
52
|
+
- Take everything it needs as parameters: clients, identifiers, amounts,
|
|
53
|
+
timeouts. It does not reach for globals, request context or configuration
|
|
54
|
+
on its own.
|
|
55
|
+
- Do not read or write application state or the database inside it. The caller
|
|
56
|
+
loads what the operation needs and stores what comes back.
|
|
57
|
+
- Return a structured result that makes failure explicit: success with its
|
|
58
|
+
data, or a failure kind plus the raw detail. Never swallow an error or
|
|
59
|
+
return a bare `false` the caller cannot interpret.
|
|
60
|
+
- Offer several small operations a caller can combine rather than one entry
|
|
61
|
+
point with flags for each caller's variant. Two callers needing different
|
|
62
|
+
steps call different functions.
|
|
63
|
+
- Keep argument order, naming and result shape consistent across sibling
|
|
64
|
+
operations, so a reader who knows one knows the rest.
|
|
65
|
+
|
|
66
|
+
Extract only what is repeated today and not specific to one product flow. A
|
|
67
|
+
step only one caller needs stays in that caller, even if it sits next to the
|
|
68
|
+
shared part.
|
|
69
|
+
|
|
70
|
+
## Example
|
|
71
|
+
|
|
72
|
+
Checkout charges a card while the customer waits; the renewal job charges
|
|
73
|
+
the same card overnight. Both used to build the provider request inline.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
type ChargeResult =
|
|
77
|
+
| { ok: true; chargeId: string }
|
|
78
|
+
| { ok: false; kind: "declined" | "unavailable" | "invalid"; detail: string };
|
|
79
|
+
|
|
80
|
+
async function chargeCard(
|
|
81
|
+
client: PaymentClient,
|
|
82
|
+
input: {
|
|
83
|
+
customerRef: string;
|
|
84
|
+
amountCents: number;
|
|
85
|
+
currency: string;
|
|
86
|
+
idempotencyKey: string;
|
|
87
|
+
},
|
|
88
|
+
): Promise<ChargeResult> {
|
|
89
|
+
/* request, call, map provider errors to kind */
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Checkout: show declines to the customer, never retry.
|
|
93
|
+
const paid = await chargeCard(client, { ...order.charge, idempotencyKey: order.id });
|
|
94
|
+
if (!paid.ok) return showPaymentError(paid.kind);
|
|
95
|
+
await orders.markPaid(order.id, paid.chargeId);
|
|
96
|
+
|
|
97
|
+
// Renewal job: retry outages later, mark the subscription past due on decline.
|
|
98
|
+
const renewed = await chargeCard(client, { ...sub.charge, idempotencyKey: `${sub.id}:${period}` });
|
|
99
|
+
if (!renewed.ok && renewed.kind === "unavailable") return scheduleRetry(sub.id);
|
|
100
|
+
if (!renewed.ok) return subs.markPastDue(sub.id, renewed.detail);
|
|
101
|
+
await subs.recordPayment(sub.id, renewed.chargeId);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`chargeCard` knows nothing about orders, subscriptions or retries. Each caller
|
|
105
|
+
decides what a decline means for its own records.
|
|
106
|
+
|
|
107
|
+
## Migrate in steps
|
|
108
|
+
|
|
109
|
+
1. Write the shared function from the most complete copy, with tests for its
|
|
110
|
+
success path and each failure kind. Done when those tests pass.
|
|
111
|
+
2. Switch one caller to it. Done when that caller's tests, the type check and
|
|
112
|
+
the linter pass, and its observable behavior is unchanged.
|
|
113
|
+
3. Switch the remaining callers one at a time with the same checks. Where the
|
|
114
|
+
copies differed, decide whether the difference was policy (keep it in that
|
|
115
|
+
caller) or a bug (fix it, and say so in the change description).
|
|
116
|
+
4. Delete the old inline copies. Done when a search for the old request
|
|
117
|
+
building or provider call finds only the shared function.
|
|
118
|
+
5. Run the project's full required checks before landing.
|
|
119
|
+
|
|
120
|
+
## Check the result
|
|
121
|
+
|
|
122
|
+
Revisit the extraction when any of these appear, now or in later changes:
|
|
123
|
+
|
|
124
|
+
- The shared function grew a parameter or mode flag that exists for one
|
|
125
|
+
caller. Move that step back to the caller or split the function.
|
|
126
|
+
- It writes domain state, or reads it to decide what to do. That is policy
|
|
127
|
+
leaking in; return the data and let the caller act.
|
|
128
|
+
- It has a single caller left. Inline it back unless a second caller is
|
|
129
|
+
already planned in this change.
|
|
130
|
+
- Callers inspect raw provider errors again instead of the failure kind. The
|
|
131
|
+
result type is missing a case.
|
|
132
|
+
|
|
133
|
+
Report what was extracted, which callers moved, any behavior difference you
|
|
134
|
+
found between the copies and how you resolved it, and the checks you ran.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hr-handoff
|
|
3
|
+
description: Create a resumable handoff when the user requests one or the low-quota handoff rule triggers. Do not invoke merely because a conversation is long.
|
|
4
|
+
argument-hint: "What will the next session be used for?"
|
|
5
|
+
disable-model-invocation: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Write a handoff document summarising the current conversation so a fresh agent can continue the work. Save it outside disposable storage and task worktrees, as § Durable notes in the house rules requires.
|
|
9
|
+
|
|
10
|
+
Default to `handoffs/<project>/<session>.md` in your notes directory (§ Durable notes), expanding `~` and environment variables to an absolute path. Respect a user-selected persistent location. Create parent directories as needed, choose a unique session name, reuse the file for updates, verify its contents, and report the absolute path. Do not default to temporary directories or caches for resumable handoffs.
|
|
11
|
+
|
|
12
|
+
For a low-quota handoff (trigger defined by the `low-quota-handoff` modifier), do only what
|
|
13
|
+
is necessary to reach a safe boundary. Do not abandon time-critical duty mid-action. Create the essential
|
|
14
|
+
current state, Git ownership
|
|
15
|
+
and next action first so they survive an interrupted write; then fill in the
|
|
16
|
+
remaining context. Record the triggering bucket, reading source/time and reset
|
|
17
|
+
time when known, and unknown quota/reset information as unknown.
|
|
18
|
+
|
|
19
|
+
Verify the saved handoff, report its absolute path, and end the turn without
|
|
20
|
+
continuing substantive work, even if tasks were previously authorized; this is the stop
|
|
21
|
+
the house rules' § End of every reply allows for a rule you are following. Only an explicit
|
|
22
|
+
user instruction resumes work, limited to its requested scope; update this same
|
|
23
|
+
handoff and stop again afterward while quota remains low. Do not change
|
|
24
|
+
provider, model or effort without authorization.
|
|
25
|
+
|
|
26
|
+
For a handoff unrelated to quota, follow the user's requested continuation or
|
|
27
|
+
stop boundary.
|
|
28
|
+
|
|
29
|
+
Before a handoff unrelated to quota, check the docs this session relied on or
|
|
30
|
+
changed against the current code: repository guidance, READMEs and design docs
|
|
31
|
+
that name the files, commands or behavior the session touched. List each claim
|
|
32
|
+
the code contradicts, with the doc's file and line and the code evidence, and
|
|
33
|
+
propose the smallest fix for each. Edit docs only with the user's approval;
|
|
34
|
+
record unapproved contradictions as open items so the next session doesn't
|
|
35
|
+
trust them. Skip this check for a low-quota handoff.
|
|
36
|
+
|
|
37
|
+
Preserve, stated exactly and complete even at the cost of length: (1) problems that came up and how they were handled; (2) options raised, tried, or set aside, and why; (3) anything asked for, decided, ruled out, or established as a preference, constraint, or boundary; (4) exactly where things stand now, including any external action started without a recorded result; (5) anything still open, promised, or expected next; (6) details that are hard to reconstruct: names, numbers, dates, exact wording, paths, links. Keep what the user said close to their own words; condense your own reasoning to what it concluded or produced. Everything else stays concise.
|
|
38
|
+
|
|
39
|
+
Close the loop on remaining work: inventory every current and past item as done,
|
|
40
|
+
open, or deferred, each with its owner and next action, and state whether all
|
|
41
|
+
items are addressed. When the handoff spans several threads or scopes, include
|
|
42
|
+
an integrated plan. Preserve an already-selected next action; record unresolved
|
|
43
|
+
decisions and recommendations in priority order.
|
|
44
|
+
|
|
45
|
+
For a handoff unrelated to quota, follow
|
|
46
|
+
[reconciliation.md](references/reconciliation.md) to compare the current and
|
|
47
|
+
preceding source transcripts, linked ledgers and Git inventory with this
|
|
48
|
+
inventory. Save its receipt and run the offline checker. Report coverage gaps
|
|
49
|
+
and mechanical results separately from the reviewed claim that all items are
|
|
50
|
+
addressed. Include owned unlanded PRs, dependency PRs and own commits without a
|
|
51
|
+
PR; preserve their owners and landing authority.
|
|
52
|
+
|
|
53
|
+
At a low-quota stop, save essential state first and record partial coverage
|
|
54
|
+
when feasible. An unfinished receipt or failing check never delays that stop.
|
|
55
|
+
|
|
56
|
+
Ask what to work on next only when an unresolved decision needs the user's
|
|
57
|
+
input and the handoff's stop boundary permits it. Follow the house rules'
|
|
58
|
+
§ Offers and § Finishing work. When stopping for low quota, the saved handoff and recorded next action serve
|
|
59
|
+
as the offer; do not ask a new selection question.
|
|
60
|
+
|
|
61
|
+
A session resuming from a handoff re-reads the repository's guidance index,
|
|
62
|
+
meaning its `AGENTS.md` (or configured instruction root) and the rules and docs
|
|
63
|
+
it names. It also checks `git log` on those paths plus the house-rules checkout
|
|
64
|
+
for changes since the handoff was written; an installed or composed copy of
|
|
65
|
+
the rules can lag its source. Boot-injected rules are a snapshot, not proof of
|
|
66
|
+
current text.
|
|
67
|
+
|
|
68
|
+
Include a **Git** section when the handoff involves repo work:
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
## Git
|
|
72
|
+
|
|
73
|
+
- Checkout: <absolute path>; branch or detached HEAD: <verified value>
|
|
74
|
+
- Owns: `path/globs`
|
|
75
|
+
- Do not touch: `<paths other chats own>`
|
|
76
|
+
- Last commit: `<sha> <subject>`
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
If two chats run in parallel on this repo, owns must not overlap. Prefer one implementation chat at a time.
|
|
80
|
+
|
|
81
|
+
End your report with a ready-to-paste prompt for the resuming agent inside a
|
|
82
|
+
fenced code block, so the user can copy it into a fresh session verbatim. It
|
|
83
|
+
must name the handoff's absolute path, tell the resuming session to read the
|
|
84
|
+
handoff fully before acting (which itself directs the guidance re-read), and
|
|
85
|
+
state the recorded next action plus any provider or host constraint the user
|
|
86
|
+
gave. Keep it under ten lines; the handoff carries the detail, the prompt only
|
|
87
|
+
points at it.
|
|
88
|
+
|
|
89
|
+
Redact any sensitive information, such as API keys, passwords, or personally identifiable information.
|
|
90
|
+
|
|
91
|
+
If the user passed arguments, treat them as a description of what the next session will focus on and tailor the doc accordingly.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"owner": "session-example",
|
|
4
|
+
"coverage": "complete",
|
|
5
|
+
"sources": [
|
|
6
|
+
{
|
|
7
|
+
"id": "current",
|
|
8
|
+
"file": "source.example.json",
|
|
9
|
+
"snapshot": "Fictional session records through 2025-01-01T10:01:00Z",
|
|
10
|
+
"expectedRecords": 3,
|
|
11
|
+
"gaps": []
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "prior-ledger",
|
|
15
|
+
"file": "ledger.example.json",
|
|
16
|
+
"snapshot": "Fictional child ledger at 2025-01-01T09:00:00Z",
|
|
17
|
+
"expectedRecords": 1,
|
|
18
|
+
"gaps": []
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"accounting": [
|
|
22
|
+
{ "source": "current", "record": "request-1", "items": ["parser", "landing"] },
|
|
23
|
+
{ "source": "current", "record": "completion-1", "items": ["parser"] },
|
|
24
|
+
{ "source": "current", "record": "git-1", "items": ["landing"] },
|
|
25
|
+
{ "source": "prior-ledger", "record": "deferred-1", "items": ["evaluation"] }
|
|
26
|
+
],
|
|
27
|
+
"items": [
|
|
28
|
+
{
|
|
29
|
+
"id": "parser",
|
|
30
|
+
"owner": "session-example",
|
|
31
|
+
"state": "done",
|
|
32
|
+
"evidence": [{ "source": "current", "record": "completion-1" }],
|
|
33
|
+
"next": "Implementation complete; landing is tracked separately."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "landing",
|
|
37
|
+
"owner": "session-example",
|
|
38
|
+
"state": "open",
|
|
39
|
+
"evidence": [{ "source": "current", "record": "git-1" }],
|
|
40
|
+
"next": "Wait for the user's landing decision; dependency PR9 belongs to its owner."
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "evaluation",
|
|
44
|
+
"owner": "session-example",
|
|
45
|
+
"state": "deferred",
|
|
46
|
+
"evidence": [{ "source": "prior-ledger", "record": "deferred-1" }],
|
|
47
|
+
"next": "Resume only after explicit user selection."
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"git": {
|
|
51
|
+
"scope": "example/widget; no other repository work",
|
|
52
|
+
"checkedAt": "2025-01-01T10:01:00Z",
|
|
53
|
+
"evidence": [{ "source": "current", "record": "git-1" }],
|
|
54
|
+
"ownedPrs": [
|
|
55
|
+
{
|
|
56
|
+
"url": "https://github.com/example/widget/pull/8",
|
|
57
|
+
"owner": "session-example",
|
|
58
|
+
"state": "open",
|
|
59
|
+
"checkedAt": "2025-01-01T10:01:00Z",
|
|
60
|
+
"evidence": [{ "source": "current", "record": "git-1" }],
|
|
61
|
+
"next": "Wait for the user's landing decision."
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"dependencyPrs": [
|
|
65
|
+
{
|
|
66
|
+
"url": "https://github.com/example/widget/pull/9",
|
|
67
|
+
"owner": "session-other",
|
|
68
|
+
"state": "open",
|
|
69
|
+
"checkedAt": "2025-01-01T10:01:00Z",
|
|
70
|
+
"evidence": [{ "source": "current", "record": "git-1" }],
|
|
71
|
+
"next": "Await the owner's adoption receipt; no landing authority transferred."
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"commitsWithoutPr": []
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"records": [
|
|
3
|
+
{
|
|
4
|
+
"id": "request-1",
|
|
5
|
+
"text": "Implement the parser, then wait for my landing decision."
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"id": "completion-1",
|
|
9
|
+
"text": "Parser implementation and checks complete; PR8 remains unlanded.",
|
|
10
|
+
"at": "2025-01-01T10:00:00Z",
|
|
11
|
+
"outcome": { "item": "parser", "state": "done" }
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "git-1",
|
|
15
|
+
"text": "Checked example/widget: own PR8 open, dependency PR9 open, no commits without a PR.",
|
|
16
|
+
"at": "2025-01-01T10:01:00Z",
|
|
17
|
+
"outcome": { "item": "landing", "state": "open" }
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Reconcile a handoff against its sources
|
|
2
|
+
|
|
3
|
+
Keep a JSON receipt beside the human-readable handoff. It accounts for the
|
|
4
|
+
source records you reviewed and the candidates you extracted. It does not
|
|
5
|
+
replace reading their content or reviewing context-only classifications.
|
|
6
|
+
|
|
7
|
+
## Collect independent source snapshots
|
|
8
|
+
|
|
9
|
+
Review the current transcript and the preceding handoff's source transcript
|
|
10
|
+
when available. Include linked plans, child ledgers, schedules, pending
|
|
11
|
+
decisions and owned Git work. Use the host's existing export and session-search
|
|
12
|
+
tools. Preserve source IDs and text rather than exporting only the items you
|
|
13
|
+
already remembered.
|
|
14
|
+
|
|
15
|
+
Normalize each source into a JSON object with a `records` array. Each record
|
|
16
|
+
has a unique `id` and its original `text`. Record the original location and
|
|
17
|
+
snapshot or range in the receipt's `snapshot` field. Name records by stable
|
|
18
|
+
message IDs or ledger row IDs. Several records can map to the same item.
|
|
19
|
+
|
|
20
|
+
When a record establishes a disposition, add an `outcome` with `item` and
|
|
21
|
+
`state`, plus `at` as a UTC ISO timestamp. States are `done`, `open` and
|
|
22
|
+
`deferred`. Use the evidence's time, not the export time. A later request or
|
|
23
|
+
current contradictory evidence that reopens completed work also sets
|
|
24
|
+
`outcome.reopens` to `true`. These annotations are reviewed judgments.
|
|
25
|
+
|
|
26
|
+
Record each expected count from independent export metadata or ledger
|
|
27
|
+
inventory. Use `null` when the total is unknown. A count is for the declared
|
|
28
|
+
snapshot or range; it does not establish coverage outside that range.
|
|
29
|
+
Describe missing, omitted, truncated or unavailable content in `gaps`.
|
|
30
|
+
Keep sensitive snapshots local and redact secrets before normalization.
|
|
31
|
+
|
|
32
|
+
## Fill the receipt
|
|
33
|
+
|
|
34
|
+
Copy the fictional [receipt example](../assets/receipt.example.json) and its
|
|
35
|
+
[session snapshot](../assets/source.example.json) and
|
|
36
|
+
[child ledger](../assets/ledger.example.json) into persistent notes. Replace
|
|
37
|
+
their contents with this session's evidence. Source `file` paths resolve
|
|
38
|
+
relative to the receipt; the checker reads only explicitly named snapshots.
|
|
39
|
+
|
|
40
|
+
- `version` is `1`; `owner` names this session. `coverage` is `complete` or
|
|
41
|
+
`partial`. Claim complete only for the declared source ranges with known
|
|
42
|
+
counts and no known gaps.
|
|
43
|
+
- Each `sources` entry has `id`, `file`, `snapshot`, `expectedRecords` and
|
|
44
|
+
`gaps`. Include inaccessible sources and their limitations rather than
|
|
45
|
+
silently dropping them.
|
|
46
|
+
- Every source record gets one `accounting` row with `source` and `record`.
|
|
47
|
+
Add nonempty `items` containing extracted item IDs, or a `context` reason
|
|
48
|
+
explaining why the record creates no candidate. Review user requests and
|
|
49
|
+
assistant commitments and options before assigning context-only status.
|
|
50
|
+
- Each `items` entry has `id`, `owner`, `state`, `evidence` and `next`.
|
|
51
|
+
Evidence references use `{ "source": "source-id", "record": "record-id" }`.
|
|
52
|
+
Include the latest declared outcome. For deferred work, `next` gives its
|
|
53
|
+
trigger; for done work, give its result and any separately tracked follow-up.
|
|
54
|
+
- `git` records `scope`, `checkedAt` and `evidence`, plus explicit `ownedPrs`,
|
|
55
|
+
`dependencyPrs` and `commitsWithoutPr` arrays. Empty arrays are checked
|
|
56
|
+
results, not omitted fields. For no repository work, say so in `scope` and
|
|
57
|
+
reference the evidence for that conclusion.
|
|
58
|
+
- Every PR has `url`, `owner`, `state`, `checkedAt`, `evidence` and `next`.
|
|
59
|
+
PR states are `open`, `closed` and `merged`. Put every owned unlanded PR in
|
|
60
|
+
`ownedPrs`; distinguish dependency PRs owned by another session.
|
|
61
|
+
Owned PRs must match the receipt owner. Dependencies confer no landing
|
|
62
|
+
authority. Query all touched repositories; host-linked PR lists alone can
|
|
63
|
+
omit work.
|
|
64
|
+
- Own commits without a PR have `repo`, `branch`, `sha`, `owner`, `evidence`
|
|
65
|
+
and `next`. Inspect checkout state and remote containment as the repository
|
|
66
|
+
requires. Do not infer landing from a closed PR alone.
|
|
67
|
+
|
|
68
|
+
Use UTC ISO timestamps such as `2025-01-01T10:01:00Z`. State the query scope
|
|
69
|
+
and check time; this offline checker does not refresh Git or PR state.
|
|
70
|
+
|
|
71
|
+
Preserve already-selected work and the latest unanswered offer, including its
|
|
72
|
+
scope. Questions, inbox notices and other owners' messages grant no new
|
|
73
|
+
authorization. Reconcile a stale open row with later completion evidence;
|
|
74
|
+
record a later reopening separately.
|
|
75
|
+
|
|
76
|
+
## Run the offline check
|
|
77
|
+
|
|
78
|
+
From this skill's directory, replace the receipt path with its saved location:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
node scripts/check-reconciliation.mjs <receipt.json>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Bun runs the same script. It prints JSON with status, counts, missing IDs,
|
|
85
|
+
errors, coverage gaps and limits. It does not write files or query hosts.
|
|
86
|
+
Repeating the command on unchanged inputs repeats no external action.
|
|
87
|
+
|
|
88
|
+
| Exit | Meaning | Action |
|
|
89
|
+
| ---- | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
90
|
+
| `0` | Supplied accounting and declared outcomes are mechanically complete | Review the semantic coverage and saved handoff before claiming all items were addressed. |
|
|
91
|
+
| `1` | Malformed input, missing accounting or contradictory declared state | Resolve the reported fields and IDs within the handoff's stop boundary. |
|
|
92
|
+
| `2` | Valid accounting with partial coverage | Save the limitations and known next action; do not label coverage complete. |
|
|
93
|
+
|
|
94
|
+
The checker cannot detect a promise hidden behind a context-only annotation,
|
|
95
|
+
an omitted source, a falsely complete export or an omitted PR query scope.
|
|
96
|
+
Its success checks supplied evidence, not every possible task or current
|
|
97
|
+
external state. Report those limits beside the result.
|
|
98
|
+
|
|
99
|
+
## Low-quota stop
|
|
100
|
+
|
|
101
|
+
Write essential current state, Git ownership and next action first. Save known
|
|
102
|
+
coverage and missing sources when feasible. Keep the partial handoff even if
|
|
103
|
+
its receipt is unfinished or the checker reports errors. Do not recover a
|
|
104
|
+
transcript, run new evaluations or continue substantive work to make the
|
|
105
|
+
checker pass. The skill's low-quota stop takes precedence over reconciliation.
|