Skip to content

feat: stop TUI browsers from silently skipping the agent-facing surface #360

Description

@YoungJinJung

Summary

The agent-facing surface (JSON CLI + MCP) covers 6 of 27 catalog services, and nothing prevents that gap from widening. Every browser merged since the MCP work landed has shipped TUI-only, and there is no test that notices.

Evidence

On a563207:

surface count
Catalog services / features (TUI) 27 / 38
Agent-facing resource commands 6
Parity or coverage test none

The six exposed resources are backup-vaults, alarms, cloudtrail-events, ecs-rollout, elb-target-health, and rds-instances (internal/cli/resources.go, internal/cli/resources_operations.go). The remaining MCP tools — get_capabilities, get_command_schema, get_mcp_capabilities, plan_context_sync — are meta, not resource reads.

Browsers with no agent-facing counterpart include CloudFormation, Step Functions, EventBridge, DynamoDB, Auto Scaling, ElastiCache, KMS, ACM, SQS, S3, Secrets Manager, Route53, IAM, VPC, EKS, ECR, and FIS.

Why this matters now

Adding a browser currently means wiring ~8 TUI touchpoints (catalog.go, model.go, app.go, filter.go, keymap.go, messages.go, feature_submodel.go, screen_views.go). The agent surface is a ninth touchpoint that is easy to miss because nothing fails when you skip it.

Concrete live example: #324 (SNS browser) adds a full TUI browser and no unic resources sns-topics. That was not a deliberate scoping decision — I simply did not know the agent surface existed, because nothing in the build, tests, or docs pointed at it.

Each JSON resource is hand-written — a jsonEnvelope[T] wrapper, a per-resource DTO, and a loadXxx function variable — so the cost is real and the gap will not close by itself.

Proposed change

Two parts, guard first.

1. A parity test with an explicit allowlist. Walk domain.Catalog(), assert each feature either has an agent-facing command or appears in a documented agentSurfaceExempt map with a one-line reason. New browsers then fail the build until the author makes a deliberate call — expose it, or record why not.

This is the high-leverage half: it is small, it prevents recurrence, and it converts an invisible gap into a visible, reviewable list.

2. Fill incrementally, highest value first. Not one PR. Suggested order, by how much a raw AWS API bridge would struggle to reproduce the view:

  • inspect — RunSecurityScan / RunChecklist already return serializable reports (SecurityScanReport{Findings, ScannerCount, Warnings, ScannedAt}); 10 rule packs behind one call
  • ElastiCache, SNS — multi-call joins with partial-failure semantics
  • CloudFormation, Step Functions — failure-first triage ordering
  • The rest as demand appears

Non-goals

  • Exposing all 89 read-only repository methods. The shipped design is ~11 curated tools and that is the right shape; this issue does not propose changing it.
  • Widening mutation coverage. The confirmation gate in internal/cli/mutation.go correctly ports the TUI's type-the-name guard, and new mutations are out of scope here.

Checklist

  • Add a catalog-to-agent-surface parity test with a documented exemption map
  • Record every current gap as an exemption entry so the list is reviewable in one place
  • Document the agent surface as a wiring step in CLAUDE.md / docs/architecture.*.md so it is visible when adding a browser
  • Expose inspect as the first fill, reusing the existing report structs
  • Run make test and make build

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestpriority/nextQueued after current focustech-debtRefactoring / maintainability

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions