QA tests for the Zipper CLI. Exercises Standard, Loadfile-Only, Chaos Engine, Production Set, Source-Driven Generation, Load File Formats, Archive Test Fixtures, Production Manifest comparison, version output, and CLI boundaries.
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.factory/skills/qa-cli/SKILL.mdZipper is a one-shot .NET CLI, not a persistent TUI. Use the droid-control skill for all terminal interactions. Route a shell through its tuistory backend and tctl wrapper; type each real Zipper invocation into the terminal, press Enter, and inspect the actual output and files. Do not use raw tuistory commands or run test flows in a plain shell outside Droid Control.
In CI, use a unique run-scoped session name and --cols 110 --rows 36. Run the build and each Zipper command through that routed terminal. Prefix each Zipper launch with env -u CI FACTORY_DISABLE_KEYRING=true to avoid Ink CI detection. In the shell session, print APP_EXIT:$? immediately after each Zipper command; save $TCTL -s "$session" snapshot --trim before closing it, using the numbered evidence path in the QA skill. Capture a fresh snapshot for each distinct report case. Type each Zipper launch as a plain top-level command at the prompt — never inside $(…) or a compound export …; out=$(…) line, and never behind a leading VAR=value assignment — and snapshot while that invocation line is still on screen, because the report validator recognizes the executable only in that position. Droid Control owns driver mechanics, Capture, and Verify.
Read .factory/skills/qa/config.yaml on every run. Invoke Compose only when both video_evidence and droid_control.compose are true; never invoke it otherwise.
Set RUN_ID before building. Build only when the CLI is affected:
dotnet publish src/Zipper.csproj -c Release \
-o "./qa-results/$RUN_ID/publish" -p:Version=0.0.0-qa-test -p:InformationalVersion=qa-testThe binary is ./qa-results/$RUN_ID/publish/Zipper (Linux/macOS) or Zipper.exe (Windows). Create each flow's output directory below ./qa-results/$RUN_ID/data/. Do not use the existing publish-bin/ or results/ directories. Preserve evidence under ./qa-results/$RUN_ID/evidence/; clean only this run's data/ and publish/ directories after testing.
The orchestrator chooses relevant flows from this menu based on the diff. These are not a full-suite checklist. Use one default persona, synthetic inputs, and real generated output. For any CLI-path diff, report at least one successful behavior flow and at least one relevant negative or boundary flow. Prefix each Test Case with [positive], [negative], or [boundary] followed by the flow name, and put concise observed evidence in Notes.
Run Zipper with --type pdf --count 20 --output-path ./qa-results/$RUN_ID/data/standard.
Verify successful exit, a non-empty Archive and DAT Load File, exactly 20 PDF Native Files, one header plus 20 records, and ASCII 20 as the DAT column delimiter. Do not assume timestamped output names.
Run --loadfile-only --count 20 --output-path ./qa-results/$RUN_ID/data/loadfile-only.
Verify the DAT Load File contains 20 records and the companion _properties.json Audit File exists. No Archive or Native Files should be generated.
Run --loadfile-only --count 200 --chaos-mode --chaos-amount 10 --output-path ./qa-results/$RUN_ID/data/chaos.
Verify the command succeeds, the Audit File records chaosMode.totalAnomalies as 10, and its injected anomaly list contains 10 records. Deliberately anomalous Load File rows are not expected to parse cleanly.
Run --production-set --count 10 --bates-prefix QA --volume-size 3 --seed 42 --output-path ./qa-results/$RUN_ID/data/production-set.
Find the generated Production Set by its _manifest.json. Verify DATA, NATIVES, IMAGES, and TEXT, both DAT and OPT Load Files, the manifest, 10 generated Native Files, and four VOL001–VOL004 volumes under NATIVES.
Run --type pdf --count 3 --bates-prefix CASE --seed 42 --output-path ./qa-results/$RUN_ID/data/bates.
Verify the Load File contains CASE00000001 through CASE00000003 as consecutive Bates Numbers with eight padded digits.
Run --type pdf --count 100 --target-zip-size 10MB --output-path ./qa-results/$RUN_ID/data/target-size.
Verify the Archive is within the 10MB_100_pdf tolerance in tests/fixtures/target-zip-size-tolerances.json (0.0031 relative deviation) and no generated file exceeds the test's target/count*10 padding-spread bound. Confirm success without an impossible-size error. Use the real Archive size, not the generated-file count, as evidence.
Create a small Source CSV with ControlNumber, FilePath, and FileType columns, covering PDF, EML, and TIFF. Run with --input-csv <source.csv> --seed 42 --output-path ./qa-results/$RUN_ID/data/source-csv.
Verify each Source Record produces one matching Native File and Load File row, preserving its relative File Path and File Type. For a Directory Template, create nested files with supported extensions, run with --directory-template <path>, and verify the nested structure is represented in the Archive. Include a sentinel in a source file and confirm source bytes were not copied into the generated Archive.
Run a small Standard Mode generation for each dat, opt, csv, xml, and concordance value of --load-file-format, each with its own output directory.
Verify the expected .dat, .opt, .csv, .xml, or Concordance .dat file exists and contains five records. Confirm OPT has no header, CSV uses valid quoting, XML parses as EDRM-XML, and Concordance uses its expected header and delimiters.
Run --archive-test-suite smoke --seed 42 --output-path ./qa-results/$RUN_ID/data/archive-fixtures into a new directory.
Verify the frozen smoke suite produces five flat .zip / .json Archive Test Fixture pairs, each basename matches its Fixture ID in the Expectation File, every Expectation File parses as JSON, and the missing-eocd Archive is unreadable by a reference ZIP reader while its sidecar remains readable.
Generate a five-record prior Production Set with --production-set --count 5 --bates-prefix SUPP --output-path <prior-dir>. Generate a second five-record supplemental Production Set with --production-set --supplemental-production --prior-manifest <prior-manifest> --count 5 --bates-prefix SUPP --bates-start 6 --output-path <supplemental-dir>.
Run --compare-production-manifests <prior-manifest>,<supplemental-manifest> --comparison-mode replacement --comparison-output <report.json>.
Verify the report parses as JSON and its summary reports five prior records, five new records, five Added records, five Removed records, and zero unchanged records.
Run --version. Verify exit code 0, the Zipper vqa-test prefix, and the repository URL https://github.com/dwojtaszek/zipper/.
Run --type invalid --count 1 --output-path ./qa-results/$RUN_ID/data/invalid-type.
Verify nonzero exit, a clear validation error (not an unhandled exception), and no Archive output.
--help flag. Zipper prints usage when invoked without arguments; --version is the supported informational flag.--bates-prefix; --production-set conflicts with --loadfile-only.--chaos-mode is parameterless and requires --loadfile-only; --chaos-amount is a separate value.--target-zip-size requires --count only when neither --input-csv nor --directory-template supplies Source Records. An impossible target is rejected. Compare achieved size with the scenario's committed tolerance.FilePath and FileType are required in the Source CSV. Source bytes must not be copied into generated Archives.--archive-test-suite, optional --archive-test-cases, --seed, and required --output-path are accepted. The output path must be new.--comparison-mode, and --comparison-output. Its three flags remain strictly validated.qa-results/$RUN_ID/data/ tree; do not write to absolute paths or shared results/ and publish-bin/ directories.dwojtaszek/zipper
5b08822
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.