Files
alkssh/tasks/implementation/w5-release-readiness.md
glm-5.3-flash f4b5f896b4 docs: sweep em dashes from all markdown prose
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.
2026-11-04 20:28:00 +00:00

12 KiB
Raw Permalink Blame History

id, name, status, depends_on, scope, risk, impact, level
id name status depends_on scope risk impact level
w5-release-readiness Wave 5: release readiness (docs, feature matrix, CHANGELOG/README, dry-run) completed
w5-decline-matrix
w5-e2e-server
w5-e2e-client
w5-fuzz-harness
moderate low phase 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

  • 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)
  • README.md landed (what/why, feature graph + fail-closed, compile-checked examples, custody posture, license)
  • CHANGELOG.md's 0.1.0 entry landed
  • The feature matrix green (default / each feature / --all-features: test + clippy + doc)
  • cargo publish --dry-run --allow-dirty clean; the packaged file list verified against the package policy; manifest sanity recorded
  • 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.