hosystem Engagements

ho-04.15 — man pages

created 2026-07-08
status complete
type ho-document
project sharibako
ho 04.15
kamae 5
shape ri

Ships section-1 man pages for the sharibako CLI. The CLI is complete and in daily dogfooding (every verb works against a real vault); what it lacked was man sharibako. This closes that gap by GENERATING the pages from the ParsableCommand tree rather than -authoring troff, so the pages track the code and cannot drift from the actual flags.

Scope is documentation-only: enrich the command definitions, generate, render, iterate the prose, commit. No behavior changes, no new runtime logic (coverage floor untouched — nothing to cover).


Phase 1 —

Decision 1 — Generate, don't hand-author

swift-argument-parser 1.8.2 ships the official GenerateManual plugin (swift package generate-manual; confirmed via swift package plugin --list). The plugin runs the tool with --experimental-dump-help, walks the resulting command tree, and emits mdoc(7) source — one page per command in --multi-page mode. It already produces NAME, SYNOPSIS, the option list (from each @Option/@Argument/@Flag help:), a DESCRIPTION built from abstract + discussion, a SEE ALSO cross-linking a command's own subcommands, and an AUTHORS section from --authors.

The consequence: the man page IS the command definition. The quality work is not troff — it is enriching each CommandConfiguration with a discussion: block and auditing every argument's help:. Hand-writing mdoc would immediately drift from the flags; generation cannot.

Decision 2 — What each discussion: carries

Every command (root + 15 subcommands + 3 key-subcommands = 19 pages) gets a discussion: covering: what the verb does and WHEN to use it versus its sibling verbs (materialize vs. run vs. update; add vs. rotate vs. link; list vs. status vs. scan vs. heal); 2–3 realistic examples; the non-obvious exit codes; and the security note that applies (materialize = plaintext at rest; run exec-replaces and injects env; get prints plaintext to stdout; key export --private). The security framing is pulled straight from SECURITY.md so the two agree.

The root discussion: additionally documents the two resolution orders (vault: --vaultSHARIBAKO_VAULT~/.sharibako/vault; age key: --age-keySHARIBAKO_AGE_KEY → Keychain (macOS) / ~/.config/sharibako/age-key (Linux)), the bootstrap path (sharibako key generate creates key + vault), and the exit-code taxonomy from ExitCode.swift.

Decision 3 — Post-process for cross-links and a bug-report footer

The plugin's SEE ALSO only links a command's own children, so a leaf page (sharibako-run) gets an empty SEE ALSO and no link back to the root or its siblings. scripts/generate-man.sh therefore post-processes each generated page to (a) rewrite SEE ALSO as a full cross-link set (root + every sibling) and (b) append a REPORTING BUGS section pointing at andrew@sageframe.net / the GitHub issues URL, matching the SECURITY.md disclosure policy. The AUTHOR/AUTHORS section is emitted by the plugin from --authors "Andrew Marcus<andrew@sageframe.net>".

Bootstrap assumption (coordinated with ho-04.14)

The root discussion states that sharibako key generate creates the vault. A parallel ho (ho-04.14) is making key generate scaffold the scopes/+shared/ layout — the fix for the known VaultLayout.createVaultLayout-never-called defect noted at the close of ho-04.13. This ho documents the intended behavior; the two land together.


Phase 2 — Execute

Enriched — added a discussion: block to every CommandConfiguration (SharibakoCommand root; add, clean, get, heal, init, key, key generate, key import, key export, link, list, materialize, rotate, run, scan, status, sync, unlink, update) and audited every @Option/@Argument/@Flag help: for completeness and accuracy against the code.

Addedscripts/generate-man.sh: runs the plugin in --multi-page mode, writes section-1 pages to docs/man/, then post-processes SEE ALSO cross-links and the REPORTING BUGS footer. Re-runnable and idempotent (clears stale *.1 first).

Generateddocs/man/*.1, one page per command.

Verification

Gotcha logged for the next session

ArgumentHelp is ExpressibleByStringLiteral, so a help: value must be a single string literal"a" + "b" runtime concatenation does not type-check against it (the discussion: field on CommandConfiguration is a plain String and DOES accept concatenation, which is why the multi-line """ ... """ discussion blocks are fine). Long help: strings were therefore reworded to fit inside the 120-column limit on a single literal line rather than split with +.


Phase 3 —


Authored, executed, and closed 2026-07-08. Man pages generated from the ParsableCommand tree via swift-argument-parser's GenerateManual plugin; packaging onto MANPATH deferred to ho-08.

Rendered from the corpus, verbatim · source on GitHub →

ingested: sharibako @ 75a79d08a2b3 · ho-system @ 0f93b7fa32f7 · the glossary · the colophon