Skip to content

Commit 853f6e4

Browse files
authored
Merge pull request #9 from flyingrobots/release/v0.2.0
Release v0.2.0
2 parents c6df03c + de4d933 commit 853f6e4

23 files changed

+1375
-35
lines changed

AGENTS.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ Tasks are now tracked under docs/tasks/. See:
112112
- README refresh:
113113
- Added “GitHub Hosting” links, Environment Reference, Quick copy/paste commands, JSON-only `show` examples.
114114

115+
### Daily Log – 2025-09-26
116+
117+
- MVP docs + release
118+
- Full features docs sweep; added docs/features/command-reference.md.
119+
- test/README.md aligned with snapshot runner, timeouts, local sandbox.
120+
- Tasks MoC generator (scripts/update-task-moc.sh) and populated docs/tasks/README.md; kept progress bars updated (scripts/update-task-progress.sh UTF‑8 fix).
121+
- Opened and merged MVP PR (feat/github → main); tagged and pushed v0.1.0-mvp.
122+
- CI/CD signing
123+
- Fixed shiplog-sign workflow to bind to the selected environment and read CI_SSH_PUBLIC_KEY from environment variables (vars.*) instead of env.*.
124+
- CLI improvements
125+
- git shiplog write: new flags (--service/--reason/--status/--ticket/--region/--cluster/--namespace/--image/--tag/--run-url, --env), non-Bosun prompt fallbacks.
126+
- Signing robustness: fixed unbound array expansion in sign_commit under set -u.
127+
- README
128+
- Linked Command Reference; kept Overall bar mirrored from docs/tasks.
129+
115130
### Daily Log – 2025-09-24
116131

117132
- Fixed Bosun non-TTY input hang: scripts/bosun now properly handles empty stdin in non-interactive environments by implementing timeout-based input detection (resolves issue where CI pipelines would hang indefinitely).
@@ -135,4 +150,4 @@ For the current backlog, active work, and completed items, see:
135150
- docs/tasks/active/
136151
- docs/tasks/complete/
137152

138-
Progress bars are now maintained in `docs/tasks/README.md` (and mirrored into the root README) by `scripts/update-task-progress.sh`.
153+
Progress bars are now maintained in `docs/tasks/README.md` (and mirrored into the root README) by `scripts/update-task-progress.sh`.

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
## [0.2.0] – 2025-09-30
4+
**Codename:** The Cut of Your Jib
5+
6+
- Added `git shiplog run` to wrap commands, capture logs, and record structured run metadata.
7+
- Added `git shiplog append` for non-interactive entries via `--json` / `--json-file` (stdin supported).
8+
- Added `git shiplog trust show` (table and `--json`) including signer inventory.
9+
- Documented the structured entry schema (`docs/reference/json-schema.md`).
10+
- Defaulted the namespace to the journal name when `SHIPLOG_NAMESPACE` is unset.
11+
12+
## [0.1.0] – 2025-09-26
13+
- Initial tagged release.

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
# SHIPLOG • 🚢🪵
2-
> _Git-native deployment ledger. Every release event is a signed commit for a tamper-evident, immutable audit trail, no new infra._
32

43
<p align="center">
54
<img src="https://repository-images.githubusercontent.com/1060619650/5194fe70-a78c-4c2d-85d9-b43e8beb8717" width="600" />
65
</p>
76

7+
## TL;DR Shiplog: Your Git Repo is an Ops Flight Recorder
8+
9+
### Your Deployment History Should Live in Git
10+
11+
**Shiplog**: your deployment history should live in the same repo as your code. No external services. No API keys. No monthly bills. Just git, doing what it does best: preserving history with cryptographic integrity.
12+
13+
### Git: An Immutable, Distributed Journal
14+
15+
***Git is a data structure.*** It can do way more than just source control. Shiplog's uses git to create chains of commits that hang off of `refs/_shiplog/*` refs, creating an append-only journal.
16+
17+
### Don't Trust; Verify
18+
19+
Shiplog uses a trust roster that's stored right in git, that restricts who may write to the journal, and uses a "policy by commits that require a quorum to change. that commit authors sign their commits to establish cryptographic provenance of each record, perfect for scenarios where you need immutable, auditable deployment and live-ops histories.
20+
21+
### It's just Git.
22+
23+
And best of all, it's all just git! You can fetch, push, clone, and verify using tools and knowledge you already have. No new software, no extra services. Just git.
24+
25+
---
26+
827
## Friday, 3:17 PM
928

1029
*Bzzzt. Bzzzzzt. Bzzzzzzzzt.*
@@ -103,6 +122,21 @@ Pipe to tools:
103122
git shiplog export-json | jq .
104123
```
105124

125+
Wrap a command and capture its output automatically:
126+
127+
```bash
128+
git shiplog run --service deploy --reason "Canary" -- env kubectl rollout status deploy/web
129+
```
130+
131+
Append structured data non-interactively (great for automation):
132+
133+
```bash
134+
printf '{"checks": {"canary": "green"}}' | \
135+
git shiplog append --env prod --region us-west-2 --cluster prod-a \
136+
--namespace frontend --service deploy --status success \
137+
--reason "post-release smoke" --json -
138+
```
139+
106140
---
107141

108142
## 🔐 Policy & Security
@@ -135,8 +169,11 @@ Shiplog enforces policy as code, stored in Git itself.
135169
|---------|---------|
136170
| `git shiplog init` | Setup refs & configs |
137171
| `git shiplog write` | Record a deployment |
172+
| `git shiplog append` | Record a deployment via JSON payload (stdin or file) |
173+
| `git shiplog run` | Wrap a command, capture logs, and record result |
138174
| `git shiplog ls` | List recent entries |
139175
| `git shiplog show` | Show entry details |
176+
| `git shiplog trust show` | Display trust roster and signer inventory |
140177
| `git shiplog verify` | Verify signatures/allowlist |
141178
| `git shiplog export-json` | Export NDJSON for tools |
142179

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
- [Docker & Dev Container Strategy](docker.md)
44
- [Trust Bootstrap and Enforcement](TRUST.md)
55
- [Feature Guides](features)
6+
- [Structured Entry Schema](reference/json-schema.md)
7+
- [Release Notes](releases/v0.2.0.md)
68
- [Bosun Helpers](bosun)
79
- [Plugin Hooks](plugins.md)

docs/features/command-reference.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ A concise, code-sourced reference for Shiplog commands, flags, and examples. Glo
3030
- Env: `SHIPLOG_SERVICE`, `SHIPLOG_STATUS`, `SHIPLOG_REASON`, `SHIPLOG_TICKET`, `SHIPLOG_REGION`, `SHIPLOG_CLUSTER`, `SHIPLOG_NAMESPACE`, `SHIPLOG_IMAGE`, `SHIPLOG_TAG`, `SHIPLOG_RUN_URL`, `SHIPLOG_LOG`, `SHIPLOG_AUTO_PUSH`.
3131
- Effects: honors allowlists/signing per policy; pushes journal (+notes) to origin unless disabled.
3232

33+
- `append [OPTIONS]`
34+
- Purpose: append a new entry non-interactively by supplying a JSON payload via CLI, stdin, or file.
35+
- Usage: `printf '{"deployment":"green"}' | git shiplog append --service deploy --status success --json -`
36+
- Flags: mirrors `write` (`--service`, `--status`, `--reason`, `--ticket`, `--region`, `--cluster`, `--namespace`, `--image`, `--tag`, `--run-url`, `--log`, `--env`).
37+
- Notes: sets `SHIPLOG_EXTRA_JSON` automatically with the provided object and runs `write` in boring/auto-confirm mode.
38+
39+
- `run [OPTIONS] -- <command ...>`
40+
- Purpose: wrap a shell command, tee its output (when interactive), and append a Shiplog entry describing the run.
41+
- Usage:
42+
- Success case: `git shiplog run --service deploy --reason "Smoke test" -- env printf hi`
43+
- Failure case: `git shiplog run --service deploy --status-failure failed -- false`
44+
- Flags: `--service`, `--reason`, `--status-success`, `--status-failure`, `--ticket`, `--region`, `--cluster`, `--namespace`, `--env`.
45+
- Notes: captures stdout/stderr to a temporary log that is attached as a git note (skipped if empty) and merges `{run:{...}}` into the JSON trailer via `SHIPLOG_EXTRA_JSON`. See `docs/reference/json-schema.md` for the structured payload.
46+
3347
- `ls [ENV] [LIMIT]`
3448
- Purpose: list recent entries.
3549
- Usage: `git shiplog ls prod 20`
@@ -71,6 +85,12 @@ A concise, code-sourced reference for Shiplog commands, flags, and examples. Glo
7185
- Purpose: sync allowed signers from a trust ref to a local file.
7286
- Usage: `git shiplog trust sync refs/_shiplog/trust/root .shiplog/allowed_signers`
7387

88+
- `trust show [REF] [--json]`
89+
- Purpose: display trust metadata (ID, threshold, maintainer roster, signer list and count).
90+
- Usage:
91+
- Human readable: `git shiplog trust show`
92+
- JSON: `git shiplog trust show --json`
93+
7494
- `refs root show|set`
7595
- Purpose: view or set the Shiplog ref root.
7696
- Usage:
@@ -91,4 +111,3 @@ A concise, code-sourced reference for Shiplog commands, flags, and examples. Glo
91111
- Features docs: init, write, ls, show, export-json, validate-trailer, verify, policy, setup, notes.
92112
- Modes and signing policy: `docs/features/modes.md`
93113
- GitHub hosting and protections: `docs/hosting/github.md`, `docs/runbooks/github-protection.md`
94-

docs/features/run.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Run Command
2+
3+
## Summary
4+
`git shiplog run` wraps a shell command, captures its stdout/stderr, and records the execution as a Shiplog journal entry. The command output is saved as a git note, and the structured trailer gains a `run` payload describing the invocation.
5+
6+
## Usage
7+
```bash
8+
git shiplog run --service deploy --reason "Smoke test" -- env printf hi
9+
```
10+
11+
- `--service` is required in non-interactive mode (and highly recommended in general).
12+
- Place the command to execute after `--`. All arguments are preserved and logged.
13+
- Successful runs inherit `--status-success` (default `success`); failures use `--status-failure` (default `failed`).
14+
15+
## Behavior
16+
- Captures stdout/stderr to a temporary file. When not in boring mode, output is also streamed to your terminal via `tee`.
17+
- Sets `SHIPLOG_BORING=1` and `SHIPLOG_ASSUME_YES=1` while calling `git shiplog write` so no prompts fire.
18+
- Populates `SHIPLOG_EXTRA_JSON` with:
19+
```json
20+
{
21+
"run": {
22+
"argv": ["env", "printf", "hi"],
23+
"cmd": "env printf hi",
24+
"exit_code": 0,
25+
"status": "success",
26+
"duration_s": 1,
27+
"started_at": "2025-09-30T00:00:00Z",
28+
"finished_at": "2025-09-30T00:00:01Z",
29+
"log_attached": true
30+
}
31+
}
32+
```
33+
- Attaches the captured log as a git note under `refs/_shiplog/notes/logs` when the entry is written successfully.
34+
- Returns the wrapped command’s exit code so it can be chained in scripts or CI pipelines.
35+
36+
## Options
37+
- `--env <name>` — Target journal environment (defaults to `SHIPLOG_ENV` or `prod`).
38+
- `--service <name>` — Service/component; required when prompts are disabled.
39+
- `--reason <text>` — Optional free-form description.
40+
- `--status-success <status>` — Status recorded when the command exits 0. Default `success`.
41+
- `--status-failure <status>` — Status recorded when the command fails. Default `failed`.
42+
- `--ticket <id>`, `--region <r>`, `--cluster <c>`, `--namespace <ns>` — Override standard write metadata.
43+
- When there is no output, log attachment is skipped and `log_attached=false` is recorded in the trailer.
44+
45+
## See Also
46+
- `docs/features/write.md`
47+
- `docs/reference/env.md`
48+
- `docs/notes/codex-feedback-on-shiplog.md`
49+
- `docs/reference/json-schema.md`

docs/features/write.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ SHIPLOG_BORING=1 git shiplog --yes write prod --service release --reason "MVP re
1818
## Behavior
1919
- Validates the author against the resolved allowlist and performs a signing precheck when signatures are required.
2020
- Prompts for service, status, change details, and artifact information. You can prefill or bypass prompts with flags (`--service`, `--reason`, etc.) or environment variables listed below.
21+
- Defaults the namespace to the journal environment when left blank (e.g., `prod`).
2122
- Generates both a human-readable header and a JSON trailer; optionally attaches NDJSON logs via `SHIPLOG_LOG`.
2223
- Accepts `--yes` to skip confirmation prompts (sets `SHIPLOG_ASSUME_YES=1`).
2324
- Fast-forwards the journal ref; aborts if the ref is missing or would require a force update.
@@ -51,3 +52,18 @@ SHIPLOG_BORING=1 git shiplog --yes write prod --service release --reason "MVP re
5152
- `test/02_write_and_ls_show.bats:22`
5253
- `test/05_verify_authors.bats:9`
5354
- `test/10_boring_mode.bats:31`
55+
- `test/17_append_and_trust.bats`
56+
57+
## Programmatic Append
58+
59+
Need to script entries without prompts? Use `git shiplog append`:
60+
61+
```bash
62+
printf '{"checks": {"canary": "green"}}' | \
63+
git shiplog append --service deploy --status success \
64+
--reason "Post-release smoke" --json -
65+
```
66+
67+
- Accepts the same metadata flags as `write` but runs in boring/auto-confirm mode.
68+
- `--json` (or `--json-file path`) must contain a JSON object; Shiplog merges it into the structured trailer via `SHIPLOG_EXTRA_JSON`.
69+
- Attach logs with `--log <path>` if desired.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Shiplog DX Notes — September 2025
2+
3+
I took Shiplog for a (manual) spin today in order to integrate it with the PF3 deploy orchestrator. These are the rough notes I’d want any future maintainer to have — both what felt rock-solid and what I’d polish next.
4+
5+
---
6+
7+
## Overall Impression
8+
9+
Shiplog already feels *production ready* for the git-native audit log niche it targets. The primitives — signed commits under `refs/_shiplog/journal/<env>` with structured trailers — map perfectly onto the “what happened in prod?” question we ask ourselves during incidents. Once trust/bootstrap is in place, `git shiplog write` feels just as natural as `git commit`.
10+
11+
I’d happily depend on it for:
12+
13+
- Deploy receipts (start → step → finish)
14+
- Maintenance mode toggles (with reasons / reminders)
15+
- RBAC changes (added admin, revoked key)
16+
- Trust rotations & secret rotations
17+
- Ad-hoc scripts with log capture (once `shiplog run` lands)
18+
19+
In other words: if an operator does something that changes prod, Shiplog is the canonical place to record it. That’s exactly what I want from an operational journal.
20+
21+
---
22+
23+
## Things That Felt Great
24+
25+
- **Git-first workflow**: No extra service. Journals are just refs. Easy to mirror, easy to inspect.
26+
- **Signing/Policy hooks**: Guard rails are strong. Missing trust ref immediately fails with a helpful message. SSH signing plays nicely with modern git.
27+
- **Structured trailers**: The JSON we get back from `git shiplog show --json` is deliciously parseable. Perfect for piping into dashboards or incident bots.
28+
- **Trust tooling**: `shiplog-bootstrap-trust.sh` + `shiplog-trust-sync.sh` made the initial setup straightforward. Non-interactive flags mean we can script it.
29+
- **Docs/AGENTS discipline**: The repo has clearly codified expectations (test in Docker, etc.). Easy to onboard to.
30+
31+
---
32+
33+
## Opportunities / DX Wishlist
34+
35+
### 1. `git shiplog run` (on deck)
36+
Exactly what we’re about to build: wrap a command, tee stdout/stderr, and attach the log as a note. I’d ship it with:
37+
- `--service`, `--reason`, `--status-success/failed` overrides.
38+
- Structured `run` payload: `argv`, `cmd`, `exit_code`, `status`, `duration_s`, `started_at`, `finished_at`.
39+
- Boring mode by default; interactive tee for humans.
40+
- Respects `SHIPLOG_NAMESPACE`, `SHIPLOG_TICKET`, etc., so we can categorize maintenance vs deploy vs misc.
41+
42+
### 2. Programmatic API helper
43+
Either a `git shiplog append --json payload` or a tiny shell helper that sets `SHIPLOG_EXTRA_JSON` and calls `write`. That would keep deploy-orchestrator code simpler.
44+
45+
### 3. Namespace defaults
46+
`git shiplog ls` shows `Env` as `?` unless `SHIPLOG_NAMESPACE` is set. Defaulting the namespace to the journal name (or providing a `--namespace` flag) would make the table friendlier.
47+
48+
### 4. Trust roster visibility
49+
A `git shiplog trust show` command that prints threshold and maintainer list would be handy during audits.
50+
51+
### 5. Docs: runbook for operators
52+
Once `shiplog run` is available, a short runbook (“How to log maintenance mode”, “How to record an incident”, “How to rotate trust”) would accelerate adoption.
53+
54+
---
55+
56+
## Integration Notes (PF3)
57+
58+
For PF3 we intend to:
59+
- Emit a Shiplog entry when a deploy plan is approved (status=started + plan JSON).
60+
- Append entries after each step (`status` `in_progress`, `reason` summarizing action, structured run payload).
61+
- Finish with a `status=success|failed` entry containing maintenance flag, failure reason, etc.
62+
- Use `shiplog run` for ad-hoc maintenance toggles or recovery scripts so we capture raw command output automatically.
63+
64+
That will replace our ad-hoc JSON journal with a tamper-evident history.
65+
66+
---
67+
68+
## Misc Observations
69+
70+
- **Trust bootstrap** refused to run outside a repo. Nice guard! Perhaps the script could detect this earlier and print “run inside target repo” with the resolved path.
71+
- **Preview output** always prints (even in `--yes`). I like that, but a `SHIPLOG_NO_PREVIEW=1` toggle might be nice for CI logs.
72+
- **`SHIPLOG_EXTRA_JSON`** hook was easy to splice in once I noticed trailers are composed in `compose_message`. Reusing `shiplog_json_escape` will keep it tidy when I refactor the helper.
73+
- **Testing** via `make test` (Docker) was smooth. Love that the AGENTS doc shouts *not* to run tests directly.
74+
75+
---
76+
77+
## Other Potential Use Cases
78+
79+
- **Incident timeline**: `git shiplog run --service incident --reason "Declared SEV-1" -- env true` to mark major steps.
80+
- **Access review**: Append entries whenever someone is added/removed from Supabase roles or GitHub teams.
81+
- **Secrets rotation**: Wrap rotation scripts with `shiplog run` so we have an audit trail of the exact CLI output.
82+
- **Schema migrations**: Each `supabase db push` could be wrapped to capture the migration log.
83+
- **Build provenance**: If we wanted to record Docker image builds (“built ghcr.io/app@sha…”) we could make `shiplog run` a standard part of the release pipeline.
84+
85+
---
86+
87+
## Closing Thoughts
88+
89+
Shiplog is already delivering on the “black box recorder for ops” promise. The biggest DX win on the horizon is the command wrapper — once we have that, we can eliminate a ton of bespoke logging code across projects. Happy to help keep pushing it forward!
90+

docs/reference/env.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ This is a compact reference for key `SHIPLOG_*` environment variables. Most can
4343
- `SHIPLOG_REGION`, `SHIPLOG_CLUSTER`, `SHIPLOG_NAMESPACE`
4444
- `SHIPLOG_IMAGE`, `SHIPLOG_TAG`, `SHIPLOG_RUN_URL`
4545
- `SHIPLOG_LOG` — Path to NDJSON log to attach as a git note
46+
- `SHIPLOG_EXTRA_JSON`*(internal)* Raw JSON object merged into the structured trailer; set automatically by `git shiplog run`/`git shiplog append`. Do not export this manually—provide custom data with `git shiplog append --json '{...}'` or `git shiplog append --json-file payload.json` (these flags populate the internal value for you).
4647

4748
See: docs/features/write.md for full semantics and examples.
4849

@@ -69,4 +70,3 @@ See: docs/features/write.md for full semantics and examples.
6970
- `TEST_TIMEOUT_SECS` — In-container Bats timeout (seconds). Default: `180`.
7071
- `BATS_FLAGS` — Extra flags for Bats (e.g., `--print-output-on-failure -T`).
7172
- `SHIPLOG_USE_LOCAL_SANDBOX``1` to avoid network clones in tests (default `1`).
72-

0 commit comments

Comments
 (0)