@launchsecure/launch-kit 0.0.33 → 0.0.34
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/dist/server/chart-serve.js +167 -2
- package/dist/server/cli.js +249 -41
- package/dist/server/council-entry.js +0 -0
- package/dist/server/course-entry.js +1 -1
- package/dist/server/fb-wizard.js +0 -0
- package/dist/server/graph-mcp-entry.js +180 -4
- package/dist/server/init-entry.js +438 -43
- package/dist/server/launch-radar-entry.js +45 -0
- package/dist/server/parse-worker-entry.js +167 -2
- package/dist/server/radar-docker-init-entry.js +444 -39
- package/dist/server/radar-entrypoint-entry.js +0 -0
- package/dist/server/radar-teardown-entry.js +23 -22
- package/dist/server/rover-entry.js +20122 -0
- package/package.json +28 -25
- package/scaffolds/ls-marketplace/plugins/kit/commands/standup.md +6 -6
- package/scaffolds/ls-marketplace/plugins/kit/skills/analyse/SKILL.md +6 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/brief/SKILL.md +40 -48
- package/scaffolds/ls-marketplace/plugins/kit/skills/debug/SKILL.md +45 -20
- package/scaffolds/ls-marketplace/plugins/kit/skills/deploy-check/SKILL.md +76 -67
- package/scaffolds/ls-marketplace/plugins/kit/skills/handoff/SKILL.md +132 -0
- package/scaffolds/ls-marketplace/plugins/kit/skills/ship/SKILL.md +149 -133
- package/scaffolds/migrate-safety/scripts/migrate-with-backup.sh +0 -0
- package/scaffolds/recall-hook/scripts/ensure-recall.sh +0 -0
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: End-to-end ship flow — runs /kit:deploy-check, prints the exact commit list, pushes the named branch only after explicit confirmation
|
|
2
|
+
description: End-to-end ship flow — runs /kit:deploy-check, prints the exact commit list, authors a shipping-log Brief (doc/shipping-logs/*.md) that joins the push payload, then pushes the named branch only after explicit confirmation. The Brief publishes itself to the LS Comm Hub via file-content-sync when the push lands — no separate post, no local log file. Stack-agnostic: detects the project's migrations tooling and deploy platform at runtime rather than assuming any one stack. Never calls a host's deploy CLI directly — pushing to a deploy-tracked branch lets the host's git integration deploy.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# /kit:ship
|
|
6
6
|
|
|
7
|
-
Compose `/kit:deploy-check` + `git push`
|
|
7
|
+
Compose `/kit:deploy-check` + shipping-log Brief + `git push` into one gated workflow. The skill is the human checklist for "I'm shipping now" — same checks a careful human would run, encoded so they cannot be skipped or reordered.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
This skill ships with `launch-kit init` into **any** project — Node, Python, Ruby, Go, Rust, a static site, a library — so it makes **no stack assumptions**. It detects the migrations tooling and deploy platform at runtime (Preflight step 7) and adapts; anything it can't detect, it degrades to a safe, platform-neutral path rather than referencing a tool the repo doesn't have.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The shipping log is a **Brief**: a markdown doc at `doc/shipping-logs/<date>-<target>-<sha>.md`, committed as part of the ship itself. If the project syncs its docs to LaunchSecure (the `shipping-logs` doc category mapped to the discussion handler — the same file-content-sync mechanism the LS server uses for any `doc/**` category), the moment the push lands the doc materializes as a Comm Hub comment under the "Shipping Logs" header — team-visible, branch-aware, no separate publish step. If the project is not wired to LaunchSecure, the Brief is still a durable in-repo record of every ship. The repo records what shipped; the Comm Hub renders it when present. One artifact, one or two surfaces.
|
|
12
|
+
|
|
13
|
+
Hard rule from project memory: **never push commits the user didn't explicitly name**, and **pushing to a deploy-tracked branch may auto-deploy** — so this skill always asks per-action before pushing, even when invoked with arguments. There is no `--yes-i-mean-it` flag.
|
|
12
14
|
|
|
13
15
|
Parse `$ARGUMENTS`:
|
|
14
16
|
|
|
15
17
|
- (empty) — full flow on the current branch → its upstream (resolved via `git rev-parse --abbrev-ref @{u}` or, missing that, `origin/<current-branch>`).
|
|
16
|
-
- **--to=<branch>** — push to a different remote branch (e.g. `--to=staging
|
|
17
|
-
- **--dry-run** — run deploy-check + build the
|
|
18
|
-
- **--note=<text>** — free-form human note
|
|
18
|
+
- **--to=<branch>** — push to a different remote branch (e.g. `--to=staging`). The skill never creates a new remote branch silently — if the target doesn't exist on origin, surface that and ask.
|
|
19
|
+
- **--dry-run** — run deploy-check + build the shipping-log Brief preview, but do NOT write the doc, do NOT commit, do NOT push. Useful for "what would shipping look like right now?".
|
|
20
|
+
- **--note=<text>** — free-form human note rendered as the Brief's `**Note**:` line. Useful for hotfix context, rollout caveats, or named reviewer.
|
|
19
21
|
- **--skip-check=<list>** — forwarded verbatim to `/kit:deploy-check --skip=<list>`. Surface skipped checks in the final report; do not let `--skip-check=build` slip through silently.
|
|
20
22
|
- **--quick** — forwarded to deploy-check (skips the slow `build` step). Refuse if the target is a deploy-tracked branch (`master` or whatever the repo's default is) — for prod, build must run.
|
|
21
23
|
|
|
22
24
|
Examples:
|
|
23
25
|
|
|
24
|
-
- `/kit:ship` → check, confirm, push current branch to its upstream
|
|
25
|
-
- `/kit:ship --dry-run` → check + preview the
|
|
26
|
+
- `/kit:ship` → check, author Brief, confirm, push current branch (including the Brief) to its upstream.
|
|
27
|
+
- `/kit:ship --dry-run` → check + preview the Brief only; no writes, no push.
|
|
26
28
|
- `/kit:ship --to=master` from `implementation` → cross-branch merge-and-deploy flow (see "Cross-branch ship" below).
|
|
27
|
-
- `/kit:ship --note="hotfix for feedback widget 500s"` →
|
|
29
|
+
- `/kit:ship --note="hotfix for feedback widget 500s"` → Brief carries the note.
|
|
28
30
|
|
|
29
31
|
## Preflight
|
|
30
32
|
|
|
@@ -42,10 +44,17 @@ Examples:
|
|
|
42
44
|
ship: <current-branch> → <target-branch> (prod: yes|no)
|
|
43
45
|
```
|
|
44
46
|
5. Stash check — if `git status --porcelain` shows uncommitted changes, refuse with `✗ working tree not clean — commit, stash, or discard before shipping`. Shipping with dirty state is never the right move; the deploy-check skill is lenient about it because it's read-only, this skill is not.
|
|
47
|
+
6. Confirm the shipping-logs category exists — `doc/shipping-logs/` directory present OR `shipping-logs` listed in the project's docCategories config (e.g. a `.launch-secure.config` / launch-kit config). If neither, warn: `⚠ shipping-logs doc category not registered — the Brief is still written to the repo, but won't sync to the Comm Hub` and continue.
|
|
48
|
+
7. **Detect the project stack** (this is what makes the skill portable — do it once here, reuse in steps 3 and 5). Probe the working tree; do not assume:
|
|
49
|
+
- **`MIGRATIONS_DIR`** — the first of these that exists, else `none`:
|
|
50
|
+
`prisma/migrations/` (Prisma) · `supabase/migrations/` (Supabase) · `drizzle/` or a dir containing `drizzle/meta/` (Drizzle) · `db/migrate/` (Rails/ActiveRecord) · `migrations/` with `alembic.ini` nearby or `alembic/versions/` (Alembic) · `*/migrations/` under a Django app · `src/main/resources/db/migration/` (Flyway) · a knex/TypeORM/Sequelize migrations dir named in the repo's ORM config. If a launch-kit/project config declares an explicit `migrationsPath`, that wins over detection. If none match, `MIGRATIONS_DIR=none` → the migration gate (step 3) is skipped entirely. Non-DB projects (libraries, CLIs, static sites) legitimately have no migrations.
|
|
51
|
+
- **`BACKUP_STORY`** — detect what protects a migration: a backup script (`scripts/*backup*`, `scripts/migrate-with-backup.*`) and/or a CI workflow (`.github/workflows/*backup*`, `*migrat*`, or the equivalent under `.gitlab-ci.yml` / other CI). Record whatever exists, or `none`.
|
|
52
|
+
- **`DEPLOY_PLATFORM`** — the first marker that matches, else `unknown`:
|
|
53
|
+
`vercel.json` / `.vercel/` → `vercel` · `netlify.toml` → `netlify` · `fly.toml` → `fly` · `render.yaml` → `render` · `railway.json`/`railway.toml` → `railway` · an app-deploying workflow under `.github/workflows/` → `github-actions` · a `Dockerfile` with no platform marker → `container` · none → `unknown`. Drives the post-push guidance in step 5; never hardcode a single host.
|
|
45
54
|
|
|
46
55
|
## Step 1 — Gate (run /kit:deploy-check)
|
|
47
56
|
|
|
48
|
-
Invoke `/kit:deploy-check` against the resolved target. Forward `--quick` / `--skip-check=` / `--target=`. Do NOT re-implement any check here — single source of truth lives in `deploy-check/SKILL.md
|
|
57
|
+
Invoke `/kit:deploy-check` against the resolved target. Forward `--quick` / `--skip-check=` / `--target=`. Do NOT re-implement any check here — single source of truth lives in `deploy-check/SKILL.md`, which does its own stack detection (typecheck/build/migration-drift adapt to the detected toolchain).
|
|
49
58
|
|
|
50
59
|
Verdict handling:
|
|
51
60
|
|
|
@@ -57,7 +66,7 @@ Verdict handling:
|
|
|
57
66
|
Hard rules:
|
|
58
67
|
|
|
59
68
|
- If `IS_PROD_PUSH=true` and the user passed `--quick` or `--skip-check=build`, refuse before running deploy-check: `✗ --quick / --skip-check=build are not allowed for prod pushes. Re-run without them.`
|
|
60
|
-
- If deploy-check
|
|
69
|
+
- If deploy-check reports a `migration_safety` row (it only does when the project has migrations) and it is anything other than ✓, treat as NO-GO regardless of overall verdict. Migration corruption is why the project carries a migration-safety discipline — this skill enforces it when migrations exist, and is silent about it when they don't.
|
|
61
70
|
|
|
62
71
|
## Step 2 — Show the exact push payload
|
|
63
72
|
|
|
@@ -71,6 +80,7 @@ About to push <current-branch> → origin/<target-branch>:
|
|
|
71
80
|
…
|
|
72
81
|
|
|
73
82
|
<N> commits, <M> files changed (<+adds>/<-dels>)
|
|
83
|
+
(+ 1 shipping-log Brief commit, authored in step 4)
|
|
74
84
|
```
|
|
75
85
|
|
|
76
86
|
Generated from:
|
|
@@ -82,18 +92,24 @@ If the list is empty → abort: `nothing to push — local branch is at or behin
|
|
|
82
92
|
|
|
83
93
|
If any commit author is not the current `git config user.email`, surface a `⚠ <N> commits authored by someone else (<emails>)` line — common in shared branches but worth flagging once.
|
|
84
94
|
|
|
85
|
-
## Step 3 — Migration backup gate
|
|
95
|
+
## Step 3 — Migration backup gate (only when MIGRATIONS_DIR ≠ none)
|
|
96
|
+
|
|
97
|
+
If `MIGRATIONS_DIR=none` (detected in Preflight step 7), **skip this step entirely** — there's nothing to gate.
|
|
86
98
|
|
|
87
|
-
|
|
99
|
+
Otherwise, if `git diff origin/<target>...HEAD --name-only -- <MIGRATIONS_DIR>` returns any files, surface:
|
|
88
100
|
|
|
89
101
|
```
|
|
90
102
|
⚠ This push includes <N> new migration(s):
|
|
91
|
-
-
|
|
103
|
+
- <MIGRATIONS_DIR>/<file>
|
|
92
104
|
…
|
|
93
105
|
|
|
94
106
|
Backup story:
|
|
95
|
-
|
|
96
|
-
-
|
|
107
|
+
<BACKUP_STORY, described concretely — e.g.:>
|
|
108
|
+
- CI: <detected workflow> runs a DB dump server-side once the migration lands on <target-branch>.
|
|
109
|
+
- Local: if you applied locally, you used <detected backup script> per the repo's migration docs.
|
|
110
|
+
<or, if BACKUP_STORY=none:>
|
|
111
|
+
- ⚠ No automated pre-migration backup detected in this repo. Take a manual dump before this lands,
|
|
112
|
+
or add a backup step to CI. Recovery is impossible without one.
|
|
97
113
|
```
|
|
98
114
|
|
|
99
115
|
Then ask:
|
|
@@ -102,122 +118,122 @@ Then ask:
|
|
|
102
118
|
|
|
103
119
|
This is a deliberate friction point — typing a word is more honest than `y`. Do not accept `yes` here; require `understood`.
|
|
104
120
|
|
|
105
|
-
## Step 4 —
|
|
121
|
+
## Step 4 — Author the shipping-log Brief
|
|
106
122
|
|
|
107
|
-
|
|
123
|
+
Build the Brief BEFORE pushing so it ships inside the same payload — the record and the code land atomically, and (when synced) file-content-sync publishes both on the same webhook delivery.
|
|
108
124
|
|
|
109
|
-
-
|
|
110
|
-
> "Push <N> commits to origin/<target-branch>? Reply `yes` to push, `cancel` to abort."
|
|
111
|
-
- If `IS_PROD_PUSH=true`:
|
|
112
|
-
> "Push <N> commits to origin/<target-branch>. This is a prod-tracked branch — Vercel will deploy automatically. Reply `ship it` to push, `cancel` to abort."
|
|
125
|
+
If `--dry-run`, build and show the Brief in a fenced block but do NOT write the file and do NOT commit.
|
|
113
126
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
On confirm: `git push origin <current-branch>:<target-branch>`. Stream stdout. If the push fails (non-fast-forward, hook reject, auth) — surface the error verbatim, do not retry, do not `--force`.
|
|
117
|
-
|
|
118
|
-
After a successful push to a deploy-tracked branch, surface the Vercel deployment lookup hint:
|
|
127
|
+
### Path & naming
|
|
119
128
|
|
|
120
129
|
```
|
|
121
|
-
|
|
122
|
-
→ check status: `vercel ls --prod` or watch the Vercel dashboard
|
|
123
|
-
(do NOT run `vercel deploy` from here — that bypasses the GitHub→Vercel flow and double-deploys)
|
|
130
|
+
doc/shipping-logs/<YYYY-MM-DD>-<target-branch>-<shortsha>.md
|
|
124
131
|
```
|
|
125
132
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
###
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
133
|
+
- `<YYYY-MM-DD>` — ship date (local date).
|
|
134
|
+
- `<target-branch>` — slugified target (e.g. `master`, `implementation`).
|
|
135
|
+
- `<shortsha>` — short sha of the current HEAD (pre-Brief-commit). Keeps same-day ships to the same target from colliding, and makes the filename greppable back to the commit range.
|
|
136
|
+
|
|
137
|
+
One ship = one new file. Never append to or rewrite a previous ship's Brief — corrections happen in a new `## Update <ISO-date>` section added to the SAME ship's Brief.
|
|
138
|
+
|
|
139
|
+
### Brief format
|
|
140
|
+
|
|
141
|
+
Plain markdown, no HTML, no emojis (project comms convention). Frontmatter carries only the title — the discussion handler manages its own sync fields.
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
144
|
+
---
|
|
145
|
+
title: Ship <YYYY-MM-DD> — <branch> → <target>: <one-line summary>
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
**Shipped**: <ISO timestamp>
|
|
149
|
+
**Branch**: <branch> → <target>
|
|
150
|
+
**Prod push**: yes | no
|
|
151
|
+
**Commits**: <N> (<oldest-sha>..<newest-sha>)
|
|
152
|
+
**Deploy check**: <verdict>
|
|
153
|
+
**Note**: <--note value — omit this line entirely when absent>
|
|
154
|
+
|
|
155
|
+
## Summary
|
|
156
|
+
|
|
157
|
+
<One paragraph: what this ship is, why it went out, what a teammate needs to know.>
|
|
158
|
+
|
|
159
|
+
## What shipped
|
|
160
|
+
|
|
161
|
+
### <theme scope, e.g. db-providers>
|
|
162
|
+
- <outcome bullet — short product-facing sentence, NOT a raw commit subject>
|
|
163
|
+
- <outcome bullet>
|
|
164
|
+
|
|
165
|
+
### <next theme>
|
|
166
|
+
- …
|
|
167
|
+
|
|
168
|
+
## Migrations
|
|
169
|
+
|
|
170
|
+
<List each migration path + its backup story, or "None.">
|
|
171
|
+
|
|
172
|
+
## Deploy check
|
|
173
|
+
|
|
174
|
+
<verdict>
|
|
175
|
+
- <warning lines from the deploy-check report, verbatim>
|
|
176
|
+
|
|
177
|
+
## Commits
|
|
178
|
+
|
|
179
|
+
- `<shortsha>` <subject>
|
|
180
|
+
- `<shortsha>` <subject>
|
|
181
|
+
- …
|
|
171
182
|
```
|
|
172
183
|
|
|
173
184
|
Field sources:
|
|
174
185
|
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
- `commits` — `git log --pretty=format:'%H%x09%s%x09%an%x09%aI' origin/<target>..HEAD` (use the pre-push range — these are the commits that just landed).
|
|
180
|
-
- `stats` — `git diff --shortstat origin/<target>...<sha>` where `<sha>` is the new HEAD.
|
|
181
|
-
- `migrations` — `git diff --name-only origin/<target>...HEAD -- prisma/migrations/` (if step 3 fired, surface those exact paths; else empty array).
|
|
182
|
-
- `envVarsAdded` — pulled from deploy-check's `env_coverage` row, parsed from its `detail`. If deploy-check was skipped or didn't run that check, `[]`.
|
|
183
|
-
- `deployCheck.verdict` / `warnings` / `skipped` — from the deploy-check report in step 1.
|
|
184
|
-
- `themes` — group commits by conventional-commit scope (same default rule as `/kit:standup` step 3). Each theme: `{ scope, outcomes: [<outcome-bullets translated from commit subjects>] }`. Outcomes are short product-facing sentences, NOT raw subject lines. If commits lack scopes and there are ≥20 changed files across ≥5 dirs, escalate to launch-chart module grouping (same rule as standup step 3); otherwise bucket into `{scope: "misc", outcomes: […]}`.
|
|
185
|
-
- `summary` — one-line human-readable. Format: `Shipped <N> commit(s) to <target>${migrations ? " — includes migration" : ""}${themes ? " — " + topTheme : ""}`.
|
|
186
|
-
- `note` — verbatim `--note=` value, or `null` if absent.
|
|
187
|
-
- `vercelDeployHint` — `"auto-triggered on push to <target>"` if `isProdPush`, else `"no auto-deploy (target is not deploy-tracked)"`.
|
|
186
|
+
- **Theme grouping** — group commits by conventional-commit scope (same default rule as `/kit:standup` step 3). Outcomes are short product-facing sentences. If commits lack scopes and there are ≥20 changed files across ≥5 dirs, escalate to launch-chart module grouping; otherwise bucket into a `misc` theme.
|
|
187
|
+
- **Commits / stats** — `git log --pretty=format:'%h%x09%s' origin/<target>..HEAD` + `git diff --shortstat origin/<target>...HEAD`.
|
|
188
|
+
- **Migrations** — if `MIGRATIONS_DIR ≠ none`: `git diff --name-only origin/<target>...HEAD -- <MIGRATIONS_DIR>` (exactly what step 3 saw); else `None.`
|
|
189
|
+
- **Deploy check** — verdict + warnings from step 1's report.
|
|
188
190
|
|
|
189
191
|
### Preview + confirm
|
|
190
192
|
|
|
191
|
-
|
|
193
|
+
Show the full Brief in a fenced block, then ask:
|
|
192
194
|
|
|
193
|
-
|
|
194
|
-
About to append to .launchsecure/ship-log.ndjson:
|
|
195
|
+
> "Write this Brief to `doc/shipping-logs/<filename>` and commit it? Reply `yes` to write + commit, `edit` to tweak (summary, themes, note), `skip` to ship without a log, or `cancel` to abort the ship."
|
|
195
196
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
197
|
+
- `yes` / `y` → write the file, then `git add doc/shipping-logs/<filename> && git commit -m "docs(shipping-logs): ship <YYYY-MM-DD> — <target> (<one-line summary>)"`. The Brief commit is now the payload's tip.
|
|
198
|
+
- `edit` → ask what to change, redraft, re-show, re-ask.
|
|
199
|
+
- `skip` → no file, no commit. The ship proceeds unlogged — say so plainly: `shipping without a log entry; there will be no record of this ship.`
|
|
200
|
+
- `cancel` → abort the entire ship. Nothing was written, nothing was pushed.
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
```
|
|
202
|
+
## Step 5 — Push confirmation
|
|
204
203
|
|
|
205
|
-
|
|
206
|
-
- `edit summary` → ask what to change (summary text, theme grouping, note), redraft the entry, re-show, re-ask.
|
|
207
|
-
- `skip` → do not write. Print the entry once more so the user can manually save it elsewhere if they want. Ship is still considered successful — the push landed.
|
|
208
|
-
- `cancel` → do not write. Same as `skip` but no echo. **Do not** attempt to revert the push — surface clearly: `Push already landed on origin/<target>; cancel only stops the log append.`
|
|
204
|
+
Ask **exactly**:
|
|
209
205
|
|
|
210
|
-
|
|
206
|
+
- If `IS_PROD_PUSH=false`:
|
|
207
|
+
> "Push <N> commits to origin/<target-branch>? Reply `yes` to push, `cancel` to abort."
|
|
208
|
+
- If `IS_PROD_PUSH=true`:
|
|
209
|
+
> "Push <N> commits to origin/<target-branch>. This is a deploy-tracked branch — <if DEPLOY_PLATFORM≠unknown: '<platform> will deploy automatically'; else: 'whatever deploy pipeline is wired to this branch will pick it up'>. Reply `ship it` to push, `cancel` to abort."
|
|
211
210
|
|
|
212
|
-
|
|
211
|
+
`<N>` includes the Brief commit from step 4 (when not skipped). Accept exactly `yes` / `ship it` (case-insensitive). Anything else → treat as cancel. **Never** accept silence, `ok`, `sure`, free-form approval. If `--dry-run`, skip this step entirely.
|
|
213
212
|
|
|
214
|
-
|
|
215
|
-
echo "<minified-json>" >> .launchsecure/ship-log.ndjson
|
|
216
|
-
```
|
|
213
|
+
On confirm: `git push origin <current-branch>:<target-branch>`. Stream stdout. If the push fails (non-fast-forward, hook reject, auth) — surface the error verbatim, do not retry, do not `--force`.
|
|
217
214
|
|
|
218
|
-
|
|
215
|
+
If the push fails AND a Brief commit was created in step 4, leave it in place — it's a normal local commit; the user resolves the push problem and re-runs `/kit:ship` (step 2 will show it as part of the payload).
|
|
219
216
|
|
|
220
|
-
|
|
217
|
+
After a successful push:
|
|
218
|
+
|
|
219
|
+
- The Brief is now live in the repo. If the project is wired to LaunchSecure, file-content-sync picks it up from the webhook delivery and materializes the Comm Hub comment under the "Shipping Logs" category (branch-aware: a ship to a non-default branch shows with a branch pill until it reaches the default branch).
|
|
220
|
+
- If `IS_PROD_PUSH=true`, surface deploy guidance **for the detected platform** (`DEPLOY_PLATFORM`), never a hardcoded host:
|
|
221
|
+
|
|
222
|
+
| DEPLOY_PLATFORM | Post-push line |
|
|
223
|
+
|---|---|
|
|
224
|
+
| `vercel` | `Vercel's git integration will deploy the latest commit on <target>. Check: vercel ls --prod. Do NOT run vercel deploy from here — it bypasses the git→Vercel flow and double-deploys.` |
|
|
225
|
+
| `netlify` | `Netlify's git integration will build the latest commit on <target>. Check the Netlify dashboard / netlify status. Do NOT run netlify deploy --prod from here.` |
|
|
226
|
+
| `fly` | `If a deploy GitHub Action is wired, it will run flyctl deploy on push. Otherwise a maintainer runs it. Check: fly status.` |
|
|
227
|
+
| `render` / `railway` | `<platform>'s git integration will deploy the latest commit on <target>. Check the <platform> dashboard.` |
|
|
228
|
+
| `github-actions` | `The deploy workflow under .github/workflows/ will run on push to <target>. Check: gh run list --branch <target>.` |
|
|
229
|
+
| `container` / `unknown` | `Push complete. This repo has no detected managed-deploy integration — whatever CI/CD or manual process is wired to <target> takes over from here. This skill does not deploy.` |
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
Pushed.
|
|
233
|
+
<platform-specific line from the table above>
|
|
234
|
+
|
|
235
|
+
Shipping log written: doc/shipping-logs/<filename><if synced: → Comm Hub "Shipping Logs">
|
|
236
|
+
```
|
|
221
237
|
|
|
222
238
|
## Cross-branch ship (--to=master from a feature branch)
|
|
223
239
|
|
|
@@ -226,49 +242,49 @@ When the user runs `/kit:ship --to=master` from a non-master branch, the flow is
|
|
|
226
242
|
1. After deploy-check passes, before step 2, verify the current branch is ahead of `origin/master` (`git rev-list --left-right --count origin/master...HEAD` → left=behind, right=ahead). If behind, abort: `✗ <current> is behind origin/master by <N>; rebase or merge master first`.
|
|
227
243
|
2. The push command becomes `git push origin <current-branch>:master`. Make sure step 2's "About to push" preamble shows this asymmetric refspec so the user sees it.
|
|
228
244
|
3. On non-fast-forward reject from origin, do NOT suggest `--force`. Surface and stop.
|
|
245
|
+
4. The Brief's `**Branch**:` line shows the asymmetric flow (`<current> → master`) and its filename uses `master` as the target slug.
|
|
229
246
|
|
|
230
247
|
## Constraints
|
|
231
248
|
|
|
232
|
-
- **Never auto-
|
|
233
|
-
- **Never call `vercel deploy`
|
|
249
|
+
- **Never auto-commit and auto-push in one breath.** Always two explicit confirmations (step 4 Brief commit, step 5 push). The `--dry-run` flag exists instead of bundling.
|
|
250
|
+
- **Never call a host's deploy CLI** (`vercel deploy`, `netlify deploy`, `flyctl deploy`, etc.). Managed deploys come from the host's git integration on push to a deploy-tracked branch. Calling the CLI double-deploys and bypasses the gate. The one exception is a project whose `DEPLOY_PLATFORM` is genuinely CLI-only with no git integration — and even then, this skill stops at the push and leaves the deploy to the user.
|
|
234
251
|
- **Never `git push --force` / `--force-with-lease`.** If a push fails, the user investigates.
|
|
235
252
|
- **Never `git push <branch>` without an explicit refspec.** Always `<local-branch>:<remote-branch>` so the destination is unambiguous in the printed command (and in shell history).
|
|
236
|
-
- **Never bypass migration_safety.** A ✓ on the deploy-check migration_safety row is the gate; anything else is NO-GO
|
|
253
|
+
- **Never bypass migration_safety when migrations exist.** A ✓ on the deploy-check migration_safety row is the gate; anything else is NO-GO. When the project has no migrations, there is no such row and nothing to bypass.
|
|
254
|
+
- **No stack assumptions.** Everything stack-specific (migrations tooling, deploy host, backup story) is resolved by detection in Preflight step 7. If detection comes up empty, degrade to the neutral path — never reference a tool, path, or command the repo doesn't have.
|
|
237
255
|
- **Single source of truth for checks.** Do not duplicate `/kit:deploy-check` logic inline; invoke it.
|
|
238
|
-
- **
|
|
239
|
-
- **Log only
|
|
240
|
-
- **
|
|
241
|
-
- **
|
|
242
|
-
- **
|
|
256
|
+
- **One ship, one Brief.** Never edit, delete, or rewrite a previous ship's Brief. Corrections go in an `## Update <ISO-date>` section appended to that ship's own Brief in a follow-up commit.
|
|
257
|
+
- **Log only what actually ships.** The Brief is committed before the push, but it only publishes when the push lands — if the user cancels at step 5, tell them the Brief commit is still local and will ride along with the next ship (or can be dropped by them; never drop it yourself).
|
|
258
|
+
- **Honest about deploy state.** This skill ends when the push completes. It does NOT wait for a build to finish, does NOT verify the prod URL is up, does NOT roll back. Point the user at the detected platform's status command for deploy-monitoring.
|
|
259
|
+
- **Dry-run is truly dry.** `--dry-run` must NOT write any file, must NOT commit, must NOT push. The preview is shown in chat only.
|
|
260
|
+
- **Respect doc/ ownership rules.** Only ever write under `doc/shipping-logs/`. Never touch `doc/ideas/` (personal scratch) or other categories from this skill.
|
|
243
261
|
|
|
244
262
|
## Idempotency
|
|
245
263
|
|
|
246
264
|
Re-running `/kit:ship` after a successful run:
|
|
247
265
|
|
|
248
|
-
- Step 2 will show "nothing to push" if the previous push landed cleanly — the natural no-op. No new
|
|
249
|
-
- Each successful ship is a separate
|
|
250
|
-
-
|
|
266
|
+
- Step 2 will show "nothing to push" if the previous push landed cleanly — the natural no-op. No new Brief results.
|
|
267
|
+
- Each successful ship is a separate file in `doc/shipping-logs/`. There is no per-day or per-branch coalescing — the Comm Hub renders them as separate entries. If a hotfix ships 10 minutes after a feature, both Briefs exist independently.
|
|
268
|
+
- A Brief committed but not pushed (cancelled at step 5) is picked up by the next run: step 2 shows it in the payload, step 4 detects an existing un-pushed Brief for this range and offers to reuse or rewrite it instead of authoring a duplicate.
|
|
251
269
|
|
|
252
270
|
## Reading the log
|
|
253
271
|
|
|
254
|
-
|
|
272
|
+
The shipping history lives in the repo, and (when synced) in the Comm Hub:
|
|
255
273
|
|
|
256
274
|
```
|
|
257
|
-
#
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
# ships to master in the last 7 days
|
|
261
|
-
jq -c 'select(.target == "master" and (.ts | fromdateiso8601) > (now - 7*86400))' .launchsecure/ship-log.ndjson
|
|
275
|
+
# repo side — every ship, newest first
|
|
276
|
+
ls -t doc/shipping-logs/
|
|
262
277
|
|
|
263
|
-
#
|
|
264
|
-
|
|
278
|
+
# one ship's full record
|
|
279
|
+
cat doc/shipping-logs/<file>.md
|
|
265
280
|
```
|
|
266
281
|
|
|
267
|
-
|
|
282
|
+
Comm Hub side (when the project is LaunchSecure-wired): the "Shipping Logs" category header in the LS sidebar lists every published ship Brief with the BookOpen icon. Filter chips (Published / In Development) follow the branch-aware brief tiers.
|
|
268
283
|
|
|
269
284
|
## Notes for the assistant
|
|
270
285
|
|
|
271
286
|
- The user has explicit project-memory rules against unauthorised pushes and dumb reverts. Treat every confirmation as load-bearing — don't paraphrase the prompt wording, don't accept ambiguous approval.
|
|
272
|
-
- "Ship" is the user's verb for "I want this in production." If the target isn't actually deploy-tracked, the skill should still work but should say so clearly in the scope line (step
|
|
273
|
-
- The
|
|
274
|
-
-
|
|
287
|
+
- "Ship" is the user's verb for "I want this in production." If the target isn't actually deploy-tracked, the skill should still work but should say so clearly in the scope line (step 5 phrasing changes).
|
|
288
|
+
- The shipping-log Brief is the durable artifact and (when synced) the published record at once — there is no separate "publish" step and no local NDJSON file. If you find `.launchsecure/ship-log.ndjson` in a repo, it's from a pre-Brief version of this skill; leave it alone (don't migrate, don't delete) and mention it once.
|
|
289
|
+
- **Portability is the contract.** This skill is installed by `launch-kit init` into projects on stacks you can't predict. Anything you hardcode that isn't in *this* repo is a bug for the next repo. When in doubt, detect or degrade — never assume.
|
|
290
|
+
- This skill assumes `/kit:deploy-check` exists. If missing (older launch-kit install), surface that as a preflight error pointing to `npx @launchsecure/launch-kit init`.
|
|
File without changes
|
|
File without changes
|