Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions RELEASE_HANDOFF_0.12.0.md
Original file line number Diff line number Diff line change
@@ -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 | `<not frozen>` |
| Source promotion PR / merge | `#<number>` / `<full sha>` |
| Source release-prep PR / merge | `#<number>` / `<full sha>` |
| Release source commit | `<full sha>` |
| Annotated tag | `v0.12.0` |
| Source Release workflow | `<run URL or ID>` |
| Staged candidate manifest | `<artifact/digest>` |
| Terminal candidate-ready aggregate | `<job/result>` |

## Published contents

`<Not published. Write this in user language after publication and link to the
CHANGELOG 0.12.0 section. Intended scope is in the release decision; keep
control-plane receipts in the readiness ledger rather than turning them into
the release story.>`

## Artifact receipt

| Artifact | Observed result |
| --- | --- |
| `shiplog-x86_64-unknown-linux-gnu` | `<asset/checksum/artifact digest>` |
| `shiplog-x86_64-apple-darwin` | `<asset/checksum/artifact digest>` |
| `shiplog-aarch64-apple-darwin` | `<asset/checksum/artifact digest>` |
| `shiplog-x86_64-pc-windows-msvc.exe` | `<asset/checksum/artifact digest>` |
| `SHA256SUMS.txt` | `<asset/checksum/artifact digest>` |

## Validation receipt

- Release preflight: `<result>`
- Release validation: `<result>`
- Four-platform first-use acceptance against one staged set: `<results>`
- Release-mode integration tests: `<result>`
- Terminal `Release Candidate Ready`: `<result>`
- crates.io install and `--version`: `<result>`
- GitHub release public-state verification: `<result>`
- Versionless installers: `<result>`
- Homebrew: `<PR/version/native validation>`
- Scoop: `<PR/version/native validation>`
- Signing/notarization: `not configured`

## Execution record

`<No commands executed. Record only what actually ran, with exact commit and
tag context.>`

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.
129 changes: 129 additions & 0 deletions docs/release/0.12.0-readiness.md
Original file line number Diff line number Diff line change
@@ -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 | `<not frozen>` |
| Source promotion PR | `EffortlessMetrics/shiplog#<number>` |
| Source promotion merge | `<full sha>` |
| Source release-prep PR | `EffortlessMetrics/shiplog#<number>` |
| Release source commit | `<full sha>` |
| 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 | `<run at frozen candidate head>` |
| `cargo xtask ci-small` | pending | `<run or local receipt>` |
| Repository contract report | pending | `<receipt>` |
| Deterministic promotion dry-run | pending | `<receipt hashes / overlay>` |
| Source promotion exact-head CI | pending | `<run>` |
| Promotion `--verify-only` | pending | `<receipt>` |
| Source post-merge CI | pending | `<run>` |
| Package version audit | pending | `<output>` |
| Package boundary audit | pending | `<output>` |
| Package proof | pending | `<run>` |
| Allowlisted publish dry-run | pending | `<run>` |
| Release-hold guard | pending | `<output>` |

## Exact-tag artifact evidence

| Gate | Result | Evidence |
| --- | --- | --- |
| Release Preflight | pending | `<job>` |
| Linux x86-64 build | pending | `<job/artifact>` |
| macOS Intel build | pending | `<job/artifact>` |
| macOS Apple Silicon build | pending | `<job/artifact>` |
| Windows x86-64 build | pending | `<job/artifact>` |
| Staged candidate manifest and artifact digests | pending | `<artifact/manifest>` |
| Checksums and draft assets | pending | `<job>` |
| Release Validation | pending | `<job>` |
| Linux first-use acceptance | pending | `<job>` |
| macOS Intel first-use acceptance | pending | `<job>` |
| macOS Apple Silicon first-use acceptance | pending | `<job>` |
| Windows first-use acceptance | pending | `<job>` |
| Release-mode integration tests | pending | `<job>` |
| Terminal `Release Candidate Ready` aggregate | pending | `<job>` |

## 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 | `<job>` |
| First-use acceptance runs with no provider credential in the environment | pending | `<job>` |
| `shiplog start --yes` then `intake` from an empty directory | pending | `<job>` |
| Piped output (`\| head`) exits 0 on a released binary | pending | `<job or manual receipt>` |

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.
Comment on lines +107 to +108

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the already-landed #389 blocker

Failure mode: The ledger directs release preparation to wait for work that is already complete: commit 08f9331 (docs(release): bind preparation to approved candidate (#389)) is an ancestor of the reviewed commit and introduced the active docs/release/release-preparation.md, so #389 is neither draft nor unlanded. Why here: Listing it under blockers and residual work makes the Phase 0 record stale and may cause operators to wait for or repeat the canonical procedure. Fix direction: Mark #389 as landed and retain only the portions of #246 that genuinely remain. Validation: git merge-base --is-ancestor 08f9331 4264baf exits 0, and the release-preparation file history identifies #389 as its landed commit. Confidence: high.

AGENTS.md reference: AGENTS.md:L48-L53

Useful? React with 👍 / 👎.

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.
Comment on lines +118 to +119

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Drop the already-satisfied credential-isolation exception

Failure mode: This records install-smoke credential isolation as unverified residual work even though, at the reviewed parent, release-install-smoke.sh line 298 unsets both GITHUB_TOKEN and GH_TOKEN, while the PowerShell script lines 289–291 removes both before the no-token first-use path; that logic predates #407. Why here: Release closeout may incorrectly preserve an exception or schedule duplicate remediation for a safeguard already implemented on both platforms. Fix direction: Record the existing script evidence, reserving a pending gate only for any additional behavioral test that is actually missing. Validation: Inspect the two scripts’ no-token sections or execute them with an ambient GH_TOKEN. Confidence: high.

Useful? React with 👍 / 👎.


## 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.
135 changes: 135 additions & 0 deletions docs/release/0.12.0-release-decision.md
Original file line number Diff line number Diff line change
@@ -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 "<title>"` 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.
Loading