aws-samples / aws-samples/sample-autonomous-cloud-coding-agents
feat(observability): CI guard to enforce attributed SDK client construction (#319 follow-up)
- Lingua principale
- TypeScript
- Stelle
- 143
- Fork
- 46
- Merge medio
- 3g 10h
- PR unite (30g)
- 24
Descrizione
## Problem
#319 (PR #345) routes every AWS SDK client through an attributed factory (`makeClient`/`makeDocClient` in TS; `tenant_client`/`platform_client` in Python) so no outbound AWS call loses solution attribution. But that invariant is currently **convention-only** — a contributor can still write a naked `new S3Client({})` / `boto3.client(...)` and it compiles, passes tests, and works, silently losing attribution. This is exactly how the pattern decayed before: 5 naked SDK sites appeared on `main` *while #345 was in review*.
The factory is the easy path; this issue adds the **hard gate** that makes a naked client fail the build.
## Proposed enforcement (mirrors the repo's existing invariant-regression pattern)
- `scripts/check-ua-coverage.mjs` modeled on `scripts/check-types-sync.ts` — scans `cdk/src` + `cli/src` (TS) and `agent/src` (Python) for client construction outside the helper modules; exits non-zero on any naked site. Wire into `mise.toml` `drift-prevention` (a `build` dependency) + a `repo:local` prek hook.
- **Note:** use git-pathspec `'cdk/src/' 'cli/src/'` (directory prefix), **not** `'cdk/src/**/*.ts'` — the `**/*.ts` glob does not match files directly under `src/` and hid a bypass during #345 review (`cli/src/webhook-test.ts`).
- ESLint `no-restricted-syntax` `NewExpression[callee.name=/Client$/]` in `cdk/eslint.config.mjs` + `cli/eslint.config.mjs`, with an override disabling it in the `ua.ts` helper files (sharper than the script for the TS side).
- Python side via ruff `flake8-tidy-imports` banned-api or a `.semgrep/` rule (the latter gives the `# nosemgrep: -- ` allowlist the repo already documents).
- Optionally a ratchet-baseline variant (like `scripts/check-deadcode-ratchet.mjs`) only if debt must remain temporarily; #345 leaves the census at zero, so a hard gate should be feasible immediately.
## Acceptance
- A PR that adds a naked `new XxxClient({})` (cdk/cli) or `boto3.client(...)` (agent, outside `aws_session.py`) fails `mise run build` and the prek hook.
- The three `md/` sanitizers stay locked identical via a shared cross-language fixture.
## Context
- Builds on #319 / PR #345 (the factory).
- Depends on nothing; #345 should merge first so the census is already zero.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Inizia leggendo scripts/check-types-sync.ts e scripts/check-deadcode-ratchet.mjs, quindi esamina mise.toml, cdk/eslint.config.mjs e cli/eslint.config.mjs. Controlla gli helper client esistenti e i tre sanitizer di md/ prima di eseguire mise run build e l’hook repo:local. Il lavoro è completato quando la costruzione diretta dell’SDK TypeScript o Python fallisce entrambi i controlli e i fixture dei sanitizer rimangono identici.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- aws, eslint, python, typescript
- Ambito
- build-system, ci-cd, observability, tooling
- Tipo di issue
- Funzionalità
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Tranquilla
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 55/100