mirror of
https://github.com/azaion/annotations.git
synced 2026-06-21 12:41:07 +00:00
docs: Step 4 testability refactor — list-of-changes + 2 task specs
autodev existing-code Step 4 (Code Testability Revision) — invoked
refactor skill in guided mode. Phase 0 (baseline) + Phase 1 (discovery
+ validation) + Phase 2 (analysis + task decomposition) artifacts.
list-of-changes.md identifies two surgical fixes required before the
67-scenario blackbox suite (already specified in _docs/02_document/
tests/) can run against the SUT:
C01 — env-gate JWKS RequireHttps on ASPNETCORE_ENVIRONMENT=E2ETest
(architecture.md Open Risks Section 6 prescribes this; the
mock issuer in e2e/docker-compose.test.yml serves plain HTTP)
C02 — DNS-resolve RABBITMQ_HOST in FailsafeProducer.ProcessQueue
(IPAddress.Parse currently throws on every drain cycle when
host is a service name; latent production-relevant bug, not
just a test-env issue)
Two task specs in _docs/02_tasks/todo/ (3 story points total).
Independent — no inter-task dependency.
Tracker: local — Atlassian MCP reported errored at task-creation
time. Deferred Jira writes (epic + 2 tickets) recorded in
_docs/_process_leftovers/2026-05-14_testability-tracker.md for
replay when MCP is restored.
Items explicitly deferred to Step 8 Refactor are enumerated in
list-of-changes.md "Deferred to Step 8 Refactor" — including the
FailsafeProducer static helper (F3), the JWKS GetAwaiter().GetResult()
hot path, RB-05/06/08 backlog items, and the MediaService ffprobe
empty-catch.
State: Step 4 in_progress, sub_step 3 (phase-2-task-decomposition).
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# Refactoring Roadmap — 01-testability-refactoring
|
||||
|
||||
## Weak Points Assessment
|
||||
|
||||
| # | Location | Description | Impact | Proposed Solution | Status |
|
||||
|---|----------|-------------|--------|-------------------|--------|
|
||||
| 1 | `src/Auth/JwtExtensions.cs:33` | `HttpDocumentRetriever { RequireHttps = true }` hardcoded; blocks the e2e mock-issuer harness that serves HTTP | Blocks ~60 of 67 documented test scenarios from running | C01 (env-gated `RequireHttps`) | Selected |
|
||||
| 2 | `src/Services/FailsafeProducer.cs:56` | `IPAddress.Parse(config.Host)` throws on DNS hostnames; outbox drain never runs in any deployment using container DNS | Blocks 5 outbox/resilience/perf test scenarios; latent **production-relevant** logic bug | C02 (DNS resolution before `IPEndPoint`) | Selected |
|
||||
|
||||
## Gap Analysis — acceptance criteria vs. current state
|
||||
|
||||
The Step 4 testability scope is the gap. The full AC list (in `_docs/00_problem/acceptance_criteria.md`) is implementation-tracked by other steps. The relevant gaps for this run:
|
||||
|
||||
| AC | Gap | Closed by |
|
||||
|----|-----|-----------|
|
||||
| AC-F-50 (Bearer token verification) | Cannot be exercised against real JWKS-fetch behavior in test harness | C01 |
|
||||
| AC-F-12 (Outbox drain → stream) | Cannot be exercised at all today | C02 |
|
||||
| AC-F-10 (SSE delivery < 1s) | Independent of these changes; works today | (none) |
|
||||
|
||||
## Phased Roadmap
|
||||
|
||||
**Phase 1 — Critical Fixes (this run)**: C01 + C02. Selected. Approved by user.
|
||||
|
||||
**Phase 2 — Major Improvements**: deferred to Step 8 Refactor; enumerated under "Deferred to Step 8 Refactor" in `list-of-changes.md`.
|
||||
|
||||
**Phase 3 — Enhancements**: out of scope.
|
||||
|
||||
## Hardening Tracks
|
||||
|
||||
For testability runs, hardening tracks (Tech Debt / Performance / Security review) are explicitly **out of scope** per existing-code flow Step 4 ("smallest set of changes ... deeper structural improvements belong in Step 8"). The user already constrained scope to C01+C02 via the Phase 1 approval — re-opening the scope here would violate Step 4's discipline.
|
||||
|
||||
**Selected hardening tracks**: None (option E).
|
||||
|
||||
## Applicability Gate
|
||||
|
||||
Every roadmap item is `Selected`. No items in `Rejected` / `Experimental only` / `Needs user decision` states. BLOCKING applicability gate cleared.
|
||||
|
||||
## Constraint Fit Summary
|
||||
|
||||
| Recommendation | Constraint fit | Mismatches | Evidence | Status |
|
||||
|---------------|---------------|-----------|----------|--------|
|
||||
| C01 | Preserves SW-05, AC-F-50, NFT-SEC-01..10, ENV-02; aligns with architecture.md Open Risks §6 | None | `research_findings.md` references | Selected |
|
||||
| C02 | Preserves SW-03, AC-F-12, AC-N-03, ENV-01; matches module-layout Component 02 ownership | None | `research_findings.md` references | Selected |
|
||||
@@ -0,0 +1,61 @@
|
||||
# Research Findings — 01-testability-refactoring
|
||||
|
||||
**Scope**: minimal — testability run with 2 surgical changes. No replacement library / SDK / framework is proposed; therefore the per-mode API capability verification (mandatory for replacements) is **not applicable** to this run. All API decisions stay inside the BCL and existing dependencies (`Microsoft.IdentityModel.Protocols`, `RabbitMQ.Stream.Client`, `System.Net.Dns`).
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### C01 area — JWKS retrieval
|
||||
|
||||
- **Pattern**: `ConfigurationManager<JsonWebKeySet>` + `HttpDocumentRetriever`. This is the recommended path in `Microsoft.IdentityModel.Protocols` 8.x for non-OIDC JWKS endpoints; the project pins the version in `Azaion.Annotations.csproj`. No alternative pattern is needed.
|
||||
- **Strength**: caching + automatic refresh on the documented schedule; key-rotation friendly.
|
||||
- **Weakness**: `HttpDocumentRetriever.RequireHttps` is a constructor-time bool. No env-aware factory in the BCL or in `Microsoft.IdentityModel.*`. The smallest change is to read `IHostEnvironment.EnvironmentName` (or `ASPNETCORE_ENVIRONMENT` directly) at the call site and pass the resulting bool.
|
||||
|
||||
### C02 area — RabbitMQ stream endpoint construction
|
||||
|
||||
- **Pattern**: `RabbitMQ.Stream.Client.StreamSystem.Create(StreamSystemConfig)` with `Endpoints = IList<EndPoint>`. The `EndPoint` base class accepts `IPEndPoint` (used today) and `DnsEndPoint`. The library's documented examples all use `IPEndPoint`.
|
||||
- **Strength**: works deterministically when given a literal IP.
|
||||
- **Weakness**: hostnames must be resolved by the caller. `IPAddress.Parse` throws on hostnames — wrong API choice for the documented `RABBITMQ_HOST` value space.
|
||||
- **Alternatives considered**:
|
||||
- **(rejected)** Replace `IPEndPoint` with `DnsEndPoint` and let `RabbitMQ.Stream.Client` resolve internally — uncertain whether the library handles this path on every transport; introduces unverified behavior. Testability rule: smallest known-correct change wins.
|
||||
- **(selected)** Resolve via `Dns.GetHostAddressesAsync(...)` when the value is not an IP, keep `IPEndPoint`. Identical behavior for IP-literal callers, mechanical fix for hostname callers.
|
||||
|
||||
## Prioritized Recommendations
|
||||
|
||||
| Recommendation | Pinned mode / config | Constraint fit | Evidence | Status |
|
||||
|----------------|---------------------|---------------|----------|--------|
|
||||
| C01 — env-gate `RequireHttps` | `HttpDocumentRetriever { RequireHttps = environment != "E2ETest" }` | Preserves SW-05, AC-F-50, NFT-SEC-01..10; aligns with `architecture.md` Open Risks §6 | Listed in `_docs/02_document/architecture.md` Open Risks §6, `_docs/02_document/tests/test-data.md` "Bearer token harness" step 2 | Selected |
|
||||
| C02 — DNS-resolve `config.Host` before `IPEndPoint` | `IPAddress.TryParse(host, out ip) ? ip : (await Dns.GetHostAddressesAsync(host, ct)).First()` | Preserves SW-03, AC-F-12, AC-N-03, ENV-01; module-layout Component 02 owner; no wire-format change | `RabbitMQ.Stream.Client` example code uses `IPEndPoint`; `System.Net.Dns.GetHostAddressesAsync` is the standard hostname-resolution call in .NET 10 | Selected |
|
||||
|
||||
**Replacement library/SDK count**: 0. **MVE files required**: 0. **`context7` calls required**: 0 (no replacement; both changes use APIs already in the dependency closure and stay inside the documented call patterns).
|
||||
|
||||
## Restrictions × Recommendation Sub-Matrix (light)
|
||||
|
||||
A full Restrictions × Candidate-Mode walk is mandatory only for replacement recommendations. Both selected items keep the existing dependencies; for completeness, the binding restrictions are mapped here.
|
||||
|
||||
| Restriction (from `_docs/00_problem/restrictions.md`) | C01 effect | C02 effect |
|
||||
|-------------------------------------------------------|-----------|-----------|
|
||||
| HW-01 ARM64 only | N/A — no native code | N/A |
|
||||
| HW-02 writable dirs | N/A | N/A |
|
||||
| SW-01 .NET 10 | uses BCL `IHostEnvironment` already injected | uses BCL `System.Net.Dns` |
|
||||
| SW-03 RabbitMQ streams plugin | N/A | unchanged — same client, same wire format |
|
||||
| SW-05 JWT verifier-only ES256 over JWKS | verification semantics unchanged | N/A |
|
||||
| ENV-01 env vars required | unchanged — same vars | unchanged — `RABBITMQ_HOST` semantics preserved |
|
||||
| ENV-02 service on port 8080 HTTP, no in-image TLS | aligned — the SUT itself is HTTP, this change only affects the issuer transport requirement | N/A |
|
||||
| ENV-06 CORS gated by validator | unchanged | N/A |
|
||||
| OP-01 per-instance SSE state | N/A | N/A |
|
||||
| OP-02 no outbox row leasing | N/A | unchanged — same drain pattern |
|
||||
|
||||
No ❌ or ❓ cells. Both recommendations are `Selected`.
|
||||
|
||||
## Quick Wins vs. Strategic Improvements
|
||||
|
||||
Both C01 and C02 are quick wins (1-2 hour implementation each). Strategic improvements were deferred to `list-of-changes.md` "Deferred to Step 8 Refactor" section — the user already approved that constraint.
|
||||
|
||||
## References
|
||||
|
||||
- `_docs/02_document/architecture.md` Open Risks §6
|
||||
- `_docs/02_document/tests/test-data.md` "Bearer token harness"
|
||||
- `_docs/02_document/tests/environment.md` services table
|
||||
- `_docs/02_document/modules/auth-identity.md`
|
||||
- `_docs/02_document/modules/rabbitmq-stream-sync.md`
|
||||
- `_docs/02_document/architecture_compliance_baseline.md`
|
||||
Reference in New Issue
Block a user