@agentsfleet/orly 0.5.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/.githooks/pre-commit +42 -0
- package/.githooks/pre-push +67 -0
- package/AGENTS.md +348 -0
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/SOUL.md +90 -0
- package/audits/agents-md.md +497 -0
- package/audits/agents-md.sh +353 -0
- package/audits/cross-tier-rates.sh +105 -0
- package/audits/data.sh +185 -0
- package/audits/deinit-pairs.sh +224 -0
- package/audits/design-tokens.sh +143 -0
- package/audits/doc-read.sh +183 -0
- package/audits/error-codes.sh +221 -0
- package/audits/fixtures/clean.diff +15 -0
- package/audits/fixtures/dirty.diff +16 -0
- package/audits/lifecycle-anchors.sh +22 -0
- package/audits/logging.sh +217 -0
- package/audits/msid-ui.sh +144 -0
- package/audits/parity-dispatch.sh +51 -0
- package/audits/rule-ledger-lib.sh +264 -0
- package/audits/rule-ledger.sh +225 -0
- package/audits/rule-paths.sh +108 -0
- package/audits/spec-template.sh +258 -0
- package/audits/sql-mod.sh +102 -0
- package/audits/ufs.sh +303 -0
- package/bin/orly +26 -0
- package/core/operating-model.md +256 -0
- package/dispatch/edit_rules.md +69 -0
- package/dispatch/lib.sh +213 -0
- package/dispatch/lifecycle.md +187 -0
- package/dispatch/name_architecture.md +93 -0
- package/dispatch/verify.md +111 -0
- package/dispatch/write_any.md +740 -0
- package/dispatch/write_any.sh +49 -0
- package/dispatch/write_auth.md +36 -0
- package/dispatch/write_changelog.md +64 -0
- package/dispatch/write_documentation.md +45 -0
- package/dispatch/write_go.md +24 -0
- package/dispatch/write_http.md +45 -0
- package/dispatch/write_mdx.md +7 -0
- package/dispatch/write_python.md +8 -0
- package/dispatch/write_rust.md +38 -0
- package/dispatch/write_shell.md +8 -0
- package/dispatch/write_spec.md +105 -0
- package/dispatch/write_sql.md +112 -0
- package/dispatch/write_sql.sh +36 -0
- package/dispatch/write_ts_adhere_bun.md +493 -0
- package/dispatch/write_ts_adhere_bun.sh +37 -0
- package/dispatch/write_zig.md +852 -0
- package/dispatch/write_zig.sh +40 -0
- package/docs/CHANGELOG_VOICE.md +18 -0
- package/docs/DISPATCH_ARCHITECTURE.md +664 -0
- package/docs/DISPATCH_REVIEW_DISPOSITION.md +65 -0
- package/docs/DOCUMENTATION_RULES.md +209 -0
- package/docs/EXECUTE_DOC_READS.md +29 -0
- package/docs/HARNESS_VERIFY_OUTPUT.md +40 -0
- package/docs/LIFECYCLE_PATTERNS.md +316 -0
- package/docs/LOGGING_STANDARD.md +397 -0
- package/docs/ORLY_ARCHITECTURE.md +129 -0
- package/docs/REST_API_DESIGN_GUIDELINES.md +783 -0
- package/docs/RULE_ENFORCEMENT.md +41 -0
- package/docs/SCHEMA_CONVENTIONS.md +93 -0
- package/docs/TEMPLATE.md +411 -0
- package/docs/VERIFY_TIERS.md +57 -0
- package/docs/greptile-learnings/README.md +51 -0
- package/docs/greptile-learnings/RULES.md +1045 -0
- package/fixtures/registry-invalid.json +1 -0
- package/fixtures/registry-valid.json +18 -0
- package/fixtures/unclosed-pack-block.md +8 -0
- package/package.json +63 -0
- package/packs/language/go/rules.md +24 -0
- package/packs/language/mdx/rules.md +7 -0
- package/packs/language/python/rules.md +8 -0
- package/packs/language/rust/rules.md +38 -0
- package/packs/language/shell/rules.md +8 -0
- package/registry.json +405 -0
- package/schemas/evidence.schema.json +43 -0
- package/schemas/profile.schema.json +12 -0
- package/schemas/registry.schema.json +12 -0
- package/skills/orly-babysit-prs/SKILL.md +326 -0
- package/skills/orly-spec-new/SKILL.md +157 -0
- package/skills/orly-write-integration-test/SKILL.md +470 -0
- package/skills/orly-write-unit-test/SKILL.md +520 -0
- package/src/cli.test.ts +70 -0
- package/src/cli.ts +287 -0
- package/src/config.test.ts +226 -0
- package/src/config.ts +288 -0
- package/src/criteria.test.ts +137 -0
- package/src/criteria.ts +166 -0
- package/src/criteria_spec.ts +127 -0
- package/src/criteria_support.ts +53 -0
- package/src/gates.test.ts +183 -0
- package/src/gates.ts +169 -0
- package/src/gates_spec.test.ts +98 -0
- package/src/gates_test_support.ts +194 -0
- package/src/git_env.ts +20 -0
- package/src/install.test.ts +514 -0
- package/src/install.ts +447 -0
- package/src/install_nested.test.ts +32 -0
- package/src/model.test.ts +31 -0
- package/src/model.ts +245 -0
- package/src/references.test.ts +47 -0
- package/src/references.ts +147 -0
- package/src/render.test.ts +60 -0
- package/src/render.ts +94 -0
- package/src/surfaces.test.ts +43 -0
- package/src/surfaces.ts +89 -0
- package/src/validation.test.ts +11 -0
- package/src/validation.ts +87 -0
- package/src/verify.test.ts +13 -0
- package/src/verify.ts +59 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orly-babysit-prs
|
|
3
|
+
description: |
|
|
4
|
+
Post-push follow-up for PRs/MRs: backoff-cadence polls over CI check runs
|
|
5
|
+
(fix every failure your diff caused), every greptile inline thread, and the
|
|
6
|
+
PR-level summary; classifies via gstack greptile-triage, suppresses via
|
|
7
|
+
greptile-history, stops after two consecutive empty polls with CI green.
|
|
8
|
+
Forge-aware (gh PR / glab MR). Use after `gh pr create` / `glab mr create`,
|
|
9
|
+
after every push to a branch with an open PR/MR, or on "babysit", "watch
|
|
10
|
+
greptile", "poll the PR/MR", "watch reviews", "follow up on review
|
|
11
|
+
feedback". Cross-agent: Claude, Codex, OpenCode, Amp.
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# orly-babysit-prs
|
|
15
|
+
|
|
16
|
+
Review bots (greptile on GitHub; greptile or another review bot on GitLab)
|
|
17
|
+
post auto-reviews **asynchronously**. They land as PR review comments / MR
|
|
18
|
+
discussion threads, not check runs, so `gh pr checks --watch` (or the glab
|
|
19
|
+
equivalent) doesn't observe them. Without explicit polling on a backoff
|
|
20
|
+
cadence, findings arrive after the human stops checking — so they get missed.
|
|
21
|
+
|
|
22
|
+
This skill is the **polling cadence + walk-every-review-thread loop**. The
|
|
23
|
+
fetch, classify, and reply mechanics live in gstack's `greptile-triage.md` —
|
|
24
|
+
open and follow it; do not paraphrase from memory. This skill never
|
|
25
|
+
duplicates the triage helper's logic; it adds (a) the cadence, (b) the
|
|
26
|
+
multi-thread walk, and (c) the **forge abstraction** so the same loop runs on
|
|
27
|
+
GitHub and GitLab.
|
|
28
|
+
|
|
29
|
+
## STEP 0 — Open greptile-triage.md every cycle
|
|
30
|
+
|
|
31
|
+
Before doing anything else in a polling cycle, read the triage helper:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
GREPTILE_TRIAGE="$HOME/.local/share/gstack/review/greptile-triage.md"
|
|
35
|
+
[ -r "$GREPTILE_TRIAGE" ] || GREPTILE_TRIAGE="$HOME/Projects/dotfiles/.unified-skills/review/greptile-triage.md"
|
|
36
|
+
[ -r "$GREPTILE_TRIAGE" ] || { echo "BABYSIT: greptile-triage.md missing — abort cycle"; exit 1; }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Then walk it section by section:
|
|
40
|
+
|
|
41
|
+
| Triage section | What this skill triggers |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `## Fetch` | Run per detected review thread (multi-thread loop below), via the forge layer |
|
|
44
|
+
| `## Suppressions Check` | Read `$HOME/.gstack/projects/<slug>/greptile-history.md`; skip lines tagged `fp` matching `repo + file-pattern + category` |
|
|
45
|
+
| `## Classify` | Read file ±10 lines around each comment's `path:line`; classify VALID & ACTIONABLE / VALID BUT ALREADY FIXED / FALSE POSITIVE / SUPPRESSED |
|
|
46
|
+
| `## Reply APIs` | Tier 1 first response, Tier 2 on re-flag — via the forge layer |
|
|
47
|
+
| `## Reply Templates` | Use Tier 1 / Tier 2 template verbatim — do not invent new wording |
|
|
48
|
+
| `## Severity Assessment & Re-ranking` | Re-rank the bot's severity against the project's actual risk profile |
|
|
49
|
+
| `## History File Writes` | Append to BOTH per-project and global history files (see below) |
|
|
50
|
+
| `## Output Format` | Use the triage helper's report shape, augmented with our cadence line |
|
|
51
|
+
|
|
52
|
+
If the triage helper is missing on the host, abort with `BABYSIT: greptile-triage.md missing` rather than guessing — the abort is visible, a silent re-implementation is not.
|
|
53
|
+
|
|
54
|
+
## STEP 0.5 — Detect the forge
|
|
55
|
+
|
|
56
|
+
`git remote` decides which CLI + review-object model to use. Everything
|
|
57
|
+
downstream branches on `$FORGE`.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
ORIGIN=$(git remote get-url origin 2>/dev/null)
|
|
61
|
+
case "$ORIGIN" in
|
|
62
|
+
*github.com*) FORGE=github ;;
|
|
63
|
+
*) FORGE=gitlab ;; # gitlab.com OR self-hosted (e.g. awakeninggit.e2enetworks.net)
|
|
64
|
+
esac
|
|
65
|
+
echo "BABYSIT: forge=$FORGE origin=$ORIGIN"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Concept | GitHub (`gh`) | GitLab (`glab`) |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| Change unit | Pull Request (PR) | Merge Request (MR) |
|
|
71
|
+
| Create cmd | `gh pr create` | `glab mr create` |
|
|
72
|
+
| Review object | a *review* with line comments | a *discussion* (thread) with notes |
|
|
73
|
+
| "walk every…" | every review id | every discussion thread id |
|
|
74
|
+
| Reply | reply to the review comment | post a note to the discussion |
|
|
75
|
+
|
|
76
|
+
Both forges' bots are filtered by author name matching `greptile` (or the
|
|
77
|
+
project's configured review bot — see the per-project history `bot:` note if
|
|
78
|
+
present).
|
|
79
|
+
|
|
80
|
+
## STEP 0.75 — CI checks must go green (poll + fix)
|
|
81
|
+
|
|
82
|
+
Greptile is not the only async signal: the PR/MR's **CI check runs** land on
|
|
83
|
+
their own schedule and are part of "done". The loop is not finished until CI is
|
|
84
|
+
green **and** the review bot is quiet. This is the one place `gh pr checks`
|
|
85
|
+
(NOT `--watch`) is the right tool — it observes *check runs*, which is exactly
|
|
86
|
+
what CI is. (The "never `gh pr checks --watch` for greptile" rule stands:
|
|
87
|
+
greptile posts review comments, not checks, so `pr checks` never sees it. CI
|
|
88
|
+
jobs are the opposite — `pr checks` is precisely how you see them.)
|
|
89
|
+
|
|
90
|
+
Each cycle, after the review-thread walk, poll CI and act by cause:
|
|
91
|
+
|
|
92
|
+
### GitHub
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
gh pr checks "$PR_NUMBER" --json name,state,bucket,link 2>/dev/null \
|
|
96
|
+
| jq -r '.[] | "\(.bucket)\t\(.state)\t\(.name)\t\(.link)"' # bucket ∈ pass|fail|pending|skipping|cancel
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### GitLab
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
glab ci status 2>/dev/null \
|
|
103
|
+
|| glab api "projects/$PROJ_ENC/merge_requests/$MR_IID/pipelines" \
|
|
104
|
+
| jq -r '.[0] | "\(.status)\t\(.web_url)"' # status ∈ success|failed|running|canceled|pending
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
| CI state | Action |
|
|
108
|
+
|---|---|
|
|
109
|
+
| all `pass`/`skipping` (GitLab `success`) | Record `ci=green`. A done-declaration is now allowed (if greptile is also quiet). |
|
|
110
|
+
| any `pending`/`running` | Record `ci=pending`; re-poll on the cadence. **Never declare done while a check is still running.** |
|
|
111
|
+
| any `fail`/`cancel` **from your changes** | In-scope finding you OWN — treat like a greptile fix. Fetch the failing log (`gh run view <run-id> --log-failed`, run id from the check `link`; GitLab `glab ci trace <job-id>`), fix the code, re-verify with the relevant `make` target, commit, push, re-poll. |
|
|
112
|
+
| any `fail` **NOT from your changes** (pre-existing red, infra flake, unrelated job) | Surface to the user with job name + link. Do **not** fix blindly, do **not** edit CI config. Pause the done-declaration until they decide. |
|
|
113
|
+
|
|
114
|
+
CI failures caused by your commit are not "surface and wait" — they are the
|
|
115
|
+
same contract as a greptile P0: diagnose, fix the code (never the CI config),
|
|
116
|
+
push, and re-poll until green.
|
|
117
|
+
|
|
118
|
+
## Triggers
|
|
119
|
+
|
|
120
|
+
- After `gh pr create` / `glab mr create` for a feature branch.
|
|
121
|
+
- After every `git push` to a branch with an open PR/MR.
|
|
122
|
+
- User says: "babysit", "watch greptile", "poll the PR", "poll the MR",
|
|
123
|
+
"watch reviews", "follow up on review feedback", "what did greptile say".
|
|
124
|
+
|
|
125
|
+
## Output contract
|
|
126
|
+
|
|
127
|
+
Per cycle, print one line (`PR` on GitHub, `MR` on GitLab):
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
BABYSIT <PR|MR> #<n> @ <SHA>: poll <i> | reviews=<count> | new=<m> | actioned=<k> | ci=<green|pending|red> | next=<delay>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`actioned` = findings whose code fix landed in this cycle (greptile OR CI).
|
|
134
|
+
`ci` = the aggregate check-run state from STEP 0.75.
|
|
135
|
+
|
|
136
|
+
## Cadence (backoff)
|
|
137
|
+
|
|
138
|
+
| Time since last push (or last review) | Poll interval |
|
|
139
|
+
|---|---|
|
|
140
|
+
| 0–10 min | +180 s after each push |
|
|
141
|
+
| 10–30 min | +300 s |
|
|
142
|
+
| 30–60 min | +600 s |
|
|
143
|
+
| > 60 min | +1200 s, then stop after 2 consecutive empty polls |
|
|
144
|
+
|
|
145
|
+
Claude Code: use `ScheduleWakeup(delaySeconds, "re-poll review on <PR|MR>
|
|
146
|
+
#<n> <SHA>")`. Other agents: `sleep <delay>` in a shell loop, or schedule
|
|
147
|
+
via the agent's native cron/wakeup mechanism.
|
|
148
|
+
|
|
149
|
+
## Polling loop
|
|
150
|
+
|
|
151
|
+
### GitHub (`FORGE=github`)
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
|
|
155
|
+
PR_NUMBER=$(gh pr view --json number --jq '.number')
|
|
156
|
+
|
|
157
|
+
# Walk EVERY review id — greptile may post more than one review per push.
|
|
158
|
+
REVIEW_IDS=$(gh api "repos/$REPO/pulls/$PR_NUMBER/reviews" \
|
|
159
|
+
--jq '.[] | select(.user.login | test("greptile"; "i")) | .id')
|
|
160
|
+
|
|
161
|
+
for rid in $REVIEW_IDS; do
|
|
162
|
+
# Follow greptile-triage.md (STEP 0): fetch line+top-level comments for THIS
|
|
163
|
+
# review id; Suppressions Check; Classify; Reply (Tier 1/Tier 2); history write.
|
|
164
|
+
# Fetch: gh api "repos/$REPO/pulls/$PR_NUMBER/reviews/$rid/comments"
|
|
165
|
+
# Reply: gh api -X POST "repos/$REPO/pulls/$PR_NUMBER/comments/<cid>/replies" -f body="..."
|
|
166
|
+
:
|
|
167
|
+
done
|
|
168
|
+
|
|
169
|
+
# ALSO triage greptile's SUMMARY feedback — it puts actionable findings in two
|
|
170
|
+
# places the line-comment walk above misses:
|
|
171
|
+
# (1) the review BODY (the review's own summary text), and
|
|
172
|
+
# (2) the top-level PR issue comment (greptile's "description reply" / summary,
|
|
173
|
+
# often with collapsible per-file sections listing concerns inline).
|
|
174
|
+
# Run each through greptile-triage.md exactly like a line comment.
|
|
175
|
+
gh api "repos/$REPO/pulls/$PR_NUMBER/reviews" \
|
|
176
|
+
--jq '.[] | select(.user.login|test("greptile";"i")) | select(.body != "") | .body'
|
|
177
|
+
gh api "repos/$REPO/issues/$PR_NUMBER/comments" \
|
|
178
|
+
--jq '.[] | select(.user.login|test("greptile";"i")) | {id, body}'
|
|
179
|
+
# Reply to a summary issue comment: gh api -X POST "repos/$REPO/issues/$PR_NUMBER/comments" -f body="..."
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### GitLab (`FORGE=gitlab`)
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Project full path (e.g. gpu/console), URL-encoded for the API.
|
|
186
|
+
PROJECT_PATH=$(glab repo view -F json 2>/dev/null | jq -r '.path_with_namespace' \
|
|
187
|
+
|| git remote get-url origin | sed -E 's#.*[:/]([^:/]+/[^/]+)$#\1#; s#\.git$##')
|
|
188
|
+
PROJ_ENC=$(printf '%s' "$PROJECT_PATH" | sed 's#/#%2F#g')
|
|
189
|
+
MR_IID=$(glab mr view -F json | jq -r '.iid')
|
|
190
|
+
|
|
191
|
+
# Walk EVERY discussion thread from the review bot. GitLab has no "review"
|
|
192
|
+
# object — a bot posts discussion threads (each with notes[]).
|
|
193
|
+
THREAD_IDS=$(glab api "projects/$PROJ_ENC/merge_requests/$MR_IID/discussions" --paginate \
|
|
194
|
+
| jq -r '.[] | select(any(.notes[]; .author.username | test("greptile"; "i"))) | .id')
|
|
195
|
+
|
|
196
|
+
for tid in $THREAD_IDS; do
|
|
197
|
+
# Follow greptile-triage.md (STEP 0): fetch the thread's notes (body +
|
|
198
|
+
# position.new_path/new_line for line-level); Suppressions Check; Classify;
|
|
199
|
+
# Reply (Tier 1/Tier 2); history write.
|
|
200
|
+
# Fetch: glab api "projects/$PROJ_ENC/merge_requests/$MR_IID/discussions/$tid"
|
|
201
|
+
# Reply: glab api -X POST "projects/$PROJ_ENC/merge_requests/$MR_IID/discussions/$tid/notes" -f body="..."
|
|
202
|
+
:
|
|
203
|
+
done
|
|
204
|
+
|
|
205
|
+
# ALSO triage greptile's SUMMARY feedback — the MR-level notes greptile posts
|
|
206
|
+
# outside a positioned discussion thread (the "description reply" / overview
|
|
207
|
+
# note, often with inline per-file concerns). Run each through greptile-triage.md.
|
|
208
|
+
glab api "projects/$PROJ_ENC/merge_requests/$MR_IID/notes" \
|
|
209
|
+
--jq '.[] | select(.author.username|test("greptile";"i")) | select(.type == null) | {id, body}'
|
|
210
|
+
# Reply to a summary note: glab api -X POST "projects/$PROJ_ENC/merge_requests/$MR_IID/notes" -f body="..."
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### History paths (forge-independent)
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
REMOTE_SLUG=$(~/.claude/skills/gstack/browse/bin/remote-slug 2>/dev/null \
|
|
217
|
+
|| basename "$(git rev-parse --show-toplevel 2>/dev/null || pwd)")
|
|
218
|
+
PROJECT_HISTORY="$HOME/.gstack/projects/$REMOTE_SLUG/greptile-history.md"
|
|
219
|
+
GLOBAL_HISTORY="$HOME/.gstack/greptile-history.md"
|
|
220
|
+
mkdir -p "$(dirname "$PROJECT_HISTORY")" "$(dirname "$GLOBAL_HISTORY")"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Critical: walk every review thread.** Greptile (or the bot) may post
|
|
224
|
+
multiple reviews/threads per push (one structural, one security, etc.). The
|
|
225
|
+
triage helper fetches once per call; the multi-thread walk lives here, on
|
|
226
|
+
both forges.
|
|
227
|
+
|
|
228
|
+
## History file discipline
|
|
229
|
+
|
|
230
|
+
Every triaged comment writes one line to BOTH:
|
|
231
|
+
|
|
232
|
+
| File | Purpose |
|
|
233
|
+
|---|---|
|
|
234
|
+
| `$HOME/.gstack/projects/<slug>/greptile-history.md` | Per-project. Drives Suppressions Check on next cycle — `fp` lines suppress matching comments forever. |
|
|
235
|
+
| `$HOME/.gstack/greptile-history.md` | Global aggregate. Cross-project retro / pattern-mining. |
|
|
236
|
+
|
|
237
|
+
Line format (from the triage helper's "History File Writes" section):
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
<YYYY-MM-DD> | <owner/repo> | <type:fp|fix|already-fixed> | <file-pattern> | <category>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
- **`fp`** — false positive. Suppressed on future polls.
|
|
244
|
+
- **`fix`** — real issue, fixed in this cycle. Not suppressed.
|
|
245
|
+
- **`already-fixed`** — real issue, fixed in a prior commit on this branch. Not suppressed.
|
|
246
|
+
|
|
247
|
+
The categories are a fixed set: `race-condition`, `null-check`, `error-handling`, `style`, `type-safety`, `security`, `performance`, `correctness`, `other`. Don't invent new categories — if a finding doesn't fit, use `other` and mention the actual concern in the reply, not the history line.
|
|
248
|
+
|
|
249
|
+
## After a fix lands
|
|
250
|
+
|
|
251
|
+
1. Fix the code per the triage helper's classification.
|
|
252
|
+
2. Re-verify with `make lint` + `make test` (or relevant tier).
|
|
253
|
+
3. Reply via the triage helper's "Reply APIs" section (Tier 1 / Tier 2
|
|
254
|
+
templates) through the forge layer above. Include the fix SHA in the body.
|
|
255
|
+
4. Commit and push.
|
|
256
|
+
5. Append the history line(s) to both files.
|
|
257
|
+
6. If the finding generalizes beyond this PR/MR (recurring pattern, new
|
|
258
|
+
class of bug), capture as a named rule in the project's
|
|
259
|
+
`docs/greptile-learnings/RULES.md` in the same commit as the fix.
|
|
260
|
+
Otherwise the history line alone is the durable record.
|
|
261
|
+
7. Re-schedule the next poll using the cadence table above.
|
|
262
|
+
|
|
263
|
+
## Stop conditions
|
|
264
|
+
|
|
265
|
+
- **Done = two consecutive empty polls AND CI green.** Both must hold: no new
|
|
266
|
+
reviews/threads/summary findings for two polls **and** STEP 0.75 reports
|
|
267
|
+
`ci=green`. A quiet bot with a still-`pending` or red CI is NOT done — keep
|
|
268
|
+
polling on the cadence.
|
|
269
|
+
- **PR/MR merged or closed** → stop, report.
|
|
270
|
+
- **CI red FROM your changes** → fix it (STEP 0.75): diagnose, fix the code,
|
|
271
|
+
push, re-poll. Not a stop condition — it's work to do.
|
|
272
|
+
- **CI red and NOT from your changes** → surface to the user; pause the
|
|
273
|
+
done-declaration until they decide.
|
|
274
|
+
- **User says stop / pause** → print one final
|
|
275
|
+
`BABYSIT <PR|MR> #<n>: paused per user` line and stop.
|
|
276
|
+
|
|
277
|
+
## Report format
|
|
278
|
+
|
|
279
|
+
At end of each cycle:
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
BABYSIT REPORT — <PR|MR> #<n> @ <SHA>
|
|
283
|
+
Polls run: <i>
|
|
284
|
+
Reviews seen: <count> (line: <l>, summary/description: <s>)
|
|
285
|
+
Findings actioned: <k> (P0: <a>, P1: <b>)
|
|
286
|
+
Findings deferred: <d> (with reasons)
|
|
287
|
+
CI: <green | pending: <job…> | red: <job> — <fixed SHA | surfaced to user>>
|
|
288
|
+
Rules added/updated: <list of RULE refs> # via triage helper's history-write
|
|
289
|
+
Next poll: in <delay>s OR stopped (<reason>)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## What this skill does NOT do
|
|
293
|
+
|
|
294
|
+
- Does **not** re-implement fetch/classify/reply — see
|
|
295
|
+
`~/.local/share/gstack/review/greptile-triage.md`.
|
|
296
|
+
- Does **not** merge the PR/MR — use `/land-and-deploy` after the bot is green.
|
|
297
|
+
- Does **not** modify CI configuration or skip the review bot.
|
|
298
|
+
- Does **not** apply P2/P3/nit findings without explicit user approval
|
|
299
|
+
(the triage helper's classification drives this).
|
|
300
|
+
|
|
301
|
+
## Failure modes
|
|
302
|
+
|
|
303
|
+
| Surface | Action |
|
|
304
|
+
|---|---|
|
|
305
|
+
| `gh api` / `glab api` rate-limited | Back off the poll interval by 2× and retry next cycle |
|
|
306
|
+
| Review missing on a push | Re-poll once at +180 s; if still missing, surface to user |
|
|
307
|
+
| `gh pr view` / `glab mr view` returns nothing (PR/MR not yet visible) | Skip cycle; retry next interval |
|
|
308
|
+
| `glab` not authed for a self-hosted host | Surface `BABYSIT: glab not authed for <host> — run glab auth login`; pause |
|
|
309
|
+
| Multiple reviews with conflicting suggestions | Apply the union; surface conflict only if both can't coexist |
|
|
310
|
+
| Finding is in code the agent did not author | Surface to user before fixing — never edit changes the agent did not create |
|
|
311
|
+
|
|
312
|
+
## References
|
|
313
|
+
|
|
314
|
+
- `~/.local/share/gstack/review/greptile-triage.md` — fetch / classify /
|
|
315
|
+
reply / suppressions / history-write mechanics. Also at
|
|
316
|
+
`~/Projects/dotfiles/.unified-skills/review/greptile-triage.md`.
|
|
317
|
+
- `$HOME/.gstack/projects/<slug>/greptile-history.md` — per-project
|
|
318
|
+
history; drives Suppressions Check.
|
|
319
|
+
- `$HOME/.gstack/greptile-history.md` — global aggregate.
|
|
320
|
+
- `docs/greptile-learnings/RULES.md` — project-level named rules
|
|
321
|
+
(durable principles). New rule added here only when the finding
|
|
322
|
+
generalizes; per-incident rows go to greptile-history.md.
|
|
323
|
+
- `~/Projects/dotfiles/AGENTS.md` — CHORE(close) skill chain step 4
|
|
324
|
+
cites this skill.
|
|
325
|
+
- `gh api` docs: https://cli.github.com/manual/gh_api
|
|
326
|
+
- `glab api` docs: https://gitlab.com/gitlab-org/cli (`glab api --help`)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orly-spec-new
|
|
3
|
+
description: |
|
|
4
|
+
Author a milestone/workstream spec the executing agent (Orly) ships into a
|
|
5
|
+
deterministic, review-clean, reported Pull Request — intent capture and
|
|
6
|
+
review-readiness first, file mechanics last. Use on "create a spec", "new
|
|
7
|
+
milestone", "start M{N}_{NNN}", "spec out X", or any TODO.md attempt
|
|
8
|
+
(forbidden — every non-trivial intent becomes a spec). Cross-agent,
|
|
9
|
+
self-contained markdown.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# orly-spec-new
|
|
13
|
+
|
|
14
|
+
A spec is the **rulebook** the executing agent (Orly) plans and ships from. This
|
|
15
|
+
skill makes me author one whose Pull Request (PR) lands **deterministic, review-clean, and
|
|
16
|
+
reported** — without a 20-questions loop. It is written for my reasoning, not as
|
|
17
|
+
a file-naming guide: the mechanics (naming, layout) are demoted to the end
|
|
18
|
+
because they are the easy part.
|
|
19
|
+
|
|
20
|
+
> **The trio stays coherent.** This skill (*how to author*) ← `docs/TEMPLATE.md`
|
|
21
|
+
> (*the section shape*) → `audits/spec-template.sh` (*the enforcer*). If a
|
|
22
|
+
> step here demands something, the template carries the section and the audit
|
|
23
|
+
> asserts it. Drift between the three is a bug.
|
|
24
|
+
|
|
25
|
+
A spec is an *instance*; `AGENTS.md` and `docs/greptile-learnings/RULES.md` are
|
|
26
|
+
the *constants*. When the spec contradicts a rule, amend the spec — never weaken
|
|
27
|
+
the rule.
|
|
28
|
+
|
|
29
|
+
## What a good spec guarantees
|
|
30
|
+
|
|
31
|
+
The three outcomes every step below serves:
|
|
32
|
+
|
|
33
|
+
- **Deterministic / invariant** — the agent plans and builds with no `[?]`; every claim is a test; every invariant is enforced by code, not review discipline.
|
|
34
|
+
- **Review-clean** — the code it produces trips no greptile finding, because the spec pre-commits to the exact `RULES.md` rule IDs and gates the diff touches.
|
|
35
|
+
- **Reported** — Discovery (consult log), the Acceptance Rubric's Graded column, and skill-chain outcomes are populated as the work proceeds.
|
|
36
|
+
|
|
37
|
+
## Triggers
|
|
38
|
+
|
|
39
|
+
- User says: "create a spec", "spec this out", "new milestone", "draft M{N}_{NNN}", "start on M{N}", "track this as a milestone".
|
|
40
|
+
- The user attempts a `TODO.md` or any ad-hoc task list — convert it into a spec. **`TODO.md` is forbidden.**
|
|
41
|
+
- A `plan-eng-review` / `plan-ceo-review` / `plan-design-review` produced a plan that should be tracked durably.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Step 1 — Capture intent (the hard part — do it before any file)
|
|
46
|
+
|
|
47
|
+
Determinism starts here. Before copying the template:
|
|
48
|
+
|
|
49
|
+
- **Testable goal** — one sentence that could be a test name. "Implement streaming" is not a goal; "SSE handler streams pubsub as `text/event-stream`, p95 < 200ms" is.
|
|
50
|
+
- **PR title + intent** — what the merged PR is called (imperative, ≤72 chars) and the one-sentence user-facing *why*.
|
|
51
|
+
- **Comprehension handshake** — restate the intent in my own words and list `ASSUMPTIONS I'M MAKING: …`. If my restatement and the requester's ask diverge, STOP and reconcile before drafting.
|
|
52
|
+
- **Golden-path walk** — trace the concrete end-to-end (every lookup, data source, secret store). Any `[?]` left in the walk blocks the spec from leaving `pending/`.
|
|
53
|
+
- **Product Clarity — Indy's ten product questions, answered in order** (successful user moment · preserved user behaviour · optimal-way check · rebuild-vs-iterate · what we build · what we do NOT build · fit with existing features · surface order · dashboard restraint · confused-user next step). They are answered BEFORE any implementation section is drafted; internal-only work may answer 8–10 as "N/A — no user surface" with the reason.
|
|
54
|
+
|
|
55
|
+
→ Fills the template's **PR Intent & comprehension handshake**, **Overview**, and **Product Clarity (authoring record)**.
|
|
56
|
+
|
|
57
|
+
## Step 2 — Lock review-readiness (so the PR ships clean)
|
|
58
|
+
|
|
59
|
+
This is the step that prevents greptile findings — the spec becomes a pre-commitment to the rules its code must obey:
|
|
60
|
+
|
|
61
|
+
- **Applicable Rules** — name the *specific* `docs/greptile-learnings/RULES.md` rule IDs the diff will trip (e.g. NDC, NLR, NLG, UFS), plus the per-surface dispatch façades / rule files: `dispatch/write_zig.md` (`*.zig`), `docs/REST_API_DESIGN_GUIDELINES.md` (`src/http/handlers/**`), `docs/SCHEMA_CONVENTIONS.md` (`schema/*`), `dispatch/write_ts_adhere_bun.md`, `docs/LOGGING_STANDARD.md`, `docs/LIFECYCLE_PATTERNS.md`. Generic "follow RULES.md" earns a greptile finding; named IDs the implementer obeys by construction do not. Cite rule docs by their repo-local `docs/…` paths — the selected packs materialise them into every repository; cite only files that exist here (`test -f` each).
|
|
62
|
+
- **Applicable Gates** — which Action-Triggered Guards fire (ZIG, PUB, LENGTH, UFS, UI, DESIGN TOKEN, LOGGING, LIFECYCLE, SCHEMA, ERROR REGISTRY) and the satisfaction strategy for each. Rules ≠ gates: rules are knowledge to read; gates fire on edits.
|
|
63
|
+
- **Prior-Art / Reference Implementations** — the reference codebase to mirror (CLI → the "7 Pillars" of CLI DX in `docs/TEMPLATE.md` Prior-Art; API → REST guide + nearest handler). No reinventing what a known-good pattern already solves.
|
|
64
|
+
|
|
65
|
+
→ Fills **Applicable Rules**, **Applicable Gates**, **Prior-Art / Reference Implementations**.
|
|
66
|
+
|
|
67
|
+
## Step 3 — Make it provable & reported
|
|
68
|
+
|
|
69
|
+
- Decompose **Sections** into numbered **Dimensions** (3.1, 3.2 …) — the unit of DONE. **Every Dimension → one Test** (tiered: unit/integration/e2e per `/orly-write-unit-test`; any user-facing Category gets a user-centric `test-e2e*` scenario).
|
|
70
|
+
- **Every Failure Mode → a negative test.** **Every Invariant → enforced by code** (compiler, lint, comptime assertion, runtime check) — never by review discipline.
|
|
71
|
+
- **Every Metrics row → event/test proof.** User-facing or operator-facing specs declare product/operator signals, privacy guards, and analytics/funnel playbook updates; internal-only cleanup explicitly says no signal changed.
|
|
72
|
+
- **Rubric = 5–12 outcome rows** — one per Section outcome, failure class, or hygiene gate (never per Dimension); each with a copy-paste Verify command and a mechanically checkable Expected (exit code / literal substring / match count). Standard rows come pre-filled in the template — prune to the touched surface.
|
|
73
|
+
- **Reporting spine** — **Discovery (consult log)** carries consults, skill-chain outcomes, and Indy-acked deferral quotes; the **Acceptance Rubric's Graded column** carries the VERIFY verdicts (✅/❌ + one decisive output line each). Both empty at creation, populated as work proceeds.
|
|
74
|
+
|
|
75
|
+
→ Fills **Sections (+ Dimensions)**, **Metrics & Observability**, **Failure Modes**, **Invariants**, **Test Specification (tiered)**, **Acceptance Rubric**, **Discovery**.
|
|
76
|
+
|
|
77
|
+
## Step 4 — Mechanics (the easy part)
|
|
78
|
+
|
|
79
|
+
Now the file. Pick the ID and copy the template:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# next free M{N}_{WS}
|
|
83
|
+
ls docs/v*/pending/ docs/v*/active/ docs/v*/done/ 2>/dev/null \
|
|
84
|
+
| grep -oE 'M[0-9]+_[0-9]+' | sort -u | tail -5
|
|
85
|
+
cp docs/TEMPLATE.md docs/v{N}/pending/M{N}_{WS}_P{P}_{CATEGORIES}_{NAME}.md
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
**Fill grammar** — the template body is ordered for the *executing* agent (execution read order), not for authoring; fill sections in the order of Steps 1–3 above, not top-to-bottom. Replace every `{…}` slot with instance content, then **delete every `<!-- tpl: … -->` guidance comment** — the SPEC TEMPLATE GATE BLOCKs any survivor, unfilled slot sentinels, and missing required sections. The SPEC AUTHORING RULES banner is the one comment that stays.
|
|
90
|
+
|
|
91
|
+
**Inputs** — Milestone `M{N}` (next free, sortable) · Workstream `{WS}` zero-padded (`001`…) · Priority (**P0** blocking · **P1** customer/operator-facing · **P2** tooling · **P3** deferrable) · Category set alphabetised (`API` Zig/Go · `CLI` agentsfleet/Node · `UI` Next.js · `OBS` Grafana · `SKILL` SKILL.md · `INFRA` Terraform) · Name UPPER_SNAKE_CASE ≤6 words describing the outcome (`BUN_VENDOR_UTILITIES`, not `BUMP_BUN_DEPS`) · Prototype tag (`v1.0.0`, `v2.0.0` — drives `docs/v1/` vs `docs/v2/`).
|
|
92
|
+
|
|
93
|
+
**File naming:** `docs/v{N}/{pending|active|done}/M{Milestone}_{Workstream}_P{Priority}_{CATEGORIES}_{NAME}.md` (e.g. `docs/v2/pending/M52_001_P2_API_BUN_VENDOR_UTILITIES.md`). Do NOT rename existing legacy-form files under `docs/v1/` or `docs/v2/done/`.
|
|
94
|
+
|
|
95
|
+
**Terminology — binding for everything that lands in a file** (conversational replies are exempt):
|
|
96
|
+
|
|
97
|
+
| Use | Do NOT use |
|
|
98
|
+
|---|---|
|
|
99
|
+
| Prototype (v1.0.0) | Release, Version train, Program |
|
|
100
|
+
| Milestone (M{N}) | Sprint, waterfall stage, Quarter |
|
|
101
|
+
| Workstream (M{N}_{WS}) | Ticket, Task, Story, Issue |
|
|
102
|
+
| Section (§3) | Waterfall stage, Step, Chapter |
|
|
103
|
+
| Dimension (3.4) | Acceptance criterion, AC, Checkbox |
|
|
104
|
+
| Batch (B2) | Wave, Tranche, Iteration |
|
|
105
|
+
|
|
106
|
+
**Directory movement** is lifecycle-driven: created → `pending/` (`Status: PENDING`); begin implementation → `active/` (CHORE(open)); all Dimensions DONE + PR opened → `done/`; parked → stay in `active/`.
|
|
107
|
+
|
|
108
|
+
## Step 5 — Self-review gate, then commit
|
|
109
|
+
|
|
110
|
+
Before the spec leaves `pending/`, it must pass this checklist — the deterministic/invariant guarantee:
|
|
111
|
+
|
|
112
|
+
- [ ] intent handshake done; golden-path walk has **no `[?]`**
|
|
113
|
+
- [ ] **Product Clarity answered** — ten items, in order, `[?]`-free
|
|
114
|
+
- [ ] **zero `tpl:` guidance comments remain** — the body carries only instance content
|
|
115
|
+
- [ ] **Applicable Rules names specific greptile rule IDs**; Applicable Gates populated with satisfaction strategy
|
|
116
|
+
- [ ] **Metrics & Observability declares events or explicitly says no product/operator signal changed**; any analytics/funnel playbook update is listed
|
|
117
|
+
- [ ] **every Dimension has a Test**; **every Failure Mode has a negative test**; every Invariant is code-enforceable
|
|
118
|
+
- [ ] Prior-Art reference named (or "greenfield — shape in `docs/architecture/`")
|
|
119
|
+
- [ ] reporting sections present (Discovery; Acceptance Rubric with Graded column empty)
|
|
120
|
+
- [ ] `bash audits/spec-template.sh --staged` is clean (it BLOCKs missing required sections and unfilled `{placeholders}`)
|
|
121
|
+
|
|
122
|
+
Then commit in the current authoring context:
|
|
123
|
+
|
|
124
|
+
- If the skill is running inside an existing branch/worktree, author and commit the spec there.
|
|
125
|
+
- If there is no branch/worktree context, use the repo's `main` branch as the fallback.
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
git add docs/v{N}/pending/M{N}_{WS}_*_{NAME}.md
|
|
129
|
+
git commit -m "docs(m{N}): add spec — {short title}"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The spec lands in `pending/` on the branch/worktree where the skill was invoked. CHORE(open) moves it to `active/` and creates any needed worktree — handled by the lifecycle, not this skill.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## What this skill does NOT do
|
|
137
|
+
|
|
138
|
+
- It does **not** start coding, create a worktree, or move the spec to `active/`. That's CHORE(open), when implementation begins.
|
|
139
|
+
- It does **not** modify any rule file, ARCHITECTURE doc, or changelog.
|
|
140
|
+
- It does **not** create a branch just to author a spec. Spec creation uses the current branch/worktree, falling back to `main` only when no branch/worktree exists.
|
|
141
|
+
|
|
142
|
+
## Failure modes
|
|
143
|
+
|
|
144
|
+
| Surface | What you do |
|
|
145
|
+
|---|---|
|
|
146
|
+
| User insists on `TODO.md` | Decline. Convert the intent into a spec via this skill. |
|
|
147
|
+
| Spec name collides with a `done/` entry | Pick the next workstream number; never reuse. |
|
|
148
|
+
| Spec depends on something still in `pending/` | Allowed — list it in `Depends on:` and surface it. |
|
|
149
|
+
| Spec proposes work that violates a rule | Amend the spec text or scope before committing. Rules are the constants. |
|
|
150
|
+
| Can't write the goal as a test name | Intent is not understood yet — go back to Step 1; do not draft sections. |
|
|
151
|
+
|
|
152
|
+
## References
|
|
153
|
+
|
|
154
|
+
- `docs/TEMPLATE.md` — the section shape this skill fills (materialised per-repo by `workflow.specifications`; canonical source: the orly repository).
|
|
155
|
+
- `audits/spec-template.sh` — the enforcer (`--staged` BLOCKs an incomplete spec).
|
|
156
|
+
- `docs/greptile-learnings/RULES.md` — the rule IDs Step 2 pins for review-cleanliness.
|
|
157
|
+
- The repository's generated `AGENTS.md` — lifecycle stages, action-triggered guards, deterministic VERIFY/CHORE sequencing.
|