diff --git a/RELEASE_HANDOFF_0.12.0.md b/RELEASE_HANDOFF_0.12.0.md new file mode 100644 index 0000000..031e87f --- /dev/null +++ b/RELEASE_HANDOFF_0.12.0.md @@ -0,0 +1,108 @@ +# shiplog 0.12.0 — Release Execution Handoff + +**Release target:** `v0.12.0` +**Status:** preparing +**Release decision:** [`docs/release/0.12.0-release-decision.md`](docs/release/0.12.0-release-decision.md) +**Readiness ledger:** [`docs/release/0.12.0-readiness.md`](docs/release/0.12.0-readiness.md) + +Nothing here has been executed. Every identity and receipt is a placeholder, +and this handoff must not be marked closed from intended commands — only from +observed public state. + +## Exact release identities + +| Identity | Value | +| --- | --- | +| Swarm candidate SHA | `` | +| Source promotion PR / merge | `#` / `` | +| Source release-prep PR / merge | `#` / `` | +| Release source commit | `` | +| Annotated tag | `v0.12.0` | +| Source Release workflow | `` | +| Staged candidate manifest | `` | +| Terminal candidate-ready aggregate | `` | + +## Published contents + +`` + +## Artifact receipt + +| Artifact | Observed result | +| --- | --- | +| `shiplog-x86_64-unknown-linux-gnu` | `` | +| `shiplog-x86_64-apple-darwin` | `` | +| `shiplog-aarch64-apple-darwin` | `` | +| `shiplog-x86_64-pc-windows-msvc.exe` | `` | +| `SHA256SUMS.txt` | `` | + +## Validation receipt + +- Release preflight: `` +- Release validation: `` +- Four-platform first-use acceptance against one staged set: `` +- Release-mode integration tests: `` +- Terminal `Release Candidate Ready`: `` +- crates.io install and `--version`: `` +- GitHub release public-state verification: `` +- Versionless installers: `` +- Homebrew: `` +- Scoop: `` +- Signing/notarization: `not configured` + +## Execution record + +`` + +The intended final boundary, for reference only: + +```text +git tag -a v0.12.0 -m "shiplog v0.12.0" +git push origin v0.12.0 +# After exact-tag staged-candidate proof and explicit owner approval: +git checkout --detach v0.12.0 +cargo publish -p shiplog --locked +gh release edit v0.12.0 --draft=false --latest +``` + +`cargo publish` must run from the exact detached tag checkout proven by the +source Release workflow, never from a later moving `main`. + +## Exceptions, rollback, or yank + +None. No tag has been pushed and nothing has been published. + +Rollback rules if that changes: the tag is immutable and published crate bytes +are never replaced. A failed candidate is fixed through swarm, promoted again, +and released as the next patch version — `v0.12.0` is not moved or reused. + +## Residual work + +- #245 — publication gated on one exact staged four-platform candidate set, + four-platform first-use acceptance, negative controls, and a terminal + readiness aggregate. The source-owned writer projection has not landed. +- Epic #246 Phase 5 — draft #389, the living release-preparation procedure, + is not yet reviewed and landed. +- Remove the "not in the shipped `v0.11.0` binary" caveat for `shiplog start` + from `README.md` and `docs/guides/guided-setup-doctor.md` as part of the + release-preparation PR, once `start` actually ships. +- Audit `scripts/release-install-smoke.sh` and `.ps1` for the ambient + credential isolation that #407 fixed in the Rust suites. +- Provider connection flows and share setup ergonomics remain deferred per the + release decision. + +## Claim boundary + +In its present form this handoff proves nothing about a release. It records +intended execution and the receipts still owed. + +When completed it will prove only what was observed. Checksums are not a +signing claim. A skipped or unavailable optional check is not executed proof. A +public GitHub Release does not by itself prove crates.io publication, Homebrew, +or Scoop. Preparation on `shiplog-swarm` confers no authority to tag, publish, +sign, or mutate a package channel; that authority is source-owned and requires +explicit owner approval. diff --git a/docs/release/0.12.0-readiness.md b/docs/release/0.12.0-readiness.md new file mode 100644 index 0000000..cab0812 --- /dev/null +++ b/docs/release/0.12.0-readiness.md @@ -0,0 +1,129 @@ +# shiplog 0.12.0 — Release Readiness + +**Release target:** `v0.12.0` +**Theme:** `Setup and everyday commands behave the way the docs already promised.` +**Status:** preparing + +Every gate below is `pending`. Nothing in this ledger has been observed yet, and +per the operating invariants a pending or unavailable check must never be +converted to a pass. + +## Candidate identities + +| Identity | Value | +| --- | --- | +| Swarm candidate SHA | `` | +| Source promotion PR | `EffortlessMetrics/shiplog#` | +| Source promotion merge | `` | +| Source release-prep PR | `EffortlessMetrics/shiplog#` | +| Release source commit | `` | +| Release tag | `v0.12.0` | + +The candidate is deliberately not frozen. `Cargo.toml` still reads `0.11.0`, +and the version and changelog freeze belong in the final shared +release-preparation PR rather than here. + +## Included release state + +Two new commands (`shiplog start`, `shiplog report validate --receipts`) make +this a minor increment; the rest is first-use and everyday-command repair, +including two evidence-correctness fixes. Scope, deferrals, and the proof +boundary are in +[`0.12.0-release-decision.md`](0.12.0-release-decision.md); the user-visible +list is the `Unreleased` section of [`CHANGELOG.md`](../../CHANGELOG.md). + +## Preflight evidence + +| Gate | Result | Evidence | +| --- | --- | --- | +| Swarm `Shiplog Rust Small Result` | pending | `` | +| `cargo xtask ci-small` | pending | `` | +| Repository contract report | pending | `` | +| Deterministic promotion dry-run | pending | `` | +| Source promotion exact-head CI | pending | `` | +| Promotion `--verify-only` | pending | `` | +| Source post-merge CI | pending | `` | +| Package version audit | pending | `` | +| Package boundary audit | pending | `` | +| Package proof | pending | `` | +| Allowlisted publish dry-run | pending | `` | +| Release-hold guard | pending | `` | + +## Exact-tag artifact evidence + +| Gate | Result | Evidence | +| --- | --- | --- | +| Release Preflight | pending | `` | +| Linux x86-64 build | pending | `` | +| macOS Intel build | pending | `` | +| macOS Apple Silicon build | pending | `` | +| Windows x86-64 build | pending | `` | +| Staged candidate manifest and artifact digests | pending | `` | +| Checksums and draft assets | pending | `` | +| Release Validation | pending | `` | +| Linux first-use acceptance | pending | `` | +| macOS Intel first-use acceptance | pending | `` | +| macOS Apple Silicon first-use acceptance | pending | `` | +| Windows first-use acceptance | pending | `` | +| Release-mode integration tests | pending | `` | +| Terminal `Release Candidate Ready` aggregate | pending | `` | + +## Release-specific checks + +Gates this release's scope earns on top of the standard matrix. + +| Gate | Result | Evidence | +| --- | --- | --- | +| `report validate --receipts` green on each platform's first-use run | pending | `` | +| First-use acceptance runs with no provider credential in the environment | pending | `` | +| `shiplog start --yes` then `intake` from an empty directory | pending | `` | +| Piped output (`\| head`) exits 0 on a released binary | pending | `` | + +The credential-free requirement is called out because it was not previously +enforced end to end: the Rust suites cleared `GITHUB_TOKEN` but not `GH_TOKEN` +until #407, so a runner holding `GH_TOKEN` would have satisfied a no-token +claim it never actually tested. The shell and PowerShell install-smoke scripts +have not been audited for the same gap. + +## Publication gates + +- [ ] Exact immutable tag SHA is confirmed. +- [ ] All applicable exact-tag jobs consume one staged candidate set and are green. +- [ ] Terminal `Release Candidate Ready` is green for that exact tag and manifest. +- [ ] GitHub release remains draft before publication approval. +- [ ] crates.io package version and metadata are final. +- [ ] Public asset names and checksums are final. +- [ ] Homebrew and Scoop update inputs are final. +- [ ] Known limitations and deferred work are explicit. + +## Blockers and exceptions + +1. **Candidate not frozen.** No swarm candidate SHA is chosen and the version + is still `0.11.0`. Every downstream identity depends on this. +2. **#245 is open.** Publication is gated on one exact staged four-platform + candidate set with four-platform first-use acceptance, negative controls, + and a terminal readiness aggregate. The source-owned writer projection has + not landed, and no real explicit-tag run has been observed. +3. **Epic #246 Phase 5 is open.** Draft #389, the living release-preparation + procedure, is not yet reviewed and landed. +4. **`shiplog start` is unreleased.** README and the setup guide carry an + explicit caveat that it is absent from the shipped `v0.11.0` binary. That + caveat must be removed as part of the release-preparation PR once `start` + actually ships, or the shipped docs will understate the release. +5. **Not verified, not passed.** Mutation testing, extended fuzzing, and the + scheduled property and BDD suites are advisory for this release. The Windows + `os error 232` broken-pipe arm has unit coverage only. Signing and + notarization are not configured. None of these may be recorded as executed + proof. +6. **Install-smoke credential isolation unaudited.** #407 fixed the Rust + suites; `scripts/release-install-smoke.sh` and `.ps1` were not in scope. + +## Release readiness decision + +`BLOCKED`. + +Blocked on candidate freeze (1) and on the publication prerequisite in #245 +(2). This is the expected state for a Phase 0 ledger: it records intended scope +and the proof still owed, and it confers no authority to tag, publish, sign, or +make anything public. Owner approval remains required after the terminal +`Release Candidate Ready` receipt for one exact staged candidate set. diff --git a/docs/release/0.12.0-release-decision.md b/docs/release/0.12.0-release-decision.md new file mode 100644 index 0000000..5ddcb5d --- /dev/null +++ b/docs/release/0.12.0-release-decision.md @@ -0,0 +1,135 @@ +# shiplog 0.12.0 — Release Decision + +**Release target:** `v0.12.0` +**Theme:** `Setup and everyday commands behave the way the docs already promised.` +**Status:** proposed + +## Decision + +`0.11.0` made the review-readiness loop low-friction to start. Using it since +then surfaced a run of defects concentrated in first use and in the commands +people type most often, and enough of them are now fixed on `main` that holding +them back is the worse option. + +The case for a public release is the user-visible change set, not control-plane +activity: + +- two new commands (`shiplog start`, `shiplog report validate --receipts`) make + this a minor rather than a patch increment; +- several fixes are reachable on the very first command a new user runs, which + is the worst place to leave them; and +- two are correctness defects in the evidence itself — duplicated event ids + across adjacent periods, and a note that the next `update` never collected. + +No release is not a serious option here: `intake | head` exiting 101 and a +`--last-6-months` window that silently drops work recorded today both make the +tool look broken to someone evaluating it. + +## Included boundary + +- **`shiplog start`** — explicit first-use setup that writes the local scaffold + only after `--yes`, with `--dry-run` to preview. Contacts no provider. +- **`shiplog report validate --receipts`** — structurally validates a run's + `packet.md`, `ledger.events.jsonl`, `coverage.manifest.json`, and + `bundle.manifest.json` rather than only checking that they exist, so a + released binary can be proven to emit well-formed artifacts on first use. +- **`Identity` setup readiness item** — `doctor --setup` now reports when + `user.label` or `sources.manual.user` is still the scaffold placeholder, + as a caveat rather than a blocker. +- **Evidence-correctness fixes** — half-open `[since, until)` windows in the + local git and Jira ingestors (#226), so boundary-date items stop being + counted in two adjacent periods with duplicate event ids; and + `--last-6-months` no longer excluding work recorded today, which had made a + note added through `shiplog add` invisible to the very next `shiplog update`. +- **First-use and everyday-command fixes** — no panic and exit 101 when a pager + or `head` closes the pipe; `shiplog add ""` defaulting its date to + today as the flag help already described; date flags naming `YYYY-MM-DD` + instead of reporting `input contains invalid characters`; and GitHub setup + readiness explaining why authentication is unavailable instead of printing + `unavailable via unavailable ... gh_unavailable`. +- **Safety fixes** — GitHub `--api-base` rejecting remote cleartext bases + before any credential lookup or payload send (#234); `github activity merge` + failing closed on a `run_ref` that is not a single plain path segment (#261); + and case-insensitive `SourceSystem::Other` so `"Jira"` and `"jira"` stop + behaving as different sources (#225). +- **Documentation** — the GitHub credential resolution order, including + `GH_TOKEN` precedence, the Enterprise variables, and the `gh` CLI fallback, + none of which appeared in any user-facing document before. + +## Explicitly deferred + +- Provider connection flows for GitLab, Jira, and Linear (`Next Candidates` in + `ROADMAP.md`). Those sources remain configuration-first. +- Share setup ergonomics, including OS-backed redaction key storage. + `SHIPLOG_REDACT_KEY` remains the mechanism. +- Signing and notarization. Checksums are published; neither is claimed. +- Any change to `GH_TOKEN` over `GITHUB_TOKEN` precedence. `0.12.0` documents + the existing behavior rather than altering it. + +## Compatibility and migration + +`none`. + +No configuration, schema, or artifact migration is required, and no command is +removed or renamed. Three behavior changes are worth stating even though none +requires user action: + +- The local git and Jira `--until` boundary is now exclusive, matching every + other window in shiplog. A period boundary that previously produced duplicate + event ids across two adjacent runs now produces one. +- `--last-6-months` now includes work recorded today. +- `shiplog add "<title>"` succeeds without `--date`, defaulting to today. + `journal add` keeps its stricter contract and still requires an explicit date. + +## Safety and proof decision + +- **Required CI:** swarm `Shiplog Rust Small Result` at the exact candidate + head, plus source routed CI after promotion. +- **Fail-closed behavior retained and extended.** `--api-base` rejects remote + cleartext before credential lookup; `github activity merge` rejects a + non-segment `run_ref`; share rendering still blocks without a redaction key. + The stdio panic hook is deliberately narrow — it exits 0 only for a broken + pipe, and a full-disk stdio failure still panics loudly. +- **Security and privacy claims actually exercised:** redaction leak + property tests, the `--api-base` cleartext rejection tests, and the + `run_ref` path-segment guard. Credential resolution is exercised through the + stubbed `gh` harness, not against a live host. +- **Platform matrix:** Linux x86-64, macOS Intel, macOS Apple Silicon, and + Windows x86-64, per the staged candidate contract in #245. +- **Signing/notarization:** not configured. Checksums are not a signing claim. +- **Advisory or unavailable:** mutation testing, extended fuzzing, and the + scheduled property/BDD suites are advisory and must not be presented as + executed proof for this release. The `os error 232` Windows arm of the + broken-pipe classifier is covered by unit test only. + +## Distribution decision + +In scope: + +- crates.io; +- GitHub Release assets with `SHA256SUMS.txt`; +- versionless installers; +- Homebrew; and +- Scoop. + +Deferred: every other package channel, and signing/notarization for all of the +above. + +## Claim boundary + +This decision records that the merged change set justifies a `0.12.0` minor +release and fixes its intended scope. It does not authorize or prove anything +else. + +It does **not** tag, publish to crates.io, upload or publish a GitHub Release, +sign or notarize any artifact, or update Homebrew or Scoop. Those are source +authority under +[`release-preparation.md`](release-preparation.md) and require explicit owner +approval after the terminal `Release Candidate Ready` receipt for one exact +staged candidate set. + +It also does not assert readiness. Readiness is tracked separately in +[`0.12.0-readiness.md`](0.12.0-readiness.md), which is `BLOCKED` until the +candidate is frozen and the exact-tag evidence is observed. No version bump has +been made; per Phase 0 the version and changelog freeze land late, in the final +shared release-preparation PR.