Renames the written-usage rule into practice across the contract surface: docs/ (architecture, research, plans, sdd), tasks/ (all 43 task files, taskgraph validate passes), AGENTS.md, README.md, CHANGELOG.md, and the .opencode/agents/ prompts. Every replacement is a sense-preserving rewrite (colons, semicolons, commas, parentheses, sentence splits, varied), never a mechanical swap; no spaced hyphens were substituted. Enum fields, frontmatter, tables, wire data, and cited identifiers survive verbatim; en dashes inside numeric ranges keep their meaning. Verification: taskgraph validate (43 tasks), repo grep clean (single exempt hit: the verification command's own search pattern in AGENTS.md), cargo test, clippy --all-targets -D warnings, fmt --check, doc all green.
232 lines
12 KiB
Markdown
232 lines
12 KiB
Markdown
---
|
||
id: w5-release-readiness
|
||
name: "Wave 5: release readiness (docs, feature matrix, CHANGELOG/README, dry-run)"
|
||
status: completed
|
||
depends_on: [w5-decline-matrix, w5-e2e-server, w5-e2e-client, w5-fuzz-harness]
|
||
scope: moderate
|
||
risk: low
|
||
impact: phase
|
||
level: implementation
|
||
---
|
||
|
||
## Description
|
||
|
||
Everything the publish needs except the publish itself
|
||
(`docs/plans/implementation.md` §Wave 5, the release-readiness
|
||
bullet; the alkgit `w5-release-readiness` shape):
|
||
|
||
- **Crate docs**: public-API rustdoc warning-free (default build +
|
||
`--all-features`; the pre-existing `client_ops.rs` private-link
|
||
warnings resolved or explicitly dispositioned); the docs-honesty
|
||
pass: module docs name each surface's postures and known limits
|
||
(the recorded limits ride the published docs: the `write_all`
|
||
no-deadline record, the PTY rule-5 fidelity limit, the port-0-only
|
||
mint wire fact, the no-reconnect-policy boundary, the no-accept-all
|
||
policy posture); crate-level docs state the feature graph and the
|
||
fail-closed invariant.
|
||
- **README.md**, which lands (none exists): what the crate is (the
|
||
two-direction door), the feature graph + the fail-closed posture
|
||
(a default build has no capabilities), minimal compile-checked
|
||
usage examples (a server mount + a dial), the custody/security
|
||
posture summary (vault-backed keys, no env vars, no secret
|
||
material on the wire), the license note.
|
||
- **CHANGELOG.md**: the 0.1.0 entry summarizing the plan's landing
|
||
per wave (the file exists; the entry lands).
|
||
- **The feature matrix**: `default` / each feature over it /
|
||
`--all-features`: test + clippy + doc green (the matrix runner
|
||
from `w5-decline-matrix` if it landed the vehicle, one command).
|
||
- **The publish dry-run**: `cargo publish --dry-run --allow-dirty`;
|
||
the packaged file list verified against the package policy (the
|
||
`exclude` list: the architecture docs ship as the authoritative
|
||
contract; the process surface (plans/research/reviews/tasks/
|
||
AGENTS.md/`.opencode`) does not); the manifest sanity (version
|
||
0.1.0, `rust-version` 1.89, edition 2024, license files present,
|
||
the pins as ADR-002 records them).
|
||
- **The freeze inventory**, the list of what the publish makes
|
||
one-way (the wire-relevant surfaces: the mapping contracts, the
|
||
honest-advertisement posture, the decline-matrix behavior, the
|
||
fingerprint string format, the russh pin's wire posture) recorded
|
||
for the gate's read, because the semver-relevant surface is frozen at
|
||
the
|
||
publish, so the gate reads this list against the landed code
|
||
before `w5-publish` executes.
|
||
|
||
## Acceptance Criteria
|
||
|
||
- [x] `cargo doc --no-deps` (+ `--all-features`) warning-free or
|
||
every residual dispositioned; the docs-honesty pass complete
|
||
(the known-limits records ride the published docs)
|
||
- [x] README.md landed (what/why, feature graph + fail-closed,
|
||
compile-checked examples, custody posture, license)
|
||
- [x] CHANGELOG.md's 0.1.0 entry landed
|
||
- [x] The feature matrix green (default / each feature /
|
||
`--all-features`: test + clippy + doc)
|
||
- [x] `cargo publish --dry-run --allow-dirty` clean; the packaged
|
||
file list verified against the package policy; manifest sanity
|
||
recorded
|
||
- [x] The freeze inventory recorded for the gate
|
||
|
||
## References
|
||
|
||
- docs/plans/implementation.md §Wave 5 (the release-readiness
|
||
bullet), §Scope authority (v0.1.0 publishes the crate)
|
||
- Cargo.toml (the package policy exclude list; the manifest ADR-002
|
||
landed), CHANGELOG.md, LICENSE-MIT / LICENSE-APACHE (present)
|
||
- docs/architecture/ (what ships as the authoritative contract),
|
||
docs/architecture/decisions/002-russh-pin.md (the pin the manifest
|
||
records)
|
||
- /workspace/@alkdev/alkgit (the sibling release shape: README,
|
||
CHANGELOG, the publish checklist's dry-run posture)
|
||
|
||
## Notes
|
||
|
||
**Crate docs.** `cargo doc --no-deps` is warning-free on both the
|
||
default build and `--all-features`. The pre-existing doc-link debt is
|
||
resolved (not dispositioned): 9 warnings (1 duplicate) at
|
||
`--all-features`: the `client_ops.rs` private-link class
|
||
(`crate::tty_map` / `crate::dispatch` / `crate::git_map`, private
|
||
modules; de-linked to backtick prose), the two
|
||
`rustdoc::redundant_explicit_links` spans (the `(client_ops::…)`
|
||
destinations on the `lib.rs` re-export docs and two
|
||
`[`TunnelChannel`](crate::TunnelChannel)` + `with_tunnel_surface` /
|
||
`KeySourceError::Decryption` same-item links in
|
||
`client_accept.rs`/`client_handler.rs`/`error.rs`), the broken
|
||
`TerminalParamsWire` path (now a resolution-correct target through
|
||
its wrapped re-export form) and the unresolved `Limits::…`
|
||
intra-doc link (now `crate::Limits::…`); plus the twin
|
||
duplicated "report is sent before close" paragraph in `tty_map.rs`
|
||
removed one. **Docs honesty:** the five recorded limits now ride the
|
||
*published* docs (the crate-root rustdoc §Known limits: the
|
||
`write_all` no-deadline record, the PTY rule-5 upstream fidelity
|
||
limit, the port-0-only mint echo wire fact, the no-reconnect-policy
|
||
boundary, the no-accept-all policy posture) with their module-doc
|
||
mirrors verified still in place (`tty_map.rs`, `exit_code.rs`
|
||
rule 5, `client_accept.rs`/`tunnel_map.rs`, `client.rs`
|
||
§Lifecycle posture, `host_key.rs`); crate-level docs state the
|
||
feature graph (each feature's row + the `default = []` decline-only
|
||
fact + no-feature-implies-another + honest advertisement) and the
|
||
fail-closed invariant.
|
||
|
||
**Compile-checked examples.** Two `no_run` doctests in the
|
||
crate-root docs (they run in every matrix build, and the publish task's
|
||
verification set keeps them compile-checked with zero extra
|
||
vehicle): a server mount (`ServeConfig::new` → `SshAdapter::new` →
|
||
`adapter.handle`, on the default build, with sketch key/identity seams
|
||
returning `Absent`/`None`, prose points at the vault-backed shapes)
|
||
and a dial (`dial(DialConfig)` → `close()`, the op rows referenced in
|
||
prose with the feature gate noted; `RejectAll` named as
|
||
connects-to-nothing by design). README mirrors them.
|
||
|
||
**README.md.** Landed (none existed): what the crate is (the
|
||
two-direction door, russh owns the wire, door-not-backend), the
|
||
feature matrix table + the fail-closed posture (a default build serves
|
||
nothing but declines; unset-config declines; never advertised), the
|
||
two usage sketches (mirroring the doctests), the custody/security
|
||
posture summary (vault-backed sources, encrypted at rest, decrypted
|
||
at use, zeroized; no env vars, no secrets on the wire; publickey-only
|
||
single attempt; fail-closed host-key default with no accept-all;
|
||
ACL-gated surface; bounded resources + the known-limits pointer; the
|
||
decline matrix as contract), the docs pointers, the license note.
|
||
|
||
**CHANGELOG.md.** The 0.1.0 entry landed (founding entry, dated
|
||
2026-10-30): the crate story (the two-direction door, the flat
|
||
fail-closed graph, ADR-003) + the posture statement, then the
|
||
landed surface wave by wave: the phase 0/1 contract, waves 1–5
|
||
(foundations, server stack, server mappings/spine, client direction,
|
||
validation+release), plus Notes (the sftp decline-only feature fact,
|
||
the OQ-09 env posture, the russh-pin one-way-door record). Only
|
||
served surface is listed; the never-features
|
||
(x11/`auth-agent`/subsystem/`env`) are named as the declines they
|
||
are.
|
||
|
||
**Feature matrix** (`scripts/matrix.sh`, the one command): all six
|
||
builds' `cargo test` green (none / git / session / tunnel / sftp-only
|
||
/ `--all-features`, with 108 result-ok reports across the matrix,
|
||
including both doctests per build), clippy ×2 (`--all-targets -D
|
||
warnings`, with and without `--all-features`) clean, `cargo fmt
|
||
--check` clean, `cargo doc --no-deps` clean; plus the fuzz corpus
|
||
gate (`cargo test --manifest-path fuzz/shared/Cargo.toml`, all 11
|
||
invariants green).
|
||
|
||
**Publish dry-run.** `cargo publish --dry-run --allow-dirty` clean,
|
||
with 76 files packaged and verified (the packaged tree compiles), upload
|
||
aborted by dry run as expected. The packaged file list verified
|
||
against the package policy (`cargo package --list`): exactly `src/`
|
||
(20 files), `tests/` (+ `common/` doubles + `vectors/`), the
|
||
architecture docs (`docs/architecture/`, the authoritative
|
||
contract), `README.md`, `CHANGELOG.md`, `LICENSE-MIT` /
|
||
`LICENSE-APACHE`, the manifests (`Cargo.toml`/`.orig`,
|
||
`Cargo.lock`, `.gitignore`, `.cargo_vcs_info.json`) and
|
||
`scripts/matrix.sh` (the verification tooling, not process surface);
|
||
none of the excluded surface appears (`.opencode/`, `AGENTS.md`,
|
||
`docs/reviews|plans|research/` / `docs/sdd_process.md`, `tasks/`,
|
||
`fuzz/` are all absent from the list). **Manifest sanity recorded:** version 0.1.0
|
||
(no bump, as `w5-publish` verifies), `rust-version` 1.89, edition
|
||
2024, `license = "MIT OR Apache-2.0"` with both license files
|
||
present, the pins as ADR-002 records them (russh 0.65
|
||
`default-features = false` + `aws-lc-rs`; alkcall 0.10; alkvault
|
||
0.1; the per-feature optional siblings alktty 0.8.1 / alkgit 0.1.0 /
|
||
alktunnels 0.4.1), the feature graph exactly ADR-003's, the
|
||
package-policy `exclude` list in place.
|
||
|
||
**The freeze inventory (for `review-wave-5` and `w5-publish`, the
|
||
surfaces the 0.1 publish makes one-way; further wire-relevant change
|
||
is a new ADR + a semver event):**
|
||
|
||
1. **The mapping contracts**, the channel-type → family-protocol
|
||
row semantics as landed (`docs/architecture/mapping.md` executed
|
||
by `dispatch.rs`/`tty_map.rs`/`git_map.rs`/`tunnel_map.rs`/
|
||
`client_ops.rs`): the route-1 bridge flow (open-direct →
|
||
accept-after-fabric-success), the exec-only git grammar + its
|
||
verdicts, the parse-only dispatch + the translation bridge
|
||
(chunk framing, the zero-length stdin sentinel, the
|
||
negotiation-error frame → 255), the exit derivation rules 1–6,
|
||
the client op-row planes (the family chunk/duplex surfaces, the
|
||
acceptor registry + payload types, the lifecycle primitives).
|
||
2. **The honest-advertisement posture**, the fail-closed invariant
|
||
as behavior: an unfeatured/unimplemented channel type is declined
|
||
(never advertised, never half-served); a default build serves
|
||
declines only; the `sftp` placeholder stays a decline in every
|
||
build (OQ-13).
|
||
3. **The decline-matrix behavior**, the decline classes and shapes:
|
||
the `OpenDeclineReason` vocabulary as exposed, the
|
||
spawned-`channel_failure`-then-close serving-path shape, the
|
||
`ConnectFailed` fabric reject, teardown-at-birth, the
|
||
token-collision refusal, the config-driven
|
||
(`seam-unconfigured`/unset-field) declines, the always-`sftp`
|
||
decline row, as pinned by the matrix suite.
|
||
4. **The fingerprint string format**, the `SHA256:` contract
|
||
format of `crate::fingerprint()` (the crate's single fingerprint
|
||
path): both the auth bridge's identity resolution and the
|
||
host-key policy's exact-string pin comparison consume it;
|
||
changing the format breaks every pin store and is a one-way door.
|
||
5. **The russh pin's wire posture**, russh 0.65.0 with
|
||
`aws-lc-rs` (no compression, `rsa` off, `des`/`dsa` never): the
|
||
kex/algorithm negotiation surface crosses the crate boundary, so
|
||
the pin is wire-relevant per ADR-002, and a bump is a deliberate,
|
||
tested, recorded event. (The `alk/ssh` ALPN pin, ADR-001, is
|
||
already its own ledger one-way door; the auth surface ships as
|
||
publickey-only, exactly one attempt.)
|
||
|
||
## Summary
|
||
|
||
Release readiness landed. Crate docs: warning-free × builds
|
||
(default + `--all-features`), the 9-warning doc-link debt resolved in
|
||
place (`client_ops.rs`'s private-link class among them), the
|
||
docs-honesty pass riding the published crate-root rustdoc (§Known
|
||
limits: the five recorded dispositions (`write_all` no-deadline, PTY
|
||
rule-5, port-0-only mint echo, no-reconnect policy, no-accept-all)
|
||
with module-doc mirrors verified) and crate-level docs stating the
|
||
feature graph + fail-closed invariant; two `no_run` usage doctests
|
||
(server mount + dial) keep the README examples compile-checked in
|
||
every matrix build. README.md landed; CHANGELOG.md carries the 0.1.0
|
||
founding entry (wave-by-wave, honest advertisement). The feature
|
||
matrix is green end to end (six test builds, clippy ×2, fmt, doc) +
|
||
the fuzz corpus gate (11 invariants). `cargo publish --dry-run
|
||
--allow-dirty` clean (76 files packaged + verified; the file list
|
||
checked against the package policy, so that architecture docs ship and the
|
||
process surface does not; manifest sanity recorded). The freeze
|
||
inventory (mapping contracts, honest advertisement, decline-matrix
|
||
behavior, fingerprint format, russh pin posture) is recorded above
|
||
for the gate's read. Ready for `review-wave-5`; `w5-publish`
|
||
executes only over a green gate. |