Skip to main content
← Back to list
01Issue
FeatureShippedUAT
Assigneesstack72

Relationships

#1096 UAT Phase 1e: report family verb gap-fill

Opened by stack72 · 7/11/2026· Shipped 7/11/2026

Summary

Phase 1e fills the remaining coverage gaps in the report command family. The report family already has dedicated coverage for get, describe, and search (stored report results). This phase adds: report type search (the type catalog) and report list (which invokes the same action as type search).

This is the smallest Phase 1 sub-package — 2 new test files. All files land in the existing model-vault-config-report CI shard.

Dependency

Phase 8a (issue #1059) is landed. No other dependencies.

Existing State (do NOT duplicate)

These report test files already exist:

  • tests/cli/report/describe_test.ts
  • tests/cli/report/get_test.ts
  • tests/cli/report/search_test.ts

e2e with report coverage:

  • tests/cli/e2e/report_lifecycle_test.ts

The tests/cli/report/type/ directory needs creating.

Verified Contracts

  • report type search and report list invoke the SAME action — the registered report-TYPE catalog (NOT stored report results)
  • JSON: {query, results:[{type, name, description, scope}]}
  • Auto-JSON when piped (non-TTY, per §4.2 interactivity rules)
  • The query arg filters the catalog
  • Hidden list alias exists (identical output to type search)

report list

  • report list is a top-level alias for report type search — same action, same output
  • It does NOT list stored report results (that's report search) — this is a meaningful distinction to assert explicitly
  • Same JSON shape as report type search

Key distinction to test

  • report search → queries stored report RESULT artifacts (data records tagged with reportName/reportScope)
  • report type search / report list → queries the report TYPE catalog (extension-provided report types)

These are completely different actions that return different shapes — the naming is confusing, which is exactly why we pin it.

New Test Files

report/type/search_test.ts (NEW)

  • Catalog listed: at minimum the built-in report types appear; if a report-kind extension fixture is installed, its type also appears
  • Query filter: report type search <query> narrows results
  • JSON shape validated: {query, results:[{type, name, description, scope}]}
  • Hidden list alias parity: report type list output ≡ report type search output
  • Auto-JSON when piped (assert JSON output without --json flag when stdin is not TTY)
  • Empty query → full catalog
  • Exit codes: always 0 (search/catalog never fails on no results)

report/list_test.ts (NEW)

  • report list output ≡ report type search (same action, same JSON shape)
  • Explicit negative assertion: report list does NOT return stored report results — run a report to produce results, then verify report list does NOT contain them (contrast with report search which would)
  • JSON shape matches report type search exactly (same schema)
  • Exit codes: always 0

Schemas

Add to src/cli/helpers/schemas.ts:

  • ReportTypeCatalogSchema{query, results:[{type, name, description, scope}]} (used by both report type search and report list)

Use .passthrough() (matching existing codebase convention).

Ground Rules

  • Read CLAUDE.md in the repo root first — its rules apply everywhere
  • Tests are more accurate than the code under test. Assert the documented contract. If swamp disagrees, the test stays red and you file the discrepancy upstream with swamp issue bug and reference it in a test comment.
  • Use the github-pr skill for commits and PR creation
  • Task 0 — ground truth: Before writing any test, build tip-of-main swamp and run each command by hand (report type search, report type search <query>, report list, all with --json and piped). Read the command definitions in ~/code/swamp-club/swamp/src/cli/commands/. Note any drift.
  • Check open swamp-uat PRs for in-flight work first
  • Use grep -rl "report type search\|report list" tests/cli/ before writing to confirm no existing coverage

Test Pattern

import { assertEquals } from "@std/assert";
import {
  createRunnerFromEnv,
  runCommand,
  runJsonCommand,
  withInitializedRepoContext,
} from "@swamp-uat/helpers";

const runner = createRunnerFromEnv();

Deno.test("swamp report type search lists the report type catalog", () =>
  withInitializedRepoContext(runner, async (repo) => {
    const result = await runJsonCommand(runner, repo.dir,
      ["report", "type", "search"], ReportTypeCatalogSchema);
    // Assert results array contains at least one type
    // Assert each item has type, name, description, scope
  }));

Every test MUST:

  • Spawn the real swamp binary
  • Assert an explicit exit code
  • Validate --json output through a Zod schema

How to Run & Verify

# 1. Format, lint, type-check
deno task fmt
deno task lint
deno task check

# 2. Framework unit tests (CI guard)
deno task test

# 3. Run report tests directly
SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno test --allow-read --allow-write --allow-env --allow-run --allow-net tests/cli/report/

# 4. Full CLI suite
SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno task uat:cli

CI Shard Wiring

New tests/cli/report/type/ directory is automatically covered by the model-vault-config-report shard (path: tests/cli/report/). New report/list_test.ts is also under tests/cli/report/. No CI changes needed.

Definition of Done

  • 2 test files created: report/type/search_test.ts and report/list_test.ts
  • ReportTypeCatalogSchema added to src/cli/helpers/schemas.ts
  • Every test spawns the real swamp binary — no mocking
  • Every test asserts an explicit exit code
  • Every --json test validates through a Zod schema
  • Explicit negative assertion: report list ≠ stored results
  • Hidden list alias parity tested in type/search_test.ts
  • deno task fmt && deno task lint && deno task check && deno task test all green
  • SWAMP_NO_TELEMETRY=1 SWAMP_SOURCE_DIR=~/code/swamp-club/swamp deno task uat:cli passes
  • PR opened via github-pr skill, branching from main
02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 4 MOREPR_MERGED+ 1 MORENOTIFICATION_SKIPPED

Shipped

7/11/2026, 9:47:52 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack727/11/2026, 9:04:42 PM

Sign in to post a ripple.