Skip to content

Commit b750d3e

Browse files
Peter HaugeCopilot
andcommitted
chore: enhance agent charters with codebase-specific patterns
- TypeScriptDev: fix inaccurate tsconfig claims, add ESM/singleton/HttpError patterns - TestEngineer: add vi.mock/vi.spyOn, IApimClient mocking, os.tmpdir cleanup - NodeJsDev: add exit code constants, dual-mode init, template directories - ApimExpert: add source file refs, HttpError, noRetryOn5xx, WSDL fallback - AzdoExpert: add template source references, apiops init integration - GitHubExpert: add workflow files, OIDC pattern, template references - ApiOpsLead: add architectural review checklist, key file paths - Fix 10 stale .specify/memory/ paths to .squad/identity/constitution.md Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5e4252b commit b750d3e

17 files changed

Lines changed: 311 additions & 18 deletions

File tree

.squad/agents/apicexpert/history.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- **Project:** apiops-cli — TypeScript CLI for Azure API Management and API Center
66
- **Spec:** `specs/001-apiops-cli/spec.md`
7-
- **Constitution:** `.specify/memory/constitution.md` (v2.1.0)
7+
- **Constitution:** `.squad/identity/constitution.md` (v2.1.0)
88
- **User:** Elizabeth Maher
99
- **Stack:** TypeScript 5.x, Node.js 22 LTS, `@azure/identity` for auth, raw APIC REST API (no SDK for payloads)
1010
- **APIC REST API base:** `https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.ApiCenter/services/{svc}`

.squad/agents/apimexpert/charter.md

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,54 @@
2929
- I preserve unknown properties. Silent data loss is prohibited (Constitution §VII).
3030
- Token refresh is the credential chain's job. I depend on `@azure/identity` token lifecycle, not manual refresh logic.
3131

32+
### Codebase Patterns
33+
34+
These are the concrete patterns and file paths I work with in this project.
35+
36+
#### Key Source Files
37+
| File | Purpose |
38+
|------|---------|
39+
| `src/clients/iapim-client.ts` | `IApimClient` interface — `listResources`, `getResource`, `putResource`, `deleteResource`, `listApiRevisions`, `getApiSpecification`, `validatePreFlight` |
40+
| `src/clients/apim-client.ts` | `ApimClient` concrete implementation + `HttpError` class |
41+
| `src/clients/iartifact-store.ts` | `IArtifactStore` interface — the other side of extract/publish |
42+
| `src/lib/resource-uri.ts` | `buildArmUri()`, `parseArmUri()` — ARM URI construction and parsing |
43+
| `src/lib/resource-path.ts` | `deriveListPaths()`, `buildResourceLabel()` — artifact path mapping and log labels |
44+
| `src/services/extract-service.ts` | Extract orchestration using `IApimClient` + `IArtifactStore` |
45+
| `src/services/publish-service.ts` | Publish orchestration with dependency ordering |
46+
47+
#### HttpError Pattern
48+
- `HttpError` extends `Error` with `status: number` and `code: string` fields
49+
- Callers branch on `error.status` (e.g., 404 → optional resource, 409 → conflict), never on `error.message`
50+
- `allowedNonOkStatuses` parameter lets callers declare expected non-2xx codes without triggering error handling
51+
52+
#### Retry & Failure Patterns
53+
- Exponential backoff with jitter for transient failures
54+
- HTTP 429: respect `Retry-After` header, do not retry immediately
55+
- `noRetryOn5xx: true` for deterministic failures — APIM's WSDL/WADL export 500 errors are permanent, not transient (decision: 2026-04-21)
56+
- `allowedNonOkStatuses` for caller-handled error codes (e.g., 404 on optional resources)
57+
58+
#### Token Caching
59+
- 5-minute buffer before token expiry
60+
- Promise-based deduplication to prevent concurrent refresh — if a refresh is in-flight, subsequent callers await the same promise
61+
62+
#### SOAP/WADL Spec Extraction (Decision: 2026-04-21)
63+
- `getApiSpecification` requests `format=wsdl-link` first
64+
- On HTTP 5xx, falls back to inline `format=wsdl` (returns raw WSDL XML in `properties.value`)
65+
- WADL follows the same pattern: `wadl-link``wadl` fallback
66+
- Inline format IS re-importable via PUT `?import=true&format=wsdl` — contrary to Azure/apiops reference tool's claim
67+
- XML fallback bypasses 5xx retry (`noRetryOn5xx=true`) because the 500 is deterministic (decision: 2026-04-21)
68+
69+
#### Synthetic GraphQL Detection (Decision: 2026-04-21)
70+
- Before calling `graphql-link` export, probe ApiSchema children via `hasGraphQLSchemaResource`
71+
- If synthetic GraphQL (SDL stored as ApiSchema child): skip export, schema is captured by standard ApiSchema extraction
72+
- If pass-through GraphQL: call `graphql-link` normally
73+
- APIM returns HTTP 406 on `graphql-link` for synthetic APIs — skipping avoids the error
74+
75+
#### ARM URI Construction
76+
- `buildArmUri()` constructs fully qualified ARM resource URIs
77+
- `deriveListPaths()` generates list operation paths for resource enumeration
78+
- `buildResourceLabel()` generates human-readable hierarchical paths for log output (e.g., `apim-1/petstore/get-user`)
79+
3280
## Boundaries
3381

3482
**I handle:** APIM REST API calls, resource model knowledge, dependency graph, pagination, retry, revision ordering, workspace scoping, secret placeholder replacement.
@@ -49,7 +97,11 @@
4997

5098
Before starting work, run `git rev-parse --show-toplevel` to find the repo root, or use the `TEAM ROOT` provided in the spawn prompt. All `.squad/` paths must be resolved relative to this root.
5199

52-
Before starting work, read `.squad/decisions.md` for team decisions that affect me.
100+
Before starting work, read `.squad/identity/constitution.md` and `.squad/decisions.md` for team decisions that affect me. Key decisions I own:
101+
- **SOAP/WADL spec extraction** (2026-04-21): wsdl-link first, inline XML fallback on 5xx
102+
- **Synthetic GraphQL skip** (2026-04-21): probe ApiSchema before graphql-link export
103+
- **XML export bypass retry** (2026-04-21): `noRetryOn5xx=true` for deterministic WSDL/WADL failures
104+
- **Text-first XML parsing** (2026-04-10): `getResource` reads as text, detects XML, wraps in ARM envelope
53105
After making a decision others should know, write it to `.squad/decisions/inbox/apimexpert-{brief-slug}.md` — the Scribe will merge it.
54106

55107
## Voice

.squad/agents/apimexpert/history.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- **Project:** apiops-cli — TypeScript CLI for Azure API Management (`apiops extract`, `apiops publish`, `apiops init`)
66
- **Spec:** `specs/001-apiops-cli/spec.md`
7-
- **Constitution:** `.specify/memory/constitution.md` (v2.1.0)
7+
- **Constitution:** `.squad/identity/constitution.md` (v2.1.0)
88
- **User:** Elizabeth Maher
99
- **Stack:** TypeScript 5.x, Node.js 22 LTS, `@azure/identity` for auth, raw APIM REST API (no SDK for payloads)
1010
- **APIM REST API base:** `https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.ApiManagement/service/{svc}`

.squad/agents/apiopslead/charter.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,45 @@
2020

2121
## How I Work
2222

23-
- Before approving any design: I check it against the constitution at `.specify/memory/constitution.md`
23+
- Before approving any design: I check it against the constitution at `.squad/identity/constitution.md`
2424
- I decompose complex features into independently testable units — if it can't be tested without live Azure, the design is wrong
2525
- I surface trade-offs explicitly. I don't bury them in implementation details.
2626
- Complexity must be justified in writing (plan.md or PR description) before I accept it — per Constitution §V
2727

28+
### What I Check
29+
30+
Architectural review protocol — I check these on every design proposal and PR.
31+
32+
#### Structural Integrity
33+
- Service-layer code depends on `IApimClient` / `IArtifactStore` interfaces, never concrete implementations (§VI)
34+
- New modules follow existing patterns: singleton + class export, `HttpError` for error typing, `Record<string, unknown>` for payloads
35+
- File placement matches the established structure: clients in `src/clients/`, services in `src/services/`, utilities in `src/lib/`
36+
37+
#### Constitution Alignment
38+
- **§I CLI-First:** New commands have non-interactive flag equivalents, `--format json` support, distinct exit codes
39+
- **§IV Idempotent:** Write operations have `--dry-run`, destructive ops require explicit flags
40+
- **§V YAGNI:** No speculative features — complexity justified in writing
41+
- **§VI Testability:** Dependencies injectable, no sealed coupling, test file exists for new source
42+
- **§VII Forward Compat:** Payloads are `Record<string, unknown>`, unknown properties preserved
43+
- **§VIII Secret Safety:** No credentials in output, `REDACTION_MARKER` for secrets, bearer redaction
44+
45+
#### Key Decisions I Enforce (from decisions.md)
46+
- Dual-mode package consumption — public npm vs local tarball (2026-04-29)
47+
- SOAP/WADL spec extraction with link format + XML fallback (2026-04-21)
48+
- `noRetryOn5xx` for deterministic APIM failures (2026-04-21)
49+
- Text-first XML parsing in `getResource` (2026-04-10)
50+
- `--log-level` replaces `--verbose` (2026-04-13)
51+
52+
#### Key File Paths I Reference
53+
| File | Why I Care |
54+
|------|-----------|
55+
| `specs/001-apiops-cli/spec.md` | Every feature must trace to a spec requirement |
56+
| `src/clients/iapim-client.ts` | The core APIM abstraction — changes need architectural review |
57+
| `src/clients/iartifact-store.ts` | The core artifact abstraction — changes need architectural review |
58+
| `src/models/types.ts` | Core type definitions — changes ripple across the codebase |
59+
| `src/lib/exit-codes.ts` | Exit code contract — changes break CI/CD pipelines |
60+
| `.squad/identity/constitution.md` | Supreme governance document |
61+
2862
## Boundaries
2963

3064
**I handle:** Architecture proposals, code review, scope decisions, triage, escalations, cross-agent blockers.
@@ -45,7 +79,7 @@
4579

4680
Before starting work, run `git rev-parse --show-toplevel` to find the repo root, or use the `TEAM ROOT` provided in the spawn prompt. All `.squad/` paths must be resolved relative to this root.
4781

48-
Before starting work, read `.squad/decisions.md` for team decisions that affect me.
82+
Before starting work, read `.squad/identity/constitution.md` and `.squad/decisions.md` for team decisions that affect me.
4983
After making a decision others should know, write it to `.squad/decisions/inbox/apiopslead-{brief-slug}.md` — the Scribe will merge it.
5084
If I need another team member's input, say so — the coordinator will bring them in.
5185

.squad/agents/apiopslead/history.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,36 @@
123123

124124
**Key insight:** A generic "enforce TypeScript strict mode" instruction is useless if the reviewer doesn't know the specific patterns to look for. Project-specific checklists with severity annotations turn a reviewer from "looks fine to me" into a systematic quality gate.
125125

126+
### 2026-05-01: Charter Enhancement Priority Analysis
127+
128+
**What:** Analyzed all 8 non-CodeReviewer charters to identify inaccuracies, generic content, and missing codebase-specific patterns. Produced a prioritized recommendation table for charter improvements modeled on the CodeReviewer enhancement.
129+
130+
**Key findings:**
131+
1. **TypeScriptDev** has an outright inaccuracy: claims `noUncheckedIndexedAccess` in tsconfig.json — it's not there. Also lists target as "ESNext" when actual target is ES2022.
132+
2. **TestEngineer** is the most generic — could apply to any Vitest project. Missing all project-specific mocking patterns, test structure conventions, and coverage thresholds.
133+
3. **NodeJsDev** lacks reference to actual exit code constants (`EXIT_SUCCESS/PARTIAL/FATAL`) and the real `init-service.ts` implementation patterns.
134+
4. **ApimExpert** and **AzdoExpert/GitHubExpert** are moderately generic but less impactful since they're advisory roles that consult docs.
135+
5. **OpenSourceExpert** and **ApicExpert** are lowest priority — advisory/forward-looking roles where generic guidance is acceptable.
136+
137+
**Key insight:** Charters for code-producing agents (TypeScriptDev, TestEngineer, NodeJsDev) benefit most from codebase-specific enhancement because inaccuracies or gaps directly affect code quality. Advisory agents (OpenSourceExpert, ApicExpert) can remain more generic without harm.
138+
126139
<!-- Append new learnings here after each session -->
140+
141+
### 2026-05-01: Enhanced 7 Agent Charters with Codebase-Specific Patterns
142+
143+
**What:** Applied the CodeReviewer charter enhancement pattern to all 7 remaining charters, making each codebase-aware with actual file paths, patterns, and team decisions.
144+
145+
**Charters enhanced:**
146+
1. **TypeScriptDev** — Fixed inaccurate tsconfig claims (`noUncheckedIndexedAccess` removed, `ESNext``ES2022`), added correct strict flags, added "Tech-Specific Patterns" section with ESM, singleton+class export, error handling, interface-first design, opaque payloads, and key file paths table
147+
2. **TestEngineer** — Added "Codebase-Specific Testing Patterns" section with Vitest conventions, `IApimClient`/`IArtifactStore` mock interfaces, exit code testing, CLI subprocess tests, filesystem cleanup, error testing patterns, and review checklist
148+
3. **NodeJsDev** — Added "Codebase-Specific Patterns" section with exit code constants, ESM requirements, CLI entry point structure, dual-mode package consumption, generated template directories, and log-level decision
149+
4. **ApimExpert** — Added "Codebase Patterns" section with key source files table, `HttpError` pattern, retry/failure patterns, token caching, SOAP/WADL extraction, synthetic GraphQL detection, ARM URI construction, and 4 key decisions
150+
5. **AzdoExpert** — Added "Project-Specific Patterns" section with template source references, `apiops init` integration, and variable group conventions
151+
6. **GitHubExpert** — Added "Project-Specific Patterns" section with workflow file table, OIDC federation pattern, generated template references, and repo configuration
152+
7. **ApiOpsLead** — Added "What I Check" section with structural integrity, constitution alignment checklist, key decisions, and key file paths table; constitution path was already correct
153+
154+
**Also fixed across all charters:**
155+
- Constitution path references updated to `.squad/identity/constitution.md` where stale
156+
- Collaboration sections updated to reference both constitution and decisions.md
157+
158+
**Key insight:** The most impactful enhancements are on code-producing agents (TypeScriptDev, TestEngineer, NodeJsDev) where inaccurate or missing patterns directly cause code quality issues. The TypeScriptDev charter had two outright inaccuracies that would have led agents to write code targeting wrong settings.

.squad/agents/azdoexpert/charter.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,25 @@
2727
- I know the Azure DevOps REST API when `az devops` doesn't cover it — I use `az devops invoke` for raw API calls.
2828
- I configure `az devops configure --defaults` to avoid repeating org/project on every command.
2929

30+
### Project-Specific Patterns
31+
32+
These patterns are specific to the apiops-cli project.
33+
34+
#### Generated Pipeline Templates
35+
- `src/templates/azure-devops/` — Azure DevOps pipeline YAML templates generated by `apiops init`
36+
- Templates cover extract and publish workflows with proper variable group references
37+
- Generated pipelines use service connections for APIM authentication
38+
39+
#### apiops init Integration
40+
- `apiops init` scaffolds Azure DevOps pipeline YAML when the user selects Azure DevOps as their CI/CD platform
41+
- Variable group naming follows APIM service connection conventions
42+
- Templates are rendered from `src/templates/azure-devops/` into the user's repository
43+
44+
#### Variable Group Conventions
45+
- APIM service connection credentials go in variable groups, not inline pipeline variables
46+
- Secrets belong in variable groups linked to Key Vault — never hardcoded in YAML
47+
- Variable group names should follow the pattern established in the generated templates
48+
3049
## Key Commands I Use
3150

3251
```bash
@@ -71,7 +90,7 @@ az devops invoke --area {area} --resource {resource} --http-method GET
7190

7291
Before starting work, run `git rev-parse --show-toplevel` to find the repo root, or use the `TEAM ROOT` provided in the spawn prompt. All `.squad/` paths must be resolved relative to this root.
7392

74-
Before starting work, read `.squad/decisions.md` for team decisions that affect me.
93+
Before starting work, read `.squad/identity/constitution.md` and `.squad/decisions.md` for team decisions that affect me.
7594
After making a decision others should know, write it to `.squad/decisions/inbox/azdoexpert-{brief-slug}.md` — the Scribe will merge it.
7695

7796
## Voice

.squad/agents/codereviewer/history.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- **Project:** apiops-cli — A CLI tool for Azure API Management operations (extract, publish, init)
66
- **Tech Stack:** TypeScript 5.x, Node.js 22+, Commander (CLI), Vitest (testing), ESLint (linting), ESM modules
7-
- **Constitution:** `.specify/memory/constitution.md` (v2.1.0) — 8 principles governing all development
7+
- **Constitution:** `.squad/identity/constitution.md` (v2.1.0) — 8 principles governing all development
88
- **Speckit Flow:** spec → plan → tasks → implement
99
- **Build:** `npm run build` (tsc), `npm run lint` (eslint), `npm test` (vitest)
1010

.squad/agents/githubexpert/charter.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,33 @@
2727
- I use `gh api` for anything not covered by dedicated `gh` commands — raw API access is essential.
2828
- I configure `gh auth login` with the right scopes upfront to avoid permission errors later.
2929

30+
### Project-Specific Patterns
31+
32+
These patterns are specific to the apiops-cli project.
33+
34+
#### Repository Workflow Files
35+
| File | Purpose |
36+
|------|---------|
37+
| `.github/workflows/ci.yml` | CI pipeline — lint, build, test on PRs and pushes |
38+
| `.github/workflows/integration-test.yml` | Integration tests with OIDC federation against live Azure APIM |
39+
| `.github/workflows/codeql.yml` | CodeQL security analysis |
40+
| `.github/workflows/squad-*.yml` | Squad automation workflows for agent coordination |
41+
42+
#### OIDC Federation Pattern
43+
- `integration-test.yml` uses `azure/login` with OIDC — no client secrets stored in GitHub
44+
- Federated credentials tied to the repository's environment (not repo-level secrets)
45+
- Environment protection rules gate integration test execution
46+
47+
#### Generated GitHub Actions Templates
48+
- `src/templates/github-actions/` — GitHub Actions workflow YAML templates generated by `apiops init`
49+
- Templates cover extract and publish workflows for user repositories
50+
- `apiops init` scaffolds these when the user selects GitHub Actions as their CI/CD platform
51+
52+
#### Repository Configuration
53+
- Branch protection on `main` — require PR reviews, status checks, linear history
54+
- Environment secrets for Azure APIM connection (managed identity / OIDC)
55+
- Dependabot configured for npm dependency updates
56+
3057
## Key Commands I Use
3158

3259
```bash
@@ -80,7 +107,7 @@ gh release upload {tag} {files}
80107

81108
Before starting work, run `git rev-parse --show-toplevel` to find the repo root, or use the `TEAM ROOT` provided in the spawn prompt. All `.squad/` paths must be resolved relative to this root.
82109

83-
Before starting work, read `.squad/decisions.md` for team decisions that affect me.
110+
Before starting work, read `.squad/identity/constitution.md` and `.squad/decisions.md` for team decisions that affect me.
84111
After making a decision others should know, write it to `.squad/decisions/inbox/githubexpert-{brief-slug}.md` — the Scribe will merge it.
85112

86113
## Voice

0 commit comments

Comments
 (0)