Add apw doctor --bundle redacted diagnostic export#62
Conversation
Closes #56. Introduces an `apw doctor --bundle <path>` flag that writes a tar.gz operators can attach to support requests without leaking credentials. Layout (apw-doctor-bundle/): - manifest.json bundleVersion, file list, redaction guarantees - doctor.json full `apw doctor --json` payload - environment.json `apw doctor --ci` environment checks - os.json uname + sw_vers on macOS - native-app/file-listing.json metadata-only listing of ~/.apw/native-app/ Redaction guarantees: - env vars never read or copied - no file contents from ~/.apw/native-app/ (only path/size/mode/type) - credentials.json, config.json, broker.log explicitly excluded - every string in the staged JSON is scanned for token-like patterns (long high-entropy alphanumeric runs, vendor key prefixes such as ghp_/AKIA/sk-, and the in-tree demo password sentinel); a match aborts the bundle with an InvalidConfig (102) error and the archive is never written - archive file is mode 0600 Bundle staging happens under the system temp dir (not under ~/.apw/native-app/) so it cannot race the file-listing walk and leak its own UUID-suffixed name into the metadata. Tar is invoked via `std::process::Command` to keep dependencies unchanged. Tests: - 5 unit tests in src/bundle.rs covering the redaction heuristic (paths, version strings, and explicit secret patterns) and the fail-closed audit - 2 e2e tests in tests/native_app_e2e.rs that - write a plausible-secret credentials.json, build the bundle, and grep every extracted byte for the secret (none survives) - inject a sentinel into APW_RUNNER_LABELS and confirm the bundle aborts with InvalidConfig and never writes the archive Docs: - docs/SECURITY_POSTURE_AND_TESTING.md describes layout and redaction guarantees - README.md adds the flag to the common-commands list
There was a problem hiding this comment.
💡 Codex Review
Lines 472 to 476 in 3160bfd
--ci from silently skipping bundle creation
run_doctor returns immediately when args.ci is set, so apw doctor --ci --bundle <path> exits सफल without ever attempting write_diagnostic_bundle. This creates a silent success path where operators think a bundle was produced but no archive exists; either mark these flags as conflicting in clap or explicitly error when both are provided.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
pheidon
left a comment
There was a problem hiding this comment.
I cannot approve this yet. The --ci path still returns before --bundle is handled, so apw doctor --ci --bundle <path> exits successfully without writing the requested archive. That is a silent-success failure for the exact operator workflow this PR adds.
Please either make --ci and --bundle conflict at the clap layer, or return an explicit error when both are supplied. The existing CI is green, but this behavior remains a release blocker for the bundle flag.
…dle-56 # Conflicts: # docs/SECURITY_POSTURE_AND_TESTING.md
|
Requested-change follow-up is addressed and ready for re-review.
Verification recorded on the PR:
|
Summary
Implements
apw doctor --bundle <path>per #56. Operators can now produce asingle redacted tarball to attach to support requests instead of copy-pasting
each output stream individually.
Closes #56.
Layout
The archive file is written mode
0600. Bundle staging happens under thesystem temp dir (not under
~/.apw/native-app/) so it cannot race thefile-listing walk and leak its own UUID-suffixed name into the metadata.
Redaction guarantees
~/.apw/native-app/are never read; only the metadata listing is included.credentials.json,config.json, andbroker.logare explicitly excluded.Review follow-up
--cinow conflicts with--bundleat the clap layer soapw doctor --ci --bundle <path>cannot silently exit without writing the archive.Verification
cargo fmt --checkcargo clippy --all-targets -- -D warningscargo testcargo test --manifest-path rust/Cargo.toml cli::tests::doctor_ci_and_bundle_are_mutually_exclusive -- --nocapturecargo test --manifest-path rust/Cargo.toml --test native_app_e2e doctor_ci_and_bundle_fail_before_writing_archive -- --nocapturebash scripts/ci/run-fast-checks.shNotes