Skip to content

feat(doctor): redesign output with grouped sections, nested children, and per-policy warnings (#692)#722

Open
sonupreetam wants to merge 9 commits into
complytime:mainfrom
sonupreetam:opsx/doctor-grouped-output
Open

feat(doctor): redesign output with grouped sections, nested children, and per-policy warnings (#692)#722
sonupreetam wants to merge 9 commits into
complytime:mainfrom
sonupreetam:opsx/doctor-grouped-output

Conversation

@sonupreetam

@sonupreetam sonupreetam commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Redesign complyctl doctor output with grouped sections, nested sub-results, and per-policy registry warnings. Tracked in #692, with feedback from @marcusburghardt on section ordering and named complypacks.

Changes

Data Model

  • CheckResult gains Children []CheckResult, Label string, and Group CheckGroup fields
  • CheckGroup type with constants and GroupOrder slice for section ordering
  • Label field provides display-ready names — renderer uses Label with Name fallback, no string parsing

Grouped Output

  • Sections ordered by scan prerequisites: Providers, Policies, Cache, Complypacks, Workspace, Verification
  • Variable checks nest under their parent provider by evaluator-id
  • Active-period checks nest under their parent policy by policy-id
  • Verbose detail (--verbose) nests as grandchildren with correct pass/fail status
  • Summary counts depth 0 + depth 1 (children); grandchildren excluded for stable counts regardless of --verbose

Per-Policy Registry Warnings

  • CheckPolicyVersions emits policy/<eid> warnings for each policy from an unreachable registry instead of a single registry/<reg> result that silently skipped subsequent policies
  • registryErrors cache prevents redundant timeout waits per registry (caches network errors, not 404s)

Other Improvements

  • Complypacks listed individually by evaluator-id (not a summary count)
  • Providers with no required variables and no policy mapping skip variable output (noise reduction)
  • Unmatched variable results promoted from GroupVariables to GroupProviders so they render in the Providers section (GroupVariables is not in GroupOrder)
  • Unmatched active-period results render as top-level in the Policies section (already carry GroupPolicies)
  • Complypack auxiliary results (state, cache-size, orphans) carry Group: GroupComplypacks

Tree Assembly

  • Run() calls attachByEvaluatorID() and attachByPolicyID() after collecting flat results
  • Check* functions remain independently testable

Tests

  • 6 new tests for attachByEvaluatorID/attachByPolicyID (matching, unmatched promotion, nil input)
  • 3 tests updated for per-policy registry results
  • 4 tests updated for verbose detail nesting (Children-based assertions with Status verification)

Verification

  • make lint: 0 issues
  • go test -race: all pass
  • make test-unit: no regressions (1 pre-existing macOS symlink failure)
  • DevPod E2E: normal mode, verbose mode, and unreachable registry scenario verified with mock OCI registry and real providers

Closes #692

Assisted-by: OpenCode (claude-opus-4-6)

OpenSpec spec-driven change for issue complytime#692: redesign complyctl doctor
output with grouped sections, nested children, per-policy registry
warnings, and named complypacks.

Artifacts: proposal, design (5 decisions), spec (6 requirements with
scenarios), tasks (8 phases, 30 tasks).
…ypacks

Implement phases 1-3 of doctor-grouped-output change:

Phase 1 - Data model:
- Add CheckGroup type, group constants, and GroupOrder slice
- Add Group field to CheckResult struct
- Assign Group to every CheckResult in all Check* functions
- Reorder Run() calls to match scan prerequisite sequence

Phase 2 - Named complypacks:
- Change CheckComplypacks to list each complypack individually by
  evaluator-id instead of a summary count
- Update tests to assert individual named results

Phase 3 - Grouped output rendering:
- Rewrite printDiagnostics with grouped section headers and indent
- Add string-based nesting helpers (partitionVariables, buildChildMap,
  filterParents, extractEvaluatorID)
- Add statusEmoji, countStatus, printResult helpers

Ref: complytime#692
Implement phases 4-8 of doctor-grouped-output change:

Phase 4 - Data model:
- Add Children []CheckResult field for explicit parent-child nesting
- Remove GroupVariables from GroupOrder (nested, not a section)
- Change resolve warnings and nil-config Group to GroupProviders

Phase 5 - Per-policy registry failure warnings:
- Change resolvePinnedFallback to emit policy/<eid> results instead
  of registry/<reg> for unreachable registries
- Remove unreachable map and continue skip logic from
  CheckPolicyVersions — each policy gets its own warning
- Update 3 tests for per-policy result expectations

Phase 6 - Tree assembly:
- Add attachByEvaluatorID helper to nest variables under providers
- Add attachByPolicyID helper to nest active-period under policies
- Update Run() to call tree assembly after collecting flat results
- Add 6 unit tests for both attach helpers

Phase 7 - Simplified rendering:
- Rewrite printDiagnostics as recursive tree walk
- Count only top-level results in summary line
- Delete string-parsing helpers (partitionVariables, buildChildMap,
  filterParents, isChildPolicyResult, extractEvaluatorID)
- Keep statusEmoji, countStatus helpers

Phase 8 - Verification:
- make lint: 0 issues
- go test -race: all pass
- make test-unit: no regressions (1 pre-existing macOS failure)

Ref: complytime#692
CHANGELOG.md: entry under Changed for doctor output redesign.
AGENTS.md: Recent Changes entry with structural details.

Ref: complytime#692
…rendering

Address review council findings:

- Restore per-registry error cache in CheckPolicyVersions to avoid
  redundant timeout waits. Each policy still gets its own per-policy
  result, but only the first policy per registry triggers a network
  call. 404 errors (ErrVersionNotFound) are not cached since they
  are per-repository, not per-registry.

- Promote unmatched variable results to GroupProviders in Run() so
  they render in the Providers section. Without this, results with
  Group: GroupVariables would be invisible since GroupVariables is
  not in GroupOrder.

- Fix AGENTS.md: 'recursive tree walk' -> 'nested tree walk' to
  accurately describe the fixed-depth iteration.

Ref: complytime#692
Update spec, design, and tasks for post-review-council refinements:

Design decisions:
- D5 revised: summary counts top-level + children, excludes
  grandchildren (verbose detail). Summary is stable regardless
  of --verbose flag.
- D7: skip variable results for unmapped providers with no
  required variables (noise reduction)
- D8: verbose detail produced as Children within Check* functions
  (three-level tree: provider -> variables -> detail)
- D9: detail Status reflects actual variable presence; remove
  inline emoji contradiction from message
- D10: add Label field to CheckResult for display-ready names;
  eliminate renderer string parsing (displayName/childLabel)

Spec requirements added:
- Unmapped provider skip scenario
- Verbose detail nesting under variable summary
- Detail Status reflects actual check state
- Summary counts depth 0+1, excludes depth 2
- Renderer uses Label field for display

New task phases:
- Phase 9: verbose detail nesting (D8, D9)
- Phase 10: display-ready Label field (D10)
- Phase 11: final verification

Ref: complytime#692
…splay helpers

Partial implementation of D5/D7/D10:

- D7: CheckVariables skips providers with no required variables and
  no policy mapping — eliminates noise for installed-but-unconfigured
  providers
- D5 revised: printDiagnostics counts top-level and children in
  summary (grandchildren excluded per updated spec)
- D10 interim: add displayName and childLabel helpers for cleaner
  output labels (to be replaced by Label field in phase 10)

Ref: complytime#692
… status

Implement phases 9-11 of doctor-grouped-output change:

Phase 9 - Verbose detail nesting (D8, D9):
- CheckVariables: collect verbose detail as Children of the
  summary CheckResult instead of flat results
- CheckPolicyActivePeriod: collect verbose detail as Children
  of the active-period CheckResult
- Detail Status reflects actual variable presence (StatusPass/
  StatusFail) — removes inline emoji contradiction where leading
  emoji showed pass but trailing showed fail
- Update 4 existing tests for Children-based detail assertions

Phase 10 - Display-ready Label field (D10):
- Add Label string field to CheckResult struct
- Set Label on all 25 CheckResult sites across CheckProviders,
  CheckPolicyVersions, CheckComplypacks, CheckVariables,
  CheckPolicyActivePeriod, and resolvePinnedFallback
- Rewrite printDiagnostics to use resultLabel() (Label with
  Name fallback) — no string parsing of Name
- Remove displayName, childLabel helpers and strings import
- Remove grandchild countStatus per D5 (summary counts depth
  0+1 only, stable regardless of --verbose)

Phase 11 - Verification:
- make lint: 0 issues
- go test -race: all pass
- make test-unit: no regressions
- Mock registry E2E: normal and verbose output verified

Ref: complytime#692
…accuracies

Review council findings:

- Add Group: GroupComplypacks to complypacks/state, complypacks/
  cache-size, and orphaned/untracked version results. Without Group
  these results were silently dropped by printDiagnostics which
  iterates only GroupOrder entries. (Architect + Guard MEDIUM)

- Fix CHANGELOG: 'Summary counts only top-level results' changed to
  accurately describe D5 behavior (counts depth 0+1, excludes depth 2
  grandchildren). (Guard + Curator MEDIUM)

- Fix AGENTS.md: add Label field to structural changes list, correct
  summary count description from 'top-level-only' to 'depth 0-1'.
  (Guard + Curator LOW)

Ref: complytime#692
@sonupreetam sonupreetam requested a review from a team as a code owner July 13, 2026 12:53
@sonupreetam sonupreetam added the enhancement New feature or request label Jul 13, 2026
@sonupreetam sonupreetam added the enhancement New feature or request label Jul 13, 2026
@sonupreetam sonupreetam self-assigned this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

enhancement: group and reorder complyctl doctor output for readability

1 participant