@catalyst-cloud/cli 0.9.5 → 0.13.1
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/CHANGELOG.md +28 -0
- package/README.md +28 -29
- package/dist/args.js +19 -1
- package/dist/ask.js +30 -18
- package/dist/capabilities.js +5 -0
- package/dist/cli.js +24 -6
- package/dist/env/declaration-rules.js +163 -0
- package/dist/env/group.js +51 -0
- package/dist/env/inventory.js +102 -0
- package/dist/env/render.js +39 -0
- package/dist/env/scan-env-example.js +62 -0
- package/dist/env/scan-source.js +43 -0
- package/dist/env/scan-workflow.js +123 -0
- package/dist/env/scan-wrangler.js +120 -0
- package/dist/env/types.js +1 -0
- package/dist/env/walk.js +87 -0
- package/dist/env.js +76 -0
- package/dist/environment.js +1 -1
- package/dist/legacy.js +224 -0
- package/dist/project.js +129 -0
- package/dist/release.js +1 -1
- package/dist/repo.js +297 -0
- package/dist/runtime-verb.js +1 -1
- package/dist/secret.js +1 -1
- package/dist/skill-shape.js +21 -13
- package/dist/skills.js +44 -4
- package/dist/transport.js +26 -1
- package/package.json +7 -6
- package/skills/catalyst-github/SKILL.md +7 -7
- package/skills/catalyst-github/references/is-it-mergeable.md +8 -2
- package/skills/catalyst-github/references/what-a-pr-accumulates.md +3 -3
- package/skills/catalyst-github/scripts/is-it-mergeable.mjs +3 -3
- package/skills/catalyst-github/scripts/lib/cli.mjs +9 -7
- package/skills/catalyst-github/scripts/lib/credential.mjs +2 -2
- package/skills/catalyst-github/scripts/read-pr.mjs +2 -2
- package/skills/catalyst-linear/SKILL.md +17 -19
- package/skills/catalyst-linear/agents/openai.yaml +1 -1
- package/skills/catalyst-linear/agents/portability.yaml +1 -1
- package/skills/catalyst-linear/references/reading-a-ticket.md +9 -26
- package/skills/catalyst-linear/references/what-a-ticket-accumulates.md +2 -2
- package/skills/catalyst-linear/references/writing-to-linear.md +7 -9
- package/skills/catalyst-linear/scripts/comment.mjs +1 -1
- package/skills/catalyst-linear/scripts/create-ticket.mjs +1 -1
- package/skills/catalyst-linear/scripts/label.mjs +1 -1
- package/skills/catalyst-linear/scripts/lib/cli.mjs +9 -7
- package/skills/catalyst-linear/scripts/lib/credential.mjs +2 -2
- package/skills/catalyst-linear/scripts/move.mjs +1 -1
- package/skills/catalyst-linear/scripts/read-ticket.mjs +1 -1
- package/skills/catalyst-linear/scripts/search.mjs +1 -1
- package/skills/catalyst-onboard/SKILL.md +37 -57
- package/skills/catalyst-onboard/agents/openai.yaml +2 -2
- package/skills/catalyst-onboard/agents/portability.yaml +1 -1
- package/skills/catalyst-onboard/references/connecting-this-machine.md +35 -0
- package/skills/catalyst-onboard/references/declaring-a-repository.md +7 -17
- package/skills/catalyst-onboard/references/local-sync.md +19 -7
- package/skills/catalyst-onboard/references/reading-ready.md +79 -0
- package/skills/catalyst-onboard/references/replacing-a-credential.md +8 -33
- package/skills/catalyst-onboard/references/repository-agent-setup.md +23 -0
- package/skills/catalyst-onboard/references/skill-sources.md +13 -19
- package/skills/catalyst-onboard/references/the-one-path.md +18 -74
- package/skills/catalyst-onboard/references/what-a-phase-needs.md +21 -28
- package/skills/catalyst-onboard/references/what-the-browser-owns.md +20 -37
- package/skills/{catalyst-setup → catalyst-onboard}/scripts/check.mjs +10 -9
- package/skills/catalyst-onboard/scripts/lib/cli.mjs +6 -4
- package/skills/catalyst-onboard/scripts/lib/credential.mjs +2 -2
- package/skills/catalyst-onboard/scripts/where-am-i.mjs +60 -4
- package/skills/run-this-project/SKILL.md +23 -25
- package/skills/run-this-project/agents/openai.yaml +1 -1
- package/skills/run-this-project/agents/portability.yaml +1 -1
- package/skills/run-this-project/references/making-work-ready.md +20 -37
- package/skills/run-this-project/references/reacting-to-events.md +25 -48
- package/skills/run-this-project/references/stalls-and-escalation.md +20 -42
- package/skills/run-this-project/scripts/lib/cli.mjs +7 -5
- package/skills/run-this-project/scripts/lib/credential.mjs +2 -2
- package/skills/run-this-project/scripts/scope-status.mjs +0 -0
- package/skills/run-this-project/scripts/watch-scope.mjs +1 -1
- package/skills/unstick/SKILL.md +12 -12
- package/skills/unstick/agents/openai.yaml +1 -1
- package/skills/unstick/agents/portability.yaml +1 -1
- package/skills/unstick/references/playbook.md +13 -13
- package/skills/unstick/scripts/lib/cli.mjs +6 -4
- package/skills/unstick/scripts/lib/credential.mjs +2 -2
- package/skills/unstick/scripts/unstick.mjs +1 -1
- package/skills/what-needs-me/SKILL.md +12 -14
- package/skills/what-needs-me/agents/openai.yaml +2 -2
- package/skills/what-needs-me/agents/portability.yaml +1 -1
- package/skills/what-needs-me/references/raising-a-decision.md +8 -16
- package/skills/what-needs-me/references/reading-the-inbox.md +9 -12
- package/skills/what-needs-me/references/settling-an-answer.md +6 -12
- package/skills/what-needs-me/scripts/inbox.mjs +14 -13
- package/skills/what-needs-me/scripts/lib/cli.mjs +6 -4
- package/skills/what-needs-me/scripts/lib/credential.mjs +2 -2
- package/skills/what-needs-me/scripts/raise.mjs +1 -1
- package/skills/what-needs-me/scripts/settle.mjs +1 -1
- package/skills/what-this-repo-needs/SKILL.md +31 -0
- package/skills/what-this-repo-needs/agents/openai.yaml +6 -0
- package/skills/what-this-repo-needs/agents/portability.yaml +4 -0
- package/skills/what-this-repo-needs/references/what-each-group-means.md +38 -0
- package/skills/what-this-repo-needs/scripts/check.mjs +64 -0
- package/skills/what-this-repo-needs/scripts/inventory.mjs +61 -0
- package/skills/{catalyst-setup → what-this-repo-needs}/scripts/lib/cli.mjs +35 -22
- package/skills/{catalyst-setup → what-this-repo-needs}/scripts/lib/credential.mjs +2 -2
- package/skills/whats-happening/SKILL.md +27 -21
- package/skills/whats-happening/agents/openai.yaml +1 -1
- package/skills/whats-happening/references/coding-accounts.md +24 -0
- package/skills/whats-happening/references/routing-work.md +11 -29
- package/skills/whats-happening/references/settings-and-where-they-live.md +20 -0
- package/skills/whats-happening/references/stages-and-mapping.md +25 -0
- package/skills/whats-happening/references/status-reply.md +21 -21
- package/skills/whats-happening/references/the-ladder.md +30 -0
- package/skills/whats-happening/references/what-runs-next.md +32 -0
- package/skills/whats-happening/references/when-a-phase-fails.md +27 -0
- package/skills/whats-happening/references/why-is-it-stuck.md +33 -40
- package/skills/whats-happening/scripts/explain.mjs +1 -1
- package/skills/whats-happening/scripts/lib/cli.mjs +7 -5
- package/skills/whats-happening/scripts/lib/credential.mjs +2 -2
- package/skills/{how-catalyst-works → whats-happening}/scripts/show-my-map.mjs +18 -32
- package/skills/whats-happening/scripts/snapshot.mjs +10 -6
- package/skills/catalyst-onboard/references/choosing-a-coding-account.md +0 -52
- package/skills/catalyst-onboard/references/who-fixes-what.md +0 -64
- package/skills/catalyst-setup/SKILL.md +0 -36
- package/skills/catalyst-setup/agents/openai.yaml +0 -6
- package/skills/catalyst-setup/agents/portability.yaml +0 -4
- package/skills/catalyst-setup/references/what-each-check-means.md +0 -88
- package/skills/catalyst-setup/scripts/replica-status.mjs +0 -46
- package/skills/connect-me/SKILL.md +0 -63
- package/skills/connect-me/agents/openai.yaml +0 -6
- package/skills/connect-me/agents/portability.yaml +0 -5
- package/skills/connect-me/references/keeping-the-replica-running.md +0 -88
- package/skills/connect-me/scripts/lib/cli.mjs +0 -185
- package/skills/connect-me/scripts/lib/credential.mjs +0 -29
- package/skills/connect-me/scripts/verify-connection.mjs +0 -68
- package/skills/how-catalyst-works/SKILL.md +0 -43
- package/skills/how-catalyst-works/agents/openai.yaml +0 -6
- package/skills/how-catalyst-works/agents/portability.yaml +0 -4
- package/skills/how-catalyst-works/references/coding-accounts.md +0 -51
- package/skills/how-catalyst-works/references/stages-and-mapping.md +0 -56
- package/skills/how-catalyst-works/references/the-ladder.md +0 -41
- package/skills/how-catalyst-works/references/what-catalyst-is.md +0 -30
- package/skills/how-catalyst-works/references/what-runs-next.md +0 -88
- package/skills/how-catalyst-works/references/when-a-phase-fails.md +0 -57
- package/skills/how-catalyst-works/scripts/explain-ticket.mjs +0 -41
- package/skills/how-catalyst-works/scripts/lib/cli.mjs +0 -164
- package/skills/how-catalyst-works/scripts/lib/credential.mjs +0 -29
- package/skills/how-catalyst-works/scripts/whats-running.mjs +0 -65
- package/skills/whats-happening/references/reading-the-board.md +0 -43
- package/skills/whats-happening/references/reprioritising.md +0 -37
|
@@ -1,45 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: run-this-project
|
|
3
3
|
description: >-
|
|
4
|
-
Own one Catalyst Cloud project end to end until it closes. Use when the person says "run this project for me", "own this until it ships", "keep this moving", or hands you a project id or a set of tickets to drive. Subscribes to the
|
|
5
|
-
|
|
6
|
-
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
4
|
+
Own one Catalyst Cloud project end to end until it closes. Use when the person says "run this project for me", "own this until it ships", "keep this moving", or hands you a project id or a set of tickets to drive. Subscribes to the account's event stream for the scope through the catalyst CLI, reacts to each change in the same turn, makes tickets ready and moves them to dispatch, parks what should stop, chases stalls, escalates inward, and keeps one status summary current. Writes to Linear as the app actor; never polls.
|
|
5
|
+
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
7
6
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.13.1 — written in this repository for customer accounts -->
|
|
9
8
|
|
|
10
9
|
# Run this project
|
|
11
10
|
|
|
12
|
-
You are the steward: the single-threaded owner of ONE project or ticket set
|
|
11
|
+
You are the steward: the single-threaded owner of ONE project or ticket set until it closes. Catalyst runs the phases; you make work ready and visible, react to what happens, unblock, and keep one status summary the person can read. `whats-happening` is the desk; other stewards are peers.
|
|
13
12
|
|
|
14
13
|
## Run first
|
|
15
14
|
|
|
16
|
-
Scripts are run, never read. Each prints its own
|
|
15
|
+
Scripts are run, never read. Each prints `--help`, and exits 2 when this machine is not connected (`catalyst login`), 1 when its own check fails.
|
|
17
16
|
|
|
18
|
-
1. `node scripts/scope-status.mjs --project <id>` (or `--team <key>`): tickets by stage
|
|
19
|
-
2. `node scripts/watch-scope.mjs --project <id>`: the subscription. In Claude Code, arm a monitor on it and react to each printed line in the same turn
|
|
20
|
-
3. `node scripts/make-ready.mjs <ticket>`
|
|
21
|
-
4. `catalyst
|
|
22
|
-
|
|
23
|
-
Every script exits 2 when this machine is not connected (run `catalyst-skills login`), 1 when its own check fails.
|
|
17
|
+
1. `node scripts/scope-status.mjs --project <id>` (or `--team <key>`): tickets by stage, what is running and queued in scope, and stalls against the local policy. Run it to take the scope, and again after a resync.
|
|
18
|
+
2. `node scripts/watch-scope.mjs --project <id>`: the subscription. In Claude Code, arm a monitor on it and react to each printed line in the same turn; elsewhere add `--exec <command>` so a reaction runs per frame.
|
|
19
|
+
3. `node scripts/make-ready.mjs <ticket>` dispatches; `--park` stops; `--note <why>` records it.
|
|
20
|
+
4. `catalyst explain <ticket>` whenever a ticket is not moving.
|
|
24
21
|
|
|
25
22
|
## Load on demand
|
|
26
23
|
|
|
27
24
|
| when | read |
|
|
28
25
|
| -- | -- |
|
|
29
|
-
| arming the watch,
|
|
30
|
-
| dispatching or parking
|
|
31
|
-
| something is not moving, tuning the stall policy,
|
|
32
|
-
|
|
|
26
|
+
| arming the watch, reading a frame, a failed reaction, a resync | `references/reacting-to-events.md` |
|
|
27
|
+
| dispatching or parking, judging whether a phase ran, writing a ticket for Catalyst | `references/making-work-ready.md` |
|
|
28
|
+
| something is not moving, tuning the stall policy, whether a human needs to hear | `references/stalls-and-escalation.md` |
|
|
29
|
+
| what an exclusion reason means, the ladder, the stage map | the `whats-happening` skill |
|
|
33
30
|
| raising or settling a decision | the `what-needs-me` skill |
|
|
34
|
-
| a PR's checks, review and merge
|
|
31
|
+
| a PR's checks, review and merge | the `catalyst-github` skill |
|
|
35
32
|
|
|
36
33
|
## Rules
|
|
37
34
|
|
|
38
|
-
- **React
|
|
39
|
-
- **Dispatch is a card move.**
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **Escalate inward
|
|
43
|
-
- **
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
35
|
+
- **React to the stream.** The watch and its cursor file are the mechanism, and a reaction that throws leaves the cursor so the frame is offered again. Re-reading the API or the replica in a loop is a defect.
|
|
36
|
+
- **Dispatch is a card move.** Your two moves are into dispatch and into the backlog; the cloud writes every ladder stage itself.
|
|
37
|
+
- **A phase ran when its outcome comment, attached document and agent session say so,** not when the clock or the column suggests it.
|
|
38
|
+
- **Account facts come from the contract, live** (`catalyst contract --path <a.b.c>`), never from prose.
|
|
39
|
+
- **Escalate inward:** instrument, you, the desk, then the human as an ask through `what-needs-me` naming what it blocks. Decide technical calls yourself and record the default; a fleet or provider condition is one note, never one ask per ticket.
|
|
40
|
+
- **Say what a write costs.** Every move and comment spends the contract's daily write budget as the app actor, and a move into dispatch starts paid work on a coding account. Read the verdict `make-ready.mjs` prints before the next move.
|
|
41
|
+
- **Reply where the message arrived,** in-thread, tagged, as the app actor. The human speaks for themselves, and each ask belongs to its own addressee. Bookkeeping records take the contract's marker (`catalyst write comment --bookkeeping`).
|
|
42
|
+
- **One status summary,** current after every reaction: in flight, blocked and on whom, closed, next, each line with a ticket id, and a pending decision's line with its ask id.
|
|
43
|
+
- **Releases belong to `unstick`.** Once the cause is fixed, the person's own login releases a park or most holds through the `unstick` skill (`catalyst release`); a round-threshold hold and a review that will not converge refuse it. PR labels and reactions are not mirrored; execution history (`explain --history`) and coding accounts (`catalyst accounts`) are readable.
|
|
@@ -3,4 +3,4 @@ interface:
|
|
|
3
3
|
short_description: "Own one Catalyst project end to end: react to its events, make tickets ready, chase stalls, escalate inward"
|
|
4
4
|
default_prompt: "Use $run-this-project to run project <id> for me until it closes."
|
|
5
5
|
policy:
|
|
6
|
-
allow_implicit_invocation:
|
|
6
|
+
allow_implicit_invocation: true
|
|
@@ -1,60 +1,43 @@
|
|
|
1
1
|
# Making work ready
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## The steward's two moves
|
|
6
|
-
|
|
7
|
-
Catalyst does not take work by being asked. It takes work by finding a card in the team's dispatch column and offering that card's next phase to a runner. So the steward's dispatch verb is a card move, and its stop verb is a card move:
|
|
3
|
+
Catalyst takes work by finding a card in the team's dispatch column and offering its next phase to a runner. So the steward's dispatch and stop verbs are both card moves:
|
|
8
4
|
|
|
9
5
|
```sh
|
|
10
|
-
node scripts/make-ready.mjs ENG-41 #
|
|
11
|
-
node scripts/make-ready.mjs ENG-41 --park #
|
|
6
|
+
node scripts/make-ready.mjs ENG-41 # into the dispatch column
|
|
7
|
+
node scripts/make-ready.mjs ENG-41 --park # into the team's backlog-type state
|
|
12
8
|
node scripts/make-ready.mjs ENG-41 --park --note "waiting on the vendor's API change"
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
Dispatch resolves the dispatch slot
|
|
11
|
+
Dispatch resolves the team's dispatch slot from the contract; parking resolves the team's first backlog-type state from its live workflow, since the backlog is not a slot. Every other stage on a ticket in the ladder is the cloud's record of what ran: a hand move forward runs nothing, and a hand move back undoes nothing.
|
|
16
12
|
|
|
17
13
|
## What a dispatchable ticket carries
|
|
18
14
|
|
|
19
|
-
|
|
15
|
+
A phase agent reads the ticket, not your chat. Read it in full, then check it has:
|
|
20
16
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- No ask on it. A ticket that carries the ask label, or whose own text reads as a decision request (an ask-shaped title, lettered options, a "default if silent" line), is excluded as a question rather than work. If a real ticket trips the shape detector, a human applies the release label named in the contract's vocabulary; you can also rewrite the text so it reads as work.
|
|
27
|
-
- Declared scope when the team enforces it: a ticket whose declared files overlap a ticket already in flight is held as `scope_overlap` for the implement phase.
|
|
17
|
+
- a title stating the outcome, and a description of what done looks like (behaviour, constraints, files or surfaces, acceptance criteria validate can check);
|
|
18
|
+
- the right team (the prefix; its stage map and labels are what the cloud uses) and a priority (unset sorts last);
|
|
19
|
+
- no live blocking relation, which excludes it as `blocked`;
|
|
20
|
+
- no ask: an ask label, or text that reads as a decision request, excludes it as a question. A human applies the contract's release label to a false positive; you can rewrite the text so it reads as work;
|
|
21
|
+
- declared scope when the team enforces it, and no file overlap with a ticket in flight (`scope_overlap`). Serialise two tickets that touch the same files.
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
It needs no branch, PR or artifact; the ladder makes those, starting at intake when the account has it on, else research.
|
|
30
24
|
|
|
31
25
|
## After the move
|
|
32
26
|
|
|
33
|
-
`make-ready.mjs`
|
|
34
|
-
|
|
35
|
-
- `offered` or `eligible` with a queue position: done; a runner will pick it up in the next dispatch pass, ordered by priority, then age, then identifier, with tickets already mid-ladder ahead of fresh ones.
|
|
36
|
-
- An ordering that is stale or never published: the cloud re-derives the team's queue within a pass of the move; ask again in a minute with `catalyst-skills explain <ticket>`.
|
|
37
|
-
- Any other exclusion reason: the paragraph names it and what releases it. The reasons and what unblocks each are in `how-catalyst-works` and in `whats-happening`'s "why is it stuck" reference.
|
|
27
|
+
`make-ready.mjs` prints the explainer's verdict. A queue position means a runner will pick it up in order. A stale or unpublished ordering is re-derived within a pass; ask again in a minute with `catalyst explain <ticket>`. Any other reason is in the `whats-happening` skill's `references/why-is-it-stuck.md`.
|
|
38
28
|
|
|
39
29
|
## Evidence a phase ran
|
|
40
30
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
1. **The outcome comment.** The cloud posts a card per phase: a completed phase names the phase, the attempt, and its artifact; a failed phase names the phase, the attempt, and the failure class, and may carry a park or hold block. A remediate round posts its own attempt card with the round number and the class it is repairing. These arrive as comment frames on the watch.
|
|
44
|
-
2. **The attachment and document.** Each artifact-bearing phase (research, plan, implement, validate, pr, remediate) is projected to a Linear document titled with the ticket, the phase, the attempt and the date, attached to the ticket, with a short link comment. Research and plan on a ticket with a project also appear as a project link.
|
|
45
|
-
3. **The agent session.** The ticket's agent session carries the ladder as its plan, with the phases before the current one completed, the current one in progress, and the rest pending; its activities are the phase start, the gate, artifacts written, the PR opened, and the report.
|
|
46
|
-
|
|
47
|
-
The card's stage is the fourth, weakest signal: a completed phase moves the card to the stage the advance table names, a failed phase writes no stage at all, and Done is written only when the pull request actually merges, by the merge webhook, never by a phase. A card sitting in a stage tells you which phase last finished, not whether the next one is running; `scripts/scope-status.mjs` shows running and leased phases beside the stage for exactly that reason.
|
|
31
|
+
Time passing proves nothing. A phase leaves three kinds of evidence on the ticket:
|
|
48
32
|
|
|
49
|
-
|
|
33
|
+
1. **The outcome comment.** Per phase: the phase, the attempt, and its artifact, or on failure the failure class and any park or hold block. A remediate round posts its own card with the round number. These arrive as comment frames.
|
|
34
|
+
2. **The document.** Each artifact-bearing phase attaches a Linear document with a short link comment.
|
|
35
|
+
3. **The agent session.** Its plan is the ladder, with the current phase in progress; its activities are the phase start, the gate, the artifacts, the PR, and the report.
|
|
50
36
|
|
|
51
|
-
|
|
37
|
+
The card's stage is the weakest signal: a completed phase moves it, a failed one writes nothing, and Done is written only when the pull request merges. `scope-status.mjs` shows running and leased phases beside each stage for that reason.
|
|
52
38
|
|
|
53
|
-
|
|
39
|
+
## Parking
|
|
54
40
|
|
|
55
|
-
|
|
41
|
+
Parking stops the cloud offering further rounds: the card is excluded at the next offer. A phase already running under a lease finishes and posts its outcome first. Un-parking is the dispatch move again, and counted attempts and rounds carry over. A cloud park (three consecutive failures, or the round cap) is not a card move: once its cause is fixed, the `unstick` skill releases it with `catalyst release <ticket>`, and only a refusal that names a person's action becomes an ask. When you park a ticket the cloud already parked, record why in a bookkeeping note.
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
- Never remove an ask label or apply the release label yourself; a human decides whether a ticket is a question.
|
|
59
|
-
- Never dispatch two tickets that touch the same files at once; serialise them or let the second one wait as `scope_overlap`.
|
|
60
|
-
- Never dispatch a ticket you have not read in full.
|
|
43
|
+
Ask labels and the release label are a human's call; leave them as you find them.
|
|
@@ -1,76 +1,53 @@
|
|
|
1
1
|
# Reacting to events
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## The mechanism
|
|
6
|
-
|
|
7
|
-
A steward never polls. It subscribes once to the tenant stream through the SDK's live client and reacts to each change as it arrives. The verb is `catalyst-skills watch`, and this skill's `scripts/watch-scope.mjs` is that verb with the scope checked up front:
|
|
3
|
+
A steward subscribes once to the account's event stream and reacts to each change as it arrives. The verb is `catalyst watch`; `scripts/watch-scope.mjs` is that verb with the scope checked up front:
|
|
8
4
|
|
|
9
5
|
```sh
|
|
10
|
-
node scripts/watch-scope.mjs --project <id>
|
|
11
|
-
node scripts/watch-scope.mjs --team <key>
|
|
6
|
+
node scripts/watch-scope.mjs --project <id>
|
|
7
|
+
node scripts/watch-scope.mjs --team <key>
|
|
12
8
|
node scripts/watch-scope.mjs --ticket ENG-41 --ticket ENG-42
|
|
9
|
+
node scripts/watch-scope.mjs --project <id> --exec 'node my-reaction.mjs' # a harness with no monitor
|
|
13
10
|
```
|
|
14
11
|
|
|
15
|
-
The stream
|
|
16
|
-
|
|
17
|
-
**In Claude Code**, arm a monitor on the command above. Each line it prints is one applied change inside the scope, delivered into your session as an event. React to it in the same turn: read what changed, decide, act, and only then let the turn end.
|
|
18
|
-
|
|
19
|
-
**In Codex, OpenCode, or any harness without a monitor**, pass `--exec`:
|
|
20
|
-
|
|
21
|
-
```sh
|
|
22
|
-
node scripts/watch-scope.mjs --project <id> --exec 'node my-reaction.mjs'
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The command runs once per frame with the frame on stdin. A non-zero exit is a failed reaction (see the cursor rule). Nothing polls in either shape.
|
|
12
|
+
The stream is account-wide and scope is filtered on this machine, resolving comments, sessions and pull requests to their ticket's project; an ignored frame costs one JSON parse, so a wide scope is fine. In Claude Code, a monitor on the command delivers each printed line into your session. With `--exec`, the command runs once per frame with the frame on stdin, and a non-zero exit is a failed reaction.
|
|
26
13
|
|
|
27
14
|
## The frame
|
|
28
15
|
|
|
29
|
-
One JSON object per line,
|
|
16
|
+
One JSON object per line, as the SDK delivers it:
|
|
30
17
|
|
|
31
18
|
```json
|
|
32
|
-
{"type":"change","accountId":"<
|
|
19
|
+
{"type":"change","accountId":"<account>","seq":4182,"entity":"comments","entityId":"<id>","op":"upsert","row":{...}}
|
|
33
20
|
```
|
|
34
21
|
|
|
35
|
-
`seq` is the
|
|
22
|
+
`seq` is the account-wide position, `entity` a feed table, `op` is `upsert` (with the row) or `delete` (the id only).
|
|
36
23
|
|
|
37
24
|
## Entities that matter to a scope
|
|
38
25
|
|
|
39
26
|
| entity | what a change means | first reaction |
|
|
40
27
|
| -- | -- | -- |
|
|
41
|
-
| `issues` | a card moved, was
|
|
42
|
-
| `comments` | someone or something wrote on a ticket | a human comment in
|
|
43
|
-
| `issue_labels`, `labels` | a label
|
|
44
|
-
| `relations` | a
|
|
45
|
-
| `pull_requests`, `pr_events`, `pushes` | the branch
|
|
46
|
-
| `check_runs`, `check_suites`, `commit_statuses` | CI moved | red
|
|
47
|
-
| `reviews`, `pr_review_threads`, `pr_review_comments` | the reviewer spoke | unresolved threads block the merge; a clean pass is a reaction or a terse comment
|
|
48
|
-
| `agent_sessions`, `agent_activities` | a phase started, wrote
|
|
49
|
-
| `fleet_activity`, `fleet_host_liveness` | a runner picked up or dropped a phase | a phase
|
|
50
|
-
| `fleet_anomalies` |
|
|
51
|
-
| `workflow_states`, `team_workflow_mapping` | the
|
|
52
|
-
| `projects`, `cycles`, `initiatives` |
|
|
53
|
-
|
|
54
|
-
Entities not listed still arrive when they are in scope; ignore what you do not need.
|
|
28
|
+
| `issues` | a card moved, was edited, re-prioritised, assigned or created | a move into a cloud-owned stage is an advance; a hand move out of the ladder, ask why before touching it |
|
|
29
|
+
| `comments` | someone or something wrote on a ticket | answer a human comment in-thread, tagged; read a cloud outcome card (phase complete or failed, remediate attempt, board health, merge wait) as your execution signal |
|
|
30
|
+
| `issue_labels`, `labels` | a label changed | an ask label means a question; a hold label means the cloud wants a human; the release label means a human cleared a false positive |
|
|
31
|
+
| `relations` | a blocker appeared or went away | chase a new blocker; a closed one may make a card dispatchable |
|
|
32
|
+
| `pull_requests`, `pr_events`, `pushes` | the branch or PR changed | ready-for-review and merged are milestones; a force-push after a resolved thread is worth a look |
|
|
33
|
+
| `check_runs`, `check_suites`, `commit_statuses` | CI moved | a red required check after the queue label wakes an automatic remediation; watch it |
|
|
34
|
+
| `reviews`, `pr_review_threads`, `pr_review_comments` | the reviewer spoke | unresolved threads block the merge; a clean pass is a reaction or a terse comment |
|
|
35
|
+
| `agent_sessions`, `agent_activities` | a phase started, wrote, opened a PR, reported | the session's plan is the ladder |
|
|
36
|
+
| `fleet_activity`, `fleet_host_liveness` | a runner picked up or dropped a phase | a running phase is not a stall |
|
|
37
|
+
| `fleet_anomalies` | a fleet-level alert | one alert covers every ticket it touches |
|
|
38
|
+
| `workflow_states`, `team_workflow_mapping` | the stage map changed | `catalyst contract --refresh` before the next move |
|
|
39
|
+
| `projects`, `cycles`, `initiatives` | the scope's container changed | update the summary |
|
|
55
40
|
|
|
56
41
|
## The same-turn rule
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
## The cursor rule
|
|
61
|
-
|
|
62
|
-
The cursor file (`~/.config/catalyst-cloud/watch-cursor.json`, stamped with the tenant) advances only after the reaction returns. A reaction that throws, or an `--exec` command that exits non-zero, leaves the cursor at the last good frame; the CLI closes the socket and the SDK's reconnect replays from that cursor, so the failed frame is offered again. Delivery is therefore at-least-once: make reactions safe to repeat (check before you write, prefer idempotent writes such as a label add over a fresh comment).
|
|
63
|
-
|
|
64
|
-
Two consequences. First, a crash mid-reaction replays, never loses. Second, a reaction that keeps failing keeps the watch pinned on one frame; fix the reaction rather than skipping the frame, or restart with `--from head` and re-read the scope with `scripts/scope-status.mjs` to catch up on what you missed.
|
|
65
|
-
|
|
66
|
-
## What to do on resync
|
|
43
|
+
React to a frame in the turn it arrives, and end the turn with the status summary current. A reaction that needs a human decision files the ask through `what-needs-me` in that same turn, before proceeding on the default.
|
|
67
44
|
|
|
68
|
-
|
|
45
|
+
## The cursor
|
|
69
46
|
|
|
70
|
-
|
|
47
|
+
The cursor file (`~/.config/catalyst-cloud/watch-cursor.json`) advances only after a reaction returns. A reaction that throws, or an `--exec` that exits non-zero, leaves it at the last good frame, and the reconnect replays from there. Delivery is at-least-once, so make reactions safe to repeat: check before writing, and prefer idempotent writes such as a label add. A reaction that keeps failing pins the watch on one frame; fix the reaction, or restart with `--from head` and re-read the scope with `scripts/scope-status.mjs`.
|
|
71
48
|
|
|
72
|
-
|
|
49
|
+
A resync prints `[watch] resync: cursor moved to head <n>` on standard error and continues from the head without replaying the gap: run `scripts/scope-status.mjs` once and reconcile. Start with `--from head` when taking over a project that ran without a steward; resume from the saved cursor (the default) after your own break.
|
|
73
50
|
|
|
74
51
|
## The honest limit
|
|
75
52
|
|
|
76
|
-
The stream carries the mirror's entity changes
|
|
53
|
+
The stream carries the mirror's entity changes, not the relay ledger's failures, parks, rounds or backoff timers as frames. Those arrive as the cloud's outcome comments, and `catalyst explain <ticket>` gives the current verdict; `--history` adds the attempts, rounds against the cap, and any park with what releases it.
|
|
@@ -1,63 +1,41 @@
|
|
|
1
1
|
# Stalls and escalation
|
|
2
2
|
|
|
3
|
-
The stall thresholds
|
|
3
|
+
The stall thresholds are **local judgment**, set once by the project's owner and read by `scripts/scope-status.mjs`. The cloud publishes no stall policy and enforces none of these numbers; what it does about a failing ticket is in the contract's `thresholds`.
|
|
4
4
|
|
|
5
5
|
## The policy file
|
|
6
6
|
|
|
7
|
-
`assets/stall-policy.json` ships the defaults: minutes a ticket may sit in each slot with no update and nothing running or leased
|
|
8
|
-
|
|
9
|
-
Two slots deserve thought when tuning. The dispatch slot's threshold is how long a card may wait to be picked up before you ask why nothing took it; on a busy tenant with a full queue that is capacity, not a stall, and the answer is to wait or re-prioritise. The PR slot's threshold is how long a card may wait for merge evidence; reviews and CI take real time, so set it generously.
|
|
7
|
+
`assets/stall-policy.json` ships the defaults: minutes a ticket may sit in each slot, with no update and nothing running or leased, before it counts as stalled. To change them, copy it to `~/.config/catalyst-cloud/stall-policy.json` and edit the copy; the script prefers it and prints which file it used (`--stall-policy <file>` picks another). On a busy account a waiting dispatch card is capacity, not a stall, and reviews and CI take real time, so set the dispatch and PR thresholds generously.
|
|
10
8
|
|
|
11
9
|
## What counts as stuck
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
A running phase is never a stall, however long it has run; the cloud's own timeout will fail it and the outcome card will say so. A ticket in retry backoff is waiting out a rung of two, five or fifteen minutes and is not a stall either.
|
|
11
|
+
All at once: an active slot, nothing running or leased, a last update older than the slot's threshold, and an explainer reason that is not a clock. `scope-status.mjs` checks the first three and hands you the fourth as a command. A running phase is never a stall; its own timeout fails it and the outcome card says so.
|
|
16
12
|
|
|
17
13
|
## The chase order
|
|
18
14
|
|
|
19
|
-
Run `catalyst
|
|
20
|
-
|
|
21
|
-
| the explainer says | what it means | your move |
|
|
22
|
-
| -- | -- | -- |
|
|
23
|
-
| offered, with a position | the queue has it; a runner is the bottleneck | wait; if every ticket waits, it is capacity, see below |
|
|
24
|
-
| lease held, intake lease held | a container has it | not a stall; wait for the outcome card |
|
|
25
|
-
| retry backoff | a pre-branch or infrastructure failure is retrying in place | wait out the rung; three in a row parks it, and then it is a real stall |
|
|
26
|
-
| blocked | a live blocks relation | chase the blocker: is it dispatchable, is it an ask nobody answered, is it done but still open |
|
|
27
|
-
| ask ticket, ask shape suspected | the ticket is a question | route it to `what-needs-me`; if it is really work, a human applies the release label |
|
|
28
|
-
| not at dispatch stage | somebody moved the card, or it never entered | read the card's history; re-dispatch with `make-ready.mjs` if it should run |
|
|
29
|
-
| phase parked, cooling down, remediate parked | the cloud parked it after repeated failure or the round cap | read the last outcome card for the class; once its cause is fixed, the `unstick` skill releases it (`catalyst-skills release <ticket> --because <what changed>`); if the fix is a decision, file an ask |
|
|
30
|
-
| no change hold | a remediate round changed nothing | a human comment on the ticket, or a new push to the branch, releases it; say what should change |
|
|
31
|
-
| validate class spent, stale failure episode | the repair budget for this failure is used, or the ladder moved on | read the outcome cards; usually a decision about the approach, so an ask |
|
|
32
|
-
| waiting on | a merge-gate failure with no automatic repair | read the merge-wait comment and the PR's three legs through `catalyst-github` |
|
|
33
|
-
| branch missing, branch gone, no branch to remediate | the branch the phase needs does not exist | a hand-deleted branch is a human question; a never-created one means implement has not run, so check the earlier phases |
|
|
34
|
-
| environment check required, running, failed, expired, hash mismatch | the repository's environment gate | a repository setting; the tenant admin resolves it in settings, one ask for the repository, not per ticket |
|
|
35
|
-
| scope overlap | another in-flight ticket owns the files | wait for it, or re-order by priority |
|
|
36
|
-
| routing unavailable, no eligible slot, runner image breaker, repo paused | a fleet or provider condition | one fleet note, never per ticket; see below |
|
|
37
|
-
| pr merged, pipeline complete, ticket terminal | it is finished | close the loop in the summary; if the card is not Done a minute after the merge, that is a finding, not a chore |
|
|
38
|
-
|
|
39
|
-
Where the explainer names a reason not in this table, it prints the raw reason; read it as spelled and consult `how-catalyst-works`.
|
|
40
|
-
|
|
41
|
-
## Capacity and fleet conditions are one note, not many asks
|
|
15
|
+
Run `catalyst explain <ticket>` and look the reason up in the `whats-happening` skill's `references/why-is-it-stuck.md`. For you as the owner:
|
|
42
16
|
|
|
43
|
-
|
|
17
|
+
- **It releases itself:** wait for the outcome card.
|
|
18
|
+
- **The person, with their own login, acts:** do it when the move is yours (re-dispatch, a comment that clears a no-change or validate-budget hold, a question routed to `what-needs-me`), and file an ask when it is theirs.
|
|
19
|
+
- **A park or hold a release clears:** once its cause is fixed, the `unstick` skill releases it (`catalyst release <ticket> --because <what changed>`). A round-threshold hold and a review that will not converge refuse that release; the table says what clears each.
|
|
20
|
+
- **An owner or admin, in settings, or an operator:** one ask per repository or setting.
|
|
21
|
+
- **Finished:** close the loop in the summary.
|
|
44
22
|
|
|
45
|
-
|
|
23
|
+
Quote a reason the table does not know as the explainer spelled it.
|
|
46
24
|
|
|
47
|
-
|
|
25
|
+
## Shared causes are one note
|
|
48
26
|
|
|
49
|
-
|
|
27
|
+
When several tickets are offered and nothing takes them, or the explainer names a routing, slot, provider or image condition, the cause is shared (coding-account headroom, a provider outage, a paused repository, a bad runner image). Write one summary line naming the condition and the tickets it holds. `catalyst accounts` reads coding-account status; enrolling or pausing one is the settings page.
|
|
50
28
|
|
|
51
|
-
|
|
52
|
-
2. **Does this need to block at all?** If a sane default exists, take it, record it, and file the ask anyway so the human can overrule; the work does not wait.
|
|
53
|
-
3. **Who else can move this?** Another steward, the desk, a repository owner. Pulling in a peer is preferred over pulling in the human.
|
|
29
|
+
## Escalate inward
|
|
54
30
|
|
|
55
|
-
|
|
31
|
+
The order is instrument, you, the desk (`whats-happening`), then the human, who only ever sees an ask. Before anything reaches the human:
|
|
56
32
|
|
|
57
|
-
|
|
33
|
+
1. **Can I decide this myself?** Approach, retry or abandon, rebase or re-cut, ordering: yours. Decide, record it in a bookkeeping note, move on.
|
|
34
|
+
2. **Does it need to block?** With a sane default, take it, record it, and file the ask anyway so the human can overrule.
|
|
35
|
+
3. **Who else can move it?** A peer steward, the desk or a repository owner comes before the human.
|
|
58
36
|
|
|
59
|
-
|
|
37
|
+
What survives is a product, priority or approval decision, or an action only a human can take: close their own pull request, read a review that will not converge, change a repository setting, apply the release label, answer a merge-policy question.
|
|
60
38
|
|
|
61
|
-
##
|
|
39
|
+
## Filing the ask
|
|
62
40
|
|
|
63
|
-
|
|
41
|
+
File it through `what-needs-me`, as the app actor: the question as its title, the options, the default if silent, and the stalled ticket in its blocks list so the inbox ranks it by what it holds. Search for an existing ask on the same decision first and attach to it, because two asks split one decision's urgency. Then proceed on the default and say so on the ticket.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// lib/cli.mjs — the one way a skill script reaches Catalyst Cloud: by spawning the catalyst
|
|
2
|
+
// lib/cli.mjs — the one way a skill script reaches Catalyst Cloud: by spawning the catalyst
|
|
3
3
|
// CLI. The CLI holds the SDK and the key; this file holds neither. It reads
|
|
4
4
|
// ~/.config/catalyst-cloud/customer.json (under CATALYST_SKILLS_HOME when set, else HOME) for the
|
|
5
|
-
// CLI path that login recorded and falls back to `npx @catalyst-cloud/catalyst
|
|
5
|
+
// CLI path that login recorded and falls back to `npx -p @catalyst-cloud/cli catalyst`.
|
|
6
6
|
//
|
|
7
7
|
// Exit codes every script built on this file shares: 2 = this machine is not connected, 1 = the
|
|
8
8
|
// script's own check failed, 0 = fine.
|
|
@@ -12,7 +12,9 @@ import { join } from "node:path";
|
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
13
|
import { CONNECT_COMMAND, hasCredential } from "./credential.mjs";
|
|
14
14
|
|
|
15
|
-
export const PACKAGE_NAME = "@catalyst-cloud/
|
|
15
|
+
export const PACKAGE_NAME = "@catalyst-cloud/cli";
|
|
16
|
+
/** The package ships two commands, so npx needs the one to run named: `npx -p <package> catalyst`. */
|
|
17
|
+
export const NPX_ARGS = ["-p", PACKAGE_NAME, "catalyst"];
|
|
16
18
|
export const NOT_CONFIGURED_EXIT = 2;
|
|
17
19
|
export const CHECK_FAILED_EXIT = 1;
|
|
18
20
|
|
|
@@ -55,7 +57,7 @@ export function cliCommand(cfg = loadCustomerConfig()) {
|
|
|
55
57
|
return { command: process.execPath, prefix: [cfg.cliPath], via: `node ${cfg.cliPath}` };
|
|
56
58
|
}
|
|
57
59
|
const npx = process.platform === "win32" ? "npx.cmd" : "npx";
|
|
58
|
-
return { command: npx, prefix:
|
|
60
|
+
return { command: npx, prefix: NPX_ARGS, via: `npx -p ${PACKAGE_NAME} catalyst` };
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
/**
|
|
@@ -176,7 +178,7 @@ export function wantsHelp(argv) {
|
|
|
176
178
|
|
|
177
179
|
const HELP = `lib/cli.mjs — shared helper; not a command.
|
|
178
180
|
|
|
179
|
-
Resolves the catalyst
|
|
181
|
+
Resolves the catalyst CLI (the path login recorded in ${configPath()}, else npx -p ${PACKAGE_NAME} catalyst)
|
|
180
182
|
and runs one verb for the script that imports it. Run any sibling script with --help instead.`;
|
|
181
183
|
|
|
182
184
|
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
//
|
|
7
7
|
// customer.json carries exactly one credential: a personal key (`key`), or the keyless login's
|
|
8
8
|
// session (`auth`, the recommended rail). A script never reads either for its value: it spawns the
|
|
9
|
-
// catalyst
|
|
9
|
+
// catalyst CLI, which authenticates with whichever is present and refreshes a login's token
|
|
10
10
|
// itself. A new credential kind lands here, once.
|
|
11
11
|
|
|
12
12
|
/** The command that connects this machine, as every not-connected line names it. */
|
|
13
13
|
export const CONNECT_COMMAND =
|
|
14
|
-
"npx @catalyst-cloud/catalyst
|
|
14
|
+
"npx -p @catalyst-cloud/cli catalyst login (or, with a personal key: CATALYST_CLOUD_TOKEN=<your personal key> npx -p @catalyst-cloud/cli catalyst login)";
|
|
15
15
|
|
|
16
16
|
/** True when `cfg` (parsed customer.json) holds a usable credential of either kind. Never throws. */
|
|
17
17
|
export function hasCredential(cfg) {
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// watch-scope.mjs — subscribe to the tenant stream filtered to one scope and pass every in-scope
|
|
3
|
-
// frame through, one JSON line each. This is `catalyst
|
|
3
|
+
// frame through, one JSON line each. This is `catalyst watch` with the scope flags checked
|
|
4
4
|
// up front; the CLI owns the socket, the cursor file, the replay and the reconnects.
|
|
5
5
|
import { CHECK_FAILED_EXIT, execCli, parseFlags, requireConfigured, wantsHelp } from "./lib/cli.mjs";
|
|
6
6
|
|
package/skills/unstick/SKILL.md
CHANGED
|
@@ -1,32 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: unstick
|
|
3
3
|
description: >-
|
|
4
|
-
Get a stuck Catalyst Cloud ticket moving again. Use when the person asks "why is this parked and can you release it?", "unpark this", "get things flowing again", "the outage is over, retry what failed", or hands you a ticket that is not moving. Reads why nothing runs and what holds the ticket through the catalyst
|
|
5
|
-
|
|
6
|
-
allowed-tools: Bash(catalyst-skills:*) Bash(npx @catalyst-cloud/catalyst-skills:*)
|
|
4
|
+
Get a stuck Catalyst Cloud ticket moving again. Use when the person asks "why is this parked and can you release it?", "unpark this", "get things flowing again", "the outage is over, retry what failed", or hands you a ticket that is not moving. Reads why nothing runs and what holds the ticket through the catalyst CLI, decides whether the recorded cause is fixed, previews the release, releases every governor holding the ticket the right way (or one failure class across a team), and raises an ask only for what a person has to do. Never releases a cause it cannot show changed without saying so.
|
|
5
|
+
allowed-tools: Bash(catalyst:*) Bash(npx -p @catalyst-cloud/cli catalyst:*)
|
|
7
6
|
---
|
|
8
|
-
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.
|
|
7
|
+
<!-- vendored-from: @catalyst-cloud/catalyst-skills@0.13.1 — written in this repository for customer accounts -->
|
|
9
8
|
|
|
10
9
|
# Unstick
|
|
11
10
|
|
|
12
|
-
You get one stuck ticket, or one set of tickets stuck for the same reason, moving again. The cloud parks or holds a ticket when retrying would only repeat a failure: after repeated failures, when the repair-round cap is spent, when a repair changed nothing, when the same validate failure recurred. Each of those is a governor. Once its cause is fixed, the person's own key releases
|
|
11
|
+
You get one stuck ticket, or one set of tickets stuck for the same reason, moving again. The cloud parks or holds a ticket when retrying would only repeat a failure: after repeated failures, when the repair-round cap is spent, when a repair changed nothing, when the same validate failure recurred. Each of those is a governor. Once its cause is fixed, the person's own key releases most of them. Two refuse that release: a round-threshold hold (a push the fleet did not make, or an answer to its ask, grants one more cycle) and a review that will not converge (a human comment on the ticket resumes it).
|
|
13
12
|
|
|
14
13
|
## Run first
|
|
15
14
|
|
|
16
|
-
Scripts are run, never read. Each prints `--help`; exit 2 means this machine is not connected (run `catalyst
|
|
15
|
+
Scripts are run, never read. Each prints `--help`; exit 2 means this machine is not connected (run `catalyst login`).
|
|
17
16
|
|
|
18
|
-
- `node scripts/unstick.mjs <ticket
|
|
19
|
-
- `node scripts/unstick.mjs <ticket> --because "<what changed>"
|
|
20
|
-
- `node scripts/unstick.mjs --class <failure-class> --team <key> [--because "<what changed>"]
|
|
17
|
+
- `node scripts/unstick.mjs <ticket>`: one JSON document: the eligibility explanation, the execution history (every governor holding the ticket with what releases it, and past releases), and a dry-run release showing what a release would clear and refuse. Changes nothing.
|
|
18
|
+
- `node scripts/unstick.mjs <ticket> --because "<what changed>"`: the same, then the real release. Add `--retry-unchanged` only when you can say what changed outside what the cloud can see.
|
|
19
|
+
- `node scripts/unstick.mjs --class <failure-class> --team <key> [--because "<what changed>"]`: the same for every ticket on one team parked under one failure class (at most 25 per call).
|
|
21
20
|
|
|
22
|
-
The verbs underneath are `catalyst
|
|
21
|
+
The verbs underneath are `catalyst explain <ticket>`, `catalyst explain <ticket> --history` and `catalyst release <ticket> --because <text> [--retry-unchanged] [--dry-run]`.
|
|
23
22
|
|
|
24
23
|
## Load on demand
|
|
25
24
|
|
|
26
25
|
| when | read |
|
|
27
26
|
| -- | -- |
|
|
28
27
|
| deciding whether to release, what a refusal means, when to ask a person | `references/playbook.md` |
|
|
29
|
-
| what a reason in the explanation means | the `whats-happening` skill
|
|
28
|
+
| what a reason in the explanation means, or what clears each kind of hold | the `whats-happening` skill: its why-is-it-stuck and when-a-phase-fails references |
|
|
30
29
|
| a refusal needs a decision or a person's action | the `what-needs-me` skill |
|
|
31
30
|
| a refusal names a person's pull request or its review | the `catalyst-github` skill |
|
|
32
31
|
|
|
@@ -38,4 +37,5 @@ The verbs underneath are `catalyst-skills explain <ticket>`, `catalyst-skills ex
|
|
|
38
37
|
- **One release per cause.** If the history shows a release for the same failure and nothing has changed since, a second release buys the same failure. Raise an ask instead.
|
|
39
38
|
- **A refusal names its fix.** Do the fix when it is yours to do; everything else is one ask through `what-needs-me`, attached to an existing ask for the same decision. Never close or merge a person's pull request, and never answer an ask as the person.
|
|
40
39
|
- **A shared cause is one note.** Several tickets parked by one outage or one bad image are one class release and one line in your reply, never one ask per ticket.
|
|
41
|
-
- **
|
|
40
|
+
- **What a release costs.** A release is a write: it is recorded against the person's name with your `--because`, shown to everyone who reads the ticket's history, and it spends a round of work the cloud will run again. The dry run is free; run it first.
|
|
41
|
+
- **Their account, as them.** Every read and write goes through the CLI and the person's own login. You never name another account.
|
|
@@ -3,4 +3,4 @@ interface:
|
|
|
3
3
|
short_description: "Find out why a Catalyst ticket is parked or held and release it once its cause is fixed; asks only for what needs a person"
|
|
4
4
|
default_prompt: "Use $unstick to find out why <ticket> is stuck and get it moving again."
|
|
5
5
|
policy:
|
|
6
|
-
allow_implicit_invocation:
|
|
6
|
+
allow_implicit_invocation: true
|