Implementation Plan: CascadeGuard CLI v2
Overview
Align the CascadeGuard CLI (v0.1) with the published getting-started docs. Changes are ordered to build incrementally: alias first, then command rename, then new init command, then unified check, then cleanup of deprecated commands/workflows, then tests.
Tasks
-
1. Add
cgalias entry point- 1.1 Add
cgentry point topyproject.toml- In
repos/cascadeguard/app/pyproject.toml, addcg = "app:main"under[project.scripts]alongside the existingcascadeguardentry - Requirements: 1.1
- In
- 1.2 Add
cgsymlink toinstall.sh- In
repos/cascadeguard/install.sh, update thelink_to_pathfunction to also create acgsymlink pointing to the same venv binary - Ensure both
cascadeguardandcgare symlinked intoLINK_DIR - Requirements: 1.3
- In
- [ ]* 1.3 Write unit test for
cgalias equivalence- Property 1: cg and cascadeguard alias equivalence
- Verify both entry points resolve to the same
app:mainfunction - Validates: Requirements 1.1, 1.2
- 1.1 Add
-
2. Rename
cicommand group tobuild- 2.1 Replace
ciparser withbuildparser inapp.py- In
repos/cascadeguard/app/app.py, rename thecisubparser tobuildinbuild_parser() - Change
ci_sub/ci_command/ci_generatevariable names tobuild_sub/build_command/build_generate - Remove the old
ciparser registration entirely - Requirements: 3.1, 3.4
- In
- 2.2 Update dispatcher functions in
app.py- Rename
cmd_citocmd_build_dispatch(or similar) and update it to dispatch onargs.build_command - Rename
cmd_ci_generatetocmd_build_generate - Update the
commandsdict inmain()to map"build"instead of"ci" - Requirements: 3.1, 3.2
- Rename
- [ ]* 2.3 Write unit test for
build generatecommand- Property 5: build generate produces identical output to former ci generate
- Verify
cg build generateinvokesgenerate_ciwith the same arguments as the oldcg ci generate - Validates: Requirements 3.2, 3.3
- 2.1 Replace
-
3. Checkpoint — Verify alias and rename
- Ensure all tests pass, ask the user if questions arise.
-
4. Implement
cg initcommand- 4.1 Add
cmd_initfunction inapp.py- Implement
cmd_init(args) -> intthat:- Clones the seed repo (
cascadeguard-seed) to a temp directory - Walks all files in the clone (excluding
.git/) - For each file: if it exists in target dir, skip with stderr warning; otherwise copy it
- Handles
.gitignore: create with.cascadeguard/.cache/if missing, append entry if file exists but lacks it, leave unchanged if already present - Prints summary:
N files copied, M skipped - Returns 0 on success, 1 on clone failure
- Clones the seed repo (
- Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8
- Implement
- 4.2 Register
initsubcommand inbuild_parser()- Add
initto the top-level subparsers inbuild_parser()with optional--target-dirargument (default.) - Add
"init": cmd_initto thecommandsdict inmain() - Requirements: 2.1
- Add
- [ ]* 4.3 Write property test for init file copy/skip behavior
- Property 2: Init copies new files and skips existing files
- Given a mock seed repo and a target dir with some pre-existing files, verify new files are copied and existing files are untouched
- Validates: Requirements 2.1, 2.2
- [ ]* 4.4 Write property test for init .gitignore idempotence
- Property 3: Init .gitignore idempotence
- Test three cases: no .gitignore, .gitignore without cache entry, .gitignore with cache entry
- Verify exactly one
.cascadeguard/.cache/entry exists after init and pre-existing content is preserved - Validates: Requirements 2.3, 2.4, 2.5
- [ ]* 4.5 Write unit test for init summary counts
- Property 4: Init summary counts match file disposition
- Verify printed summary matches actual copied/skipped counts
- Validates: Requirement 2.6
- 4.1 Add
-
5. Checkpoint — Verify init command
- Ensure all tests pass, ask the user if questions arise.
-
6. Unify
images checkcommand- 6.1 Absorb
check-upstreamlogic intocmd_checkinapp.py- Extend the existing
cmd_checkfunction to add a Phase 4 after digest drift checking:- Query Docker Hub for new upstream tags on each enrolled image (port logic from
cmd_images_check_upstream) - Append upstream tag findings to the results list with status
"new-tags" - Update exit code logic: return 1 if drift OR new tags found
- Query Docker Hub for new upstream tags on each enrolled image (port logic from
- Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8
- Extend the existing
- 6.2 Add
--formatand--imageflags toimages checkparser- Ensure
images checkparser has--format(choices:table,json, default:table) and--image(optional filter) - Implement table and JSON output rendering in
cmd_check - Requirements: 4.9, 4.10, 4.11, 7.1, 7.2, 7.3
- Ensure
- [ ]* 6.3 Write property test for exit code correctness
- Property 10: Exit code reflects drift and upstream tag status
- Verify exit code 1 iff drift or new-tags present, 0 otherwise
- Validates: Requirements 4.7, 4.8
- [ ]* 6.4 Write property test for image filter scoping
- Property 12: Image filter scoping
- Verify
--image <name>restricts output to only that image - Validates: Requirement 4.11
- [ ]* 6.5 Write unit test for output format completeness
- Property 11: Output format completeness
- Verify both table and JSON formats include image name, status, and details for every result
- Verify JSON output is valid JSON
- Validates: Requirements 7.1, 7.2
- 6.1 Absorb
-
7. Remove
check-upstreamsubcommand and workflow- 7.1 Remove
check-upstreamfromimagesparser inapp.py- Remove the
images_check_upstreamparser registration frombuild_parser() - Remove
"check-upstream": cmd_images_check_upstreamfrom thecmd_imagesdispatch dict - Optionally keep
cmd_images_check_upstreamfunction body for reference or remove entirely - Requirements: 5.1, 5.2
- Remove the
- 7.2 Delete
check-upstream-tags.yamlworkflow from open-secure-images- Delete
repos/cascadeguard-open-secure-images/.github/workflows/check-upstream-tags.yaml - Requirements: 6.1, 6.2
- Delete
- 7.1 Remove
-
8. Update existing tests for all changes
- [ ]* 8.1 Update
test_app.pyfor renamedbuildcommand and removedci/check-upstream- Update any tests referencing
ci generateto usebuild generate - Remove or update tests for
images check-upstream - Add test that
cicommand is no longer recognized by the parser - Add test that
images check-upstreamis no longer recognized - Requirements: 3.4, 5.2
- Update any tests referencing
- [ ]* 8.2 Update
test_generate_ci.pyif it references CLI entry points- Ensure generate_ci tests still pass (the underlying function is unchanged, only the CLI entry point name changed)
- Requirements: 3.2
- [ ]* 8.3 Write integration test for unified
images checkwith mock registry- Test the full check flow: load images.yaml, parse Dockerfiles, write state, check drift, check upstream tags
- Mock registry responses to test both drift and no-drift scenarios
- Property 9: Drift detection correctness
- Validates: Requirements 4.5, 4.6, 4.7, 4.8
- [ ]* 8.1 Update
-
9. Final checkpoint — Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
Notes
- Tasks marked with
*are optional and can be skipped for faster MVP - Each task references specific requirements for traceability
- The implementation language is Python, matching the existing codebase
- Checkpoints ensure incremental validation after each major change
- Property tests validate universal correctness properties from the design document
- The underlying
generate_ci.pymodule is unchanged; only the CLI entry point is renamed