vouchington-tooling 0.43.0 → 0.44.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 (64) hide show
  1. package/README.md +45 -1
  2. package/dist/cli/commands/fresh-base.d.mts +6 -0
  3. package/dist/cli/commands/fresh-base.mjs +14 -0
  4. package/dist/cli/index.mjs +3 -0
  5. package/dist/cli/parse-fresh-base.d.mts +2 -0
  6. package/dist/cli/parse-fresh-base.mjs +15 -0
  7. package/dist/cli/parse.d.mts +5 -0
  8. package/dist/cli/parse.mjs +3 -0
  9. package/dist/cli/usage.d.mts +1 -1
  10. package/dist/cli/usage.mjs +2 -0
  11. package/dist/fresh-base/classify.d.mts +21 -0
  12. package/dist/fresh-base/classify.mjs +29 -0
  13. package/dist/fresh-base/index.d.mts +4 -0
  14. package/dist/fresh-base/index.mjs +2 -0
  15. package/dist/fresh-base/run.d.mts +25 -0
  16. package/dist/fresh-base/run.mjs +66 -0
  17. package/dist/gh-cli/closing-refs.d.mts +24 -0
  18. package/dist/gh-cli/closing-refs.mjs +37 -0
  19. package/dist/gh-cli/index.d.mts +3 -0
  20. package/dist/gh-cli/index.mjs +2 -0
  21. package/dist/gh-cli/non-closing-refs.d.mts +11 -0
  22. package/dist/gh-cli/non-closing-refs.mjs +24 -0
  23. package/dist/index.d.mts +6 -0
  24. package/dist/index.mjs +3 -0
  25. package/dist/pull-request-diff/diff-size.d.mts +29 -0
  26. package/dist/pull-request-diff/diff-size.mjs +35 -0
  27. package/dist/pull-request-diff/index.d.mts +2 -0
  28. package/dist/pull-request-diff/index.mjs +1 -0
  29. package/dist/retrospective-distill/args.d.mts +13 -0
  30. package/dist/retrospective-distill/args.mjs +27 -0
  31. package/dist/retrospective-distill/checkpoint-entry.d.mts +2 -0
  32. package/dist/retrospective-distill/checkpoint-entry.mjs +11 -0
  33. package/dist/retrospective-distill/fixtures.test-helpers.d.mts +3 -0
  34. package/dist/retrospective-distill/fixtures.test-helpers.mjs +21 -0
  35. package/dist/retrospective-distill/flag-args.d.mts +5 -0
  36. package/dist/retrospective-distill/flag-args.mjs +31 -0
  37. package/dist/retrospective-distill/index.d.mts +10 -0
  38. package/dist/retrospective-distill/index.mjs +6 -0
  39. package/dist/retrospective-distill/partition-records.d.mts +6 -0
  40. package/dist/retrospective-distill/partition-records.mjs +49 -0
  41. package/dist/retrospective-distill/retrospective-entry.d.mts +3 -0
  42. package/dist/retrospective-distill/retrospective-entry.mjs +4 -0
  43. package/dist/retrospective-distill/run.d.mts +5 -0
  44. package/dist/retrospective-distill/run.mjs +28 -0
  45. package/dist/retrospective-distill/session-types.d.mts +17 -0
  46. package/dist/retrospective-distill/session-types.mjs +1 -0
  47. package/dist/retrospective-distill/shape.d.mts +29 -0
  48. package/dist/retrospective-distill/shape.mjs +111 -0
  49. package/docs/mcp-server.md +1 -1
  50. package/package.json +18 -3
  51. package/skills/agent-workflow/SKILL.md +20 -0
  52. package/skills/agent-workflow/references/four-refs.md +74 -0
  53. package/skills/blackboard/SKILL.md +21 -1
  54. package/skills/github-issue/SKILL.md +6 -0
  55. package/skills/manifest.json +11 -5
  56. package/skills/postgres-node-performance-tuning/SKILL.md +2 -0
  57. package/skills/postgres-node-performance-tuning/references/performance-patterns.md +76 -0
  58. package/skills/postgres-node-performance-tuning/references/reading-plans.md +111 -0
  59. package/skills/postgres-schema-design/references/relations.md +18 -0
  60. package/skills/retrospective-distill/SKILL.md +67 -4
  61. package/skills/revisit-followups/SKILL.md +17 -0
  62. package/skills/stacked-prs/SKILL.md +47 -16
  63. package/skills/stacked-prs/references/drain.md +168 -0
  64. package/skills/stacked-prs/references/gh-stack.md +143 -0
@@ -0,0 +1,168 @@
1
+ # Drain and keep track
2
+
3
+ Shepherding a layer to ready and merging are different acts. The first covers every pull request
4
+ the worker owns in the stack at once. The second lands the ready prefix in one command, and it is
5
+ never the agent's own decision.
6
+
7
+ ## Establish scope
8
+
9
+ 1. Resolve the stack from `pulls/<any-layer>.stack`, and record whether the field was present. A
10
+ stack object supplies its number; an explicit `null` means no registered stack. A missing
11
+ preview field: query `stacks?pull_request=<N>`, where one result is the stack and zero means
12
+ unstacked. Do not treat an empty `.stack.number` alone as proof
13
+ that a pull request is unstacked.
14
+ 2. Read topology from `repos/{owner}/{repo}/stacks/<n>`, ordered bottom to top. A
15
+ `closed && merged_at == null` layer below an open one means the stack is broken. Report it to
16
+ the human, and never merge across it.
17
+ 3. Partition by ownership, using that topology read plus each member's body from `pulls/<N>` (the
18
+ stack response has no bodies). Shepherd only owned pull requests. Never
19
+ poll, fix, rebase, or push the others, but list them in every report. Owned means this session
20
+ opened the pull request, or a human named it in this session.
21
+ - The opened-by-me half is a durable remote fact when the repository's pull request description
22
+ tool stamps each body with the authoring harness and session id. Compare the stamp with the
23
+ current session id.
24
+ - The named-by-a-human half is conversational and cannot be recovered remotely. That is
25
+ acceptable, because the human can restate it after a compaction.
26
+ - Degrade explicitly. A body without a matching stamp, or with a stamp naming no session id,
27
+ is not owned. Report it as "ownership unverifiable" and never poll it.
28
+ - A parent may assign its stack to one worker by listing the pull request numbers and the
29
+ session id stamped on them. The worker treats that list as assigned and still refuses any
30
+ layer outside it.
31
+
32
+ ## Shepherd the owned layers
33
+
34
+ Run one stack shepherd poll for the assigned stack, and follow its printed instructions.
35
+
36
+ - A shepherd's own "owned" mark can mean only that the author login equals the authenticated
37
+ viewer. Several sessions often share one account, so filter every printed row against the
38
+ ownership partition above before acting. Never start a per-pull-request session, fix, or push
39
+ for a row outside it, even when the shepherd marks it owned.
40
+ - Apply code fixes, rebases, pushes, and review mutations to owned layers only. Report work
41
+ surfaced on an unowned layer to the human.
42
+ - Fix on the owning layer. Commit there, rebase the layers above it (`gh stack rebase --upstack`),
43
+ `gh stack sync` when there are no local stack commits, `gh stack push` once, then rerun the
44
+ shepherd.
45
+ `rebase --upstack` and `push` act through the top of the stack. When an unowned layer sits above
46
+ an owned one, stop at that layer: do not rebase or push it, and hand the remaining rebase and
47
+ push to its owner.
48
+ - Start the shepherd with the first pull request. While the poll is in a pure wait and the
49
+ worktree is clean, commit the next layer once the lower layer is in decent shape. On a
50
+ fix-code result, finish it on the owning layer before more upper edits. A ready-delay schedules
51
+ the rerun: continue owned work on a later layer, and do not invent unrelated work.
52
+ - Never run a printed merge command unless the human's approval covers that layer and every open
53
+ layer below it, and the checks below pass. `gh stack merge <pr>` lands that pull request and
54
+ every layer below it.
55
+ - Mutating git does not parallelize. Stop the poll before a rebase, sync, or push in the stack's
56
+ shared worktree, because other layers' branches can be rewritten underneath it. Discard a poll
57
+ result that was in flight across the mutation, and start the poll again after the push lands.
58
+ Run at most one git mutation at a time.
59
+
60
+ ### Upper-only fast-forward
61
+
62
+ A queued lower layer, or any lower layer that must not be rewritten, does not stop an upper-only
63
+ fast-forward, or upper review and CI work that does not write git.
64
+
65
+ - Before that push, read the forge and capture the parent head, the parent base, the upper remote
66
+ head, and the stack order. Read all four again immediately before pushing.
67
+ - Push only when all four still match, the local upper commit fast-forwards that remote head, and
68
+ it still contains the parent. If anything differs, or the lower layer merges or leaves the queue
69
+ meanwhile, stop and read the forge again. Never push from a stale capture.
70
+ - Do not amend, force-push, `gh stack sync`, or `gh stack rebase` a queued parent: each rewrites
71
+ it. When the lower layer changes, re-read topology before branch work that depends on the new
72
+ parent.
73
+
74
+ ### Escalations persist to the pull request
75
+
76
+ When a layer needs a human, because it is ready and waiting on a merge decision or genuinely
77
+ blocked:
78
+
79
+ - Apply the repository's needs-human label and post one comment per escalation event, not per
80
+ poll, with the layer's position and what it needs.
81
+ - When a layer re-escalates, minimize the superseded comment (GraphQL `minimizeComment`,
82
+ `classifier: OUTDATED`). Clear the label once the layer no longer needs a human.
83
+ - A relayed merge command is for visibility only. The shepherd picks its target from ready
84
+ results alone and does not know what the human approved.
85
+
86
+ ## Report
87
+
88
+ When the owned set settles, present the stack bottom to top: each layer's number, owner, state,
89
+ and whether it is ready or blocked and why. Never leave a ready bottom layer under a blocked upper
90
+ layer without saying so.
91
+
92
+ ## Merge the ready prefix
93
+
94
+ The ready prefix is the bottom-most open layer plus every consecutive layer above it that is also
95
+ ready and inside the approval. Its top layer is the merge target. A shepherd that prints a merge
96
+ of its highest ready layer may name a layer above the approved range. Target the highest approved
97
+ layer of the prefix instead; that is still one command.
98
+
99
+ Merge only on explicit human approval. The approval names what it covers: one layer, a range, or
100
+ the whole stack. Approving the whole stack also covers the next ready prefix after an earlier
101
+ merge. It does not cover a layer added after the approval. Ask before merging any layer outside
102
+ it.
103
+
104
+ Immediately before each approved merge, run these checks in order:
105
+
106
+ 1. `gh api repos/{owner}/{repo}/stacks/<target>` must return 404. `gh stack merge` resolves a bare
107
+ number as a stack number first, then a pull request number. A 200 response means `--yes` would
108
+ merge every layer of that stack. Stop and ask.
109
+ 2. Re-read topology. Confirm every layer from the bottom-most open layer up to the target is open,
110
+ ready, and inside the approval, with nothing broken below.
111
+ 3. For every layer in the prefix, capture `pulls/<N>.head.sha` before the final poll and after it.
112
+ They must match. A mismatch means a push landed inside the evaluation window: discard the
113
+ verdict and poll again.
114
+ 4. `gh stack merge <target> --yes` with the repository's merge strategy. It lands the target and
115
+ every open layer below it, which is the ready prefix.
116
+ 5. Do not `gh stack sync` here. Return to step 2 of [Establish scope](#establish-scope) and
117
+ re-read topology remotely: rebasing right after a merge can replay already-landed commits from
118
+ a stale local base ref. Keep shepherding the layers above. When the new bottom is ready, merge
119
+ the next ready prefix the same way. Before any local edit, rebase, or push on a remaining
120
+ layer, rerun the fetch and ahead/behind check in
121
+ [Import a stack](gh-stack.md#import-a-stack-before-acting-on-it): GitHub rebases the next
122
+ layer remotely, so local upper branches are stale until fast-forwarded. The drain is complete when no unmerged owned layer remains.
123
+
124
+ The window between the last head read and the merge cannot be closed, because `gh stack merge`
125
+ has no head-SHA pin. Branch protection and rulesets are evaluated when the merge runs, and stacks
126
+ cannot bypass merge requirements. If the merge is rejected, re-read topology instead of retrying
127
+ blindly. Under a merge queue, a successful `gh stack merge` only enqueues: the prefix queues
128
+ together, and a failing layer is ejected along with the layers above it. The next topology
129
+ re-read handles that.
130
+
131
+ When you stop or are blocked (an unresolved escalation, an interrupt or pause, repeated fixes with
132
+ no progress, or an external blocker), report each layer's number and state. If the bottom layers
133
+ are ready, ask whether to merge that ready prefix before continuing.
134
+
135
+ ## Keep track: derive the ledger
136
+
137
+ A hand-kept list of "pull requests I opened" drifts, and a compaction or new session erases it.
138
+ The ownership stamp makes the ledger derivable, so state is re-read instead of recalled.
139
+
140
+ Reconcile broadly, partition narrowly. A new session opens a rival stack because it never looks for
141
+ the old one, so the reconcile query is deliberately unfiltered; only the partition is
142
+ session-filtered:
143
+
144
+ ```bash
145
+ # Reconcile, unfiltered: it finds stacks this session did not create.
146
+ gh api --paginate repos/{owner}/{repo}/stacks --jq '.[] | select(.open)' # 30 per page
147
+ gh api --paginate "repos/{owner}/{repo}/pulls?state=open&per_page=100" \
148
+ --jq '.[] | {number, title, user: .user.login, body}'
149
+ # Partition: apply the ownership check from Establish scope to that output.
150
+ ```
151
+
152
+ - Reconcile before starting anything new. At the start of work, and before opening any pull
153
+ request or stack, surface every open stack or unfinished layer, whoever made it.
154
+ - Close out; do not drift away. Close a layer that will not land. Ending or pausing a session with
155
+ owned open layers requires reporting them.
156
+ - Continue the stack instead of starting a parallel one. Dependent work for an owned open stack is
157
+ a new layer (`gh stack add`, after the layer cap check). For an unowned open stack, report it and
158
+ ask instead of adding to it or starting a rival.
159
+ - Derive state (which pull requests and stacks exist, their positions, their status) every time;
160
+ never cache it. Only intent, such as which stack is being built or what a planned layer is for,
161
+ belongs in the session's plan or journal, and it is a plan, not a record.
162
+
163
+ Known gaps:
164
+
165
+ - An ownership stamp is a body line any writer can edit. It is a signal, not an authorization
166
+ boundary, and that is sound only because every merge is human-gated.
167
+ - Stack and pull request numbers share no guaranteed disjointness, which is why merge check 1
168
+ runs before every merge.
@@ -0,0 +1,143 @@
1
+ # gh-stack mechanics
2
+
3
+ Official docs (do not copy): [About](https://docs.github.com/en/pull-requests/get-started/about-stacked-prs),
4
+ [CLI](https://docs.github.com/en/pull-requests/reference/stacked-prs-cli-commands),
5
+ [Managing](https://docs.github.com/en/pull-requests/how-tos/create-pull-requests/managing-stacked-pull-requests),
6
+ [Merging](https://docs.github.com/en/pull-requests/how-tos/merge-and-close-pull-requests/merging-stacked-pull-requests).
7
+
8
+ ## Setup
9
+
10
+ - Install on first stacked use: `gh extension install github/gh-stack`. The feature is in public
11
+ preview.
12
+ - If `gh stack` exits 9 (stacks are not enabled on the repository), do not bundle the source issues
13
+ into one pull request. Open one pull request on the default branch for the bottom issue, wait for
14
+ it to merge, then open the next. Say that stacks are unavailable.
15
+ - Workflows that must run on stacked pull requests must not set `pull_request.branches` or
16
+ `branches-ignore`. GitHub evaluates `branches: [main]` against `stack.base.ref`, but
17
+ `gh stack submit` opens mid-stack pull requests before the stack object exists
18
+ ([github/gh-stack#425](https://github.com/github/gh-stack/issues/425)), so the filter skips them
19
+ permanently. After a workflow trigger change lands on the default branch, rebase existing stacks
20
+ (`gh stack rebase` or `gh stack sync`) so parent branches include it.
21
+
22
+ ## Agent commands
23
+
24
+ Use only non-interactive forms, and run every `gh stack` command without a TTY. Run
25
+ `git config rerere.enabled true` before the first `init`, which otherwise prompts. An explicit
26
+ `checkout` prompts when local and remote compositions differ, and `submit --auto` prompts to
27
+ create ordinary pull requests when stacks are disabled; without a TTY these fail instead, so treat
28
+ a failure as the exit-9 recovery above rather than answering a prompt.
29
+
30
+ - `gh stack init <branch>`, rooted on the default branch only.
31
+ - `gh stack add <branch>`, after the layer cap check in [SKILL.md](../SKILL.md#work-bottom-up).
32
+ - `gh stack checkout <stack-or-pr-number>` imports an existing remote stack. See
33
+ [Import a stack](#import-a-stack-before-acting-on-it).
34
+ - `gh stack submit --auto` creates drafts. Immediately update each new pull request's title and
35
+ body with the repository's pull request description tool; auto titles and bodies are not
36
+ sufficient, and an unstamped body fails the ownership check in [drain.md](drain.md).
37
+ - `gh stack link <branch-or-pr>...` (bottom to top) registers a stack without local tracking. It
38
+ pushes the branches and creates a draft pull request for any branch without one. Update each
39
+ pull request it created the same way as after `submit --auto`.
40
+ - `gh stack view --json` is for acting only. Never use it, or `gh stack bottom`, to decide
41
+ topology, ownership, or bottom-ness.
42
+ - `gh stack rebase`, `gh stack rebase --upstack`, `gh stack rebase --continue`,
43
+ `gh stack rebase --abort`.
44
+ - `gh stack sync` fetches, fast-forwards the trunk, cascade-rebases every layer onto its updated
45
+ parent, and pushes all branches with `--force-with-lease --atomic`. It rewrites every layer's
46
+ head, so treat it like a rebase: stop the poll first, never run it over a queued layer, and
47
+ expect reviewed heads to change. Do not check out the default branch. Run it without a TTY (a
48
+ TTY prompts on local/remote divergence; without one it aborts) and without `--prune`.
49
+ - `gh stack push`.
50
+ - `gh stack up <n>`, `gh stack down <n>`, `gh stack top`, `gh stack bottom`, for movement only.
51
+ - `gh stack merge <pr> --yes --squash`, or the repository's merge strategy. The pull request number
52
+ is required. `--yes` skips a prompt that a non-interactive runner cannot answer.
53
+ - `gh stack unstack [<stack-number>]` (alias `delete`) recovers a mis-rooted stack. With no
54
+ argument it targets the active stack. It unstacks on GitHub and removes local tracking; add
55
+ `--local` to remove only local tracking. Pull requests and branches survive. GitHub leaves
56
+ queued or auto-merge pull requests stacked, and then keeps the stack.
57
+
58
+ Never run the interactive forms: `gh stack submit` without `--auto`, `gh stack modify`, bare
59
+ `gh stack checkout`, `gh stack switch`, or bare `gh stack merge` (a TUI that lands the whole
60
+ stack). `gh stack checkout <branch>` resolves only stacks this worktree already tracks. Do not run
61
+ `gh stack trunk` from a linked worktree whose default branch is checked out elsewhere.
62
+
63
+ ## Worktree and scope
64
+
65
+ - One worktree per stack. Move with `up` and `down`. Do not add a worktree per layer:
66
+ `gh stack rebase --upstack` rewrites upper branches, and git refuses to update a branch checked
67
+ out in another worktree.
68
+ - `git diff --name-only origin/<default>...HEAD` lists what lands if this layer and every layer
69
+ below merge.
70
+ - `git diff --name-only <parent>...HEAD` is this layer's review scope.
71
+
72
+ ## Import a stack before acting on it
73
+
74
+ `gh stack rebase`, `sync`, `push`, and movement act only on stacks the worktree's local record
75
+ tracks. A stack created from another worktree, session, or machine is not tracked. Before rebasing
76
+ or pushing a layer, including when a shepherd instruction says to, import the stack:
77
+
78
+ 1. `gh stack checkout <stack-number>`, with the number from `pulls/<N>.stack.number`. It records
79
+ the stack and checks out the top-most unmerged layer. When the worktree already tracks a
80
+ matching stack it only switches branches, so remote-tracking refs can be stale.
81
+ 2. Resolve the remote gh-stack uses once (`remote.pushDefault` when set, else the only remote,
82
+ else `origin`), and read `origin` below as that remote.
83
+ 3. gh-stack keeps existing local layer branches as they are, so a stale one makes the next rebase
84
+ start from stale commits. Run `git fetch origin`, then for each unmerged layer branch `<b>` run
85
+ `git rev-list --left-right --count "$b...origin/$b"` (left: local-only commits; right: commits
86
+ only on the pull request head). Branch names may contain shell metacharacters: pass each as a
87
+ quoted variable, never paste it into a command line, and skip names that start with `-`:
88
+ - `0 0`: up to date.
89
+ - `0 N`: fast-forward. Use `git merge --ff-only origin/<b>` on the checked-out layer and
90
+ `git branch -f <b> origin/<b>` on any other.
91
+ - A left count above `0` (ahead or diverged): inspect before rewriting or pushing, as the
92
+ consumer's git procedure describes. Do not open another pull request for the layer.
93
+
94
+ ## Submit and verify the remote stack
95
+
96
+ - A pull request's base branch selects its comparison target. Chaining bases alone does not
97
+ register a native stack. `gh stack init` and `add` record a local plan. Neither local tracking
98
+ nor a successful pull request creation proves GitHub registered the stack.
99
+ - Once an upper layer has committed, reviewable work and its local checks pass, submit the layers
100
+ as drafts with `gh stack submit --auto` while the lower pull request is still open and unqueued.
101
+ - Verify remote registration before asking to merge or enqueue the lower pull request. An open
102
+ pull request already in a merge queue cannot join a new stack. If it was queued externally, stop
103
+ registering and report the blocker. Do not dequeue it without authorization or rewrite it. When
104
+ it leaves the queue, re-read it: retry registration if it is still open and unqueued, or recover
105
+ as below if it merged. If it closed without merging, report the broken dependency.
106
+ - Do not wait for upper-layer CI or ready status to register the dependency. Do not create empty
107
+ placeholder layers, or start work held for approval, only to preserve a stack.
108
+ - After each submission or link, read every intended pull request's `pulls/<N>.stack` and the
109
+ single-stack endpoint. Require the same stack number, the intended bottom-to-top order, and the
110
+ expected bases. Missing preview metadata leaves membership unknown: report that, and do not infer
111
+ success from local tracking.
112
+ - If the lower pull request merges before registration, GitHub can reject linking it. Re-read the
113
+ forge, fetch, and rebase the remaining work onto the updated default branch without replaying
114
+ the merged layer. Keep any upper pull request already created. Register several remaining open
115
+ layers as a stack and verify their bases. For a single survivor, read its remote base, retarget
116
+ it to the default branch if needed, and verify that before shepherding it alone: a head rebase
117
+ does not change a base. Report sequential pull requests when no stack registered. Do not recreate
118
+ the merged bottom or chain bases by hand as a substitute.
119
+
120
+ ## Lower-layer review fix
121
+
122
+ Check out the layer that owns the change and commit there. Then run `gh stack rebase --upstack`
123
+ and `gh stack push` once. Do not duplicate the fix in an upper layer.
124
+
125
+ ## The forge is the only truth
126
+
127
+ Every fact the procedure branches on (topology, layer state, ownership, head SHA) comes from the
128
+ REST or GraphQL API, never from local gh-stack metadata. A local base ref can go stale after a
129
+ remote relink or rebase and silently replay already-landed commits. `gh stack view --json` also
130
+ errors from a worktree whose current branch is not in the stack, which is normal right after a
131
+ merge retargets it.
132
+
133
+ ```bash
134
+ gh api "repos/{owner}/{repo}/pulls/<N>" --jq '{stackPresent: has("stack"), stack: .stack}'
135
+ gh api "repos/{owner}/{repo}/stacks/<n>" # layers bottom to top, with head.sha and author
136
+ gh api --paginate "repos/{owner}/{repo}/stacks" --jq '.[] | select(.open)' # state is null
137
+ # and ?state=open is ignored
138
+ ```
139
+
140
+ - Use the single-stack endpoint for one stack's layers. The list form returns each layer's
141
+ `base.ref` as `null`.
142
+ - `.stack` is a preview field. Its absence is not proof a pull request is unstacked: report "stack
143
+ membership unknown" instead of assuming it is unstacked.