|
2 | 2 |
|
3 | 3 | ## Active Decisions |
4 | 4 |
|
| 5 | +### 2026-05-26T21:18:34Z: Compare JSON results include source or target instance metadata |
| 6 | +**By:** TypeScriptDev |
| 7 | +**Status:** Implemented |
| 8 | +**What:** Added an optional `instance: 'source' | 'target'` field to `ComparisonDifference` so structured compare output explicitly identifies whether a non-matching resource exists only in the source or only in the target APIM instance. |
| 9 | + |
| 10 | +**Implementation:** |
| 11 | +- `missing` diffs now emit `instance: 'source'` |
| 12 | +- `extra` diffs now emit `instance: 'target'` |
| 13 | +- `property-diff` entries remain unchanged |
| 14 | +- Focused unit coverage verifies both instance values and confirms property diffs are unaffected |
| 15 | + |
| 16 | +**Why:** `diffType` alone was ambiguous in JSON mode because it did not say which APIM instance owned a resource that appeared only on one side. The compare service is the right seam to make the machine-readable contract self-describing without changing table or text output. |
| 17 | + |
| 18 | +**Validation:** |
| 19 | +- `npx vitest run tests/unit/services/compare-service.test.ts` |
| 20 | + |
| 21 | +--- |
| 22 | + |
5 | 23 | ### 2026-05-22T08:08:23Z: apiops compare Command — Cloud-to-Cloud Comparison |
6 | 24 | **By:** ApimExpert |
7 | 25 | **Status:** Completed (lint errors pending) |
|
146 | 164 | **What:** Made `--cli-package` optional in `apiops init`. The command now supports two package consumption modes: (1) **Public npm mode** (default, when `--cli-package` NOT provided): generates package.json with `"@peterhauge/apiops-cli": "latest"`, no local tarball copy, no `.apiops/` directory created, standard consumption pattern after npm publish. (2) **Local tarball mode** (when `--cli-package <path>` provided): copies tarball to `.apiops/` directory, generates package.json with `"apiops": "file:.apiops/{tarball}"`, preserves existing behavior for local development/testing. |
147 | 165 | **Why:** After publishing to npm as `@peterhauge/apiops-cli`, requiring users to download the package and run `apiops init --cli-package ./tarball.tgz` added unnecessary friction. Most users want to reference the public package directly. The change is backward compatible — existing workflows with `--cli-package` continue to work unchanged. Improves user experience with simpler onboarding. |
148 | 166 |
|
149 | | -### 2026-04-21T19:35:00Z: SOAP/WADL spec extraction prefers link format with inline XML fallback |
150 | | -**By:** ApimExpert (via Squad session with a user) |
151 | | -**Status:** Implemented |
152 | | -**What:** For soap-type APIs, `getApiSpecification` requests `format=wsdl-link` first. On HTTP 5xx, it falls back to the inline (non-link) `format=wsdl` export which returns raw WSDL XML in `properties.value`. WADL follows the same pattern (`wadl-link` → `format=wadl` fallback). The XML fallback content is saved as `specification.wsdl` / `specification.wadl` and is re-importable via PUT `?import=true&format=wsdl` (or `wadl-xml`). |
153 | | -**Why:** User requires full round-trip fidelity — SOAP APIs must be re-importable to a new APIM instance. APIM's `wsdl-link` emitter deterministically returns HTTP 500 on many real-world SOAP APIs. Azure/apiops reference tool skips XML specs on 500 with comment "non-link exports cannot be reimported" — this is inaccurate; the inline form IS re-importable. Converting SOAP → OpenAPI via `openapi-link` works but loses SOAP semantics on round-trip. |
154 | | - |
155 | | -### 2026-04-21T19:34:00Z: Synthetic GraphQL APIs skip the graphql-link export call |
156 | | -**By:** ApimExpert (via Squad session with a user) |
157 | | -**Status:** Implemented |
158 | | -**What:** Before calling `graphql-link` export, `api-extractor.ts` probes ApiSchema children via `hasGraphQLSchemaResource` and checks for `contentType` containing 'graphql'. If found (synthetic GraphQL — SDL stored as an ApiSchema resource), the export call is skipped. If not found (pass-through GraphQL), `graphql-link` is called normally. |
159 | | -**Why:** APIM returns HTTP 406 on `graphql-link` export for synthetic GraphQL APIs because there is nothing to export — the SDL is already held as an ApiSchema child resource and is captured by standard ApiSchema extraction. Skipping the redundant call avoids the error without losing fidelity. |
160 | | - |
161 | | -### 2026-04-21T19:33:00Z: XML export fallback bypasses the default 5xx retry loop |
162 | | -**By:** ApimExpert (via Squad session with user) |
163 | | -**Status:** Implemented |
164 | | -**What:** `getApiSpecification` passes `noRetryOn5xx=true` to `request()` when exporting `wsdl-link` or `wadl-link`. The fallback to inline format runs immediately on HTTP 5xx rather than after three retries. |
165 | | -**Why:** APIM's wsdl-link/wadl-link 500 errors are deterministic failures in APIM's XML emitter, not transient. Retrying wastes time and delays the fallback. The inline format path is fast and reliable. |
166 | | - |
167 | | -### 2026-04-14T21:37:55Z: Resource Path Labels for Log Output |
168 | | -**By:** CodeReviewer |
169 | | -**Status:** Approved |
170 | | -**What:** Implemented `buildResourceLabel()` utility to generate human-readable hierarchical resource paths in logs. Format: serviceName/grandparent/parent/name (e.g., "apim-1/petstore/get-user" instead of just "get-user"). Applied across resource-extractor.ts, api-extractor.ts, and extract-service.ts. |
171 | | -**Why:** Improves observability by providing full context in log messages; aids debugging and tracing. Tested comprehensively (8 unit tests, all 467 integration tests passing). Compliant with Constitution §I-§VIII; no secret safety risks (only metadata logged). |
172 | | - |
173 | | -### 2026-04-13T23:35:35Z: Replace --verbose with --log-level Option |
174 | | -**By:** TypeScriptDev |
175 | | -**Status:** Implemented |
176 | | -**What:** Replaced boolean `--verbose` flag with `--log-level <level>` supporting debug, info, warn, error (default: info). Logger updated with `LOG_LEVEL_PRIORITY` numeric filtering; all 432 tests pass. |
177 | | -**Why:** Granular log control (4 levels vs. binary), production-friendly (suppress INFO noise), industry standard alignment (kubectl, docker, terraform), explicit semantics. Breaking change; users update `--verbose` to `--log-level debug`. |
178 | | - |
179 | | -### 2026-04-13T18:50:54Z: Comprehensive test coverage for API publisher and rate limiting |
180 | | -**By:** TestEngineer |
181 | | -**What:** Created `tests/unit/services/api-publisher.test.ts` (20 tests) covering all aspects of API publisher service, and enhanced `tests/unit/clients/apim-client.test.ts` with 4 rate-limiting tests for HTTP 429 handling. |
182 | | -**Why:** Critical gap: api-publisher.ts had no dedicated test file despite being central to T032 (revision handling). Additionally, HTTP 429 rate limiting (FR-015) was untested. Both pose production risks. Solution maintains Constitution §VI (unit tests only, no external deps), full mock coverage, and edge case testing. |
183 | | - |
184 | | -### 2026-04-10T18:14:39Z: Text-first XML parsing in ApimClient.getResource |
185 | | -**By:** TypeScriptDev |
186 | | -**What:** Modified `getResource` to handle raw XML responses from APIM policy endpoints by reading response as text first, detecting XML via Content-Type header or body sniffing, then wrapping in ARM envelope. |
187 | | -**Why:** APIM policy endpoints (ServicePolicy, ApiPolicy, etc.) return raw XML instead of JSON-wrapped XML. Previous implementation crashed on `response.json()`. Text-first approach is defensive, maintains backward compatibility (no interface changes), and handles both explicit and implicit XML detection. |
188 | | - |
189 | | -### 2025-04-09T05:34:00Z: Formalized commit message convention |
190 | | -**By:** ApiOpsLead |
191 | | -**What:** Codified the commit convention (include `Closes #N` or `Fixes #N` when resolving issues) into CONTRIBUTING.md and PR template. Previously this existed only in agent memory. |
192 | | -**Why:** Conventions that only live in agent memory are invisible to human contributors and new AI agents. Formalizing in repo files ensures all contributors follow the same process. |
193 | | - |
194 | | -### 2025-05-18: GitHub Agentic Workflows (gh-aw) Adoption Strategy |
195 | | -**By:** GitHubExpert |
196 | | -**Status:** Proposed |
197 | | -**Scope:** Branch maintenance workflows |
198 | | - |
199 | | -**Context:** Whether or not to use gh-aw or hand-rolled YAML implementations. |
200 | | - |
201 | | -**Decision:** |
202 | | -- Use gh-aw LabelOps pattern, event pattern for advising. |
203 | | -- Use hand-rolled yaml for deterministic outcode, like CI gates. |
204 | | - |
205 | | -**Impact:** Reduces maintenance burden for advisory workflows; eliminates keyword-matching brittleness in triage; no change to security posture. |
206 | | - |
207 | | ---- |
208 | | - |
209 | 167 | ### 2026-06-11: GitHub Agentic Workflows (gh-aw) Security Assessment |
210 | 168 | **By:** SecurityExpert |
211 | 169 | **Status:** Proposed |
|
249 | 207 |
|
250 | 208 | **Net Assessment:** gh-aw improves least-privilege, blast radius, auditability, and separation of concerns vs. current model. Weakens determinism and introduces prompt injection surface (mitigated by constraints). Net security improvement for advisory workflows when guardrails are in place. |
251 | 209 |
|
| 210 | +Archived entries older than 30 days are stored in `.squad/decisions-archive.md`. |
| 211 | + |
252 | 212 | --- |
253 | 213 |
|
254 | 214 | ## Governance |
|
0 commit comments