Files
satellite-provider/_docs/06_metrics/structure_2026-05-12_cycle3.md
Oleksandr Bezdieniezhnykh ca0ca9f2a4
ci/woodpecker/push/01-test Pipeline was successful
ci/woodpecker/push/02-build-push Pipeline was successful
[AZ-491] [AZ-492] [AZ-493] [AZ-494] [AZ-495] [AZ-496] Cycle 3 Step 17: retrospective + close cycle
Cycle-3 retrospective:
  - 6 tasks (AZ-491..AZ-496), 5 batches, 18 SP delivered.
  - 100% code review pass rate (5/5 PASS_WITH_WARNINGS, 0 FAIL).
  - 0 Critical/High/Medium review findings; 7 distinct Low.
  - Security audit PASS_WITH_WARNINGS: 0 new Medium, 3 Low (all
    test-only or operator-CLI), 2 Informational, 1 False Positive.
  - Net Architecture delta: **-3** (F-AUTH-2 + D1 + D3 RESOLVED;
    only new findings are Low test-side surfaces). First
    net-negative cycle on record.
  - 5 of 6 tasks completed first attempt (no post-review fix
    commits). Cycle-2's 2 prior-retro actions all translated to
    closed work (AZ-491 from Action 1, AZ-492 from Action 2,
    AZ-493 from Action 3).

Top 3 cycle-4 improvement actions surfaced:
  1. Execute the perf harness to capture PT-07/PT-08 baseline.
  2. Bump TestSupport JWT pins 7.0.3 → 7.1.2+ (D4 NU1902 cleanup).
  3. Add `workspace:` tag to cross-repo ACs in task-spec writing
     and render them separately in the traceability matrix.

3 new ring-buffer lessons appended to _docs/LESSONS.md:
  - [process] Option-B forcing functions for cross-team blockers.
  - [process] ACs prescribing a measurement should also prescribe
    the collection path.
  - [process] Cross-repo-write ACs need workspace tags.

Structural snapshot at structure_2026-05-12_cycle3.md records the
new SatelliteProvider.TestSupport project (+2 ProjectReference edges
into it; no production-layer dependents) and the AZ-496 package
bumps (8.0.21 → 8.0.25).

Cycle 3 COMPLETE. State advanced to Step 9 (New Task) for cycle 4
per existing-code flow Re-Entry After Completion.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 03:46:41 +03:00

6.5 KiB

Structural Snapshot — 2026-05-12 (post-cycle 3, AZ-491 / AZ-492 / AZ-493 / AZ-494 / AZ-495 / AZ-496)

Cycle 3 delta against structure_2026-05-11_cycle2.md. Source of truth: _docs/02_document/module-layout.md + on-disk *.csproj graph + _docs/02_document/contracts/.

Projects

Layer csproj Cycle 3 delta
1 (Foundation) SatelliteProvider.Common unchanged
1 (Foundation) SatelliteProvider.DataAccess unchanged
3 (Application) SatelliteProvider.Services.TileDownloader unchanged
3 (Application) SatelliteProvider.Services.RegionProcessing unchanged
3 (Application) SatelliteProvider.Services.RouteManagement unchanged
4 (API / Entry) SatelliteProvider.Api +Authentication/AuthenticationServiceCollectionExtensions extended with iss/aud resolution + fail-fast (AZ-494); Microsoft.AspNetCore.OpenApi 8.0.21 → 8.0.25 and Microsoft.AspNetCore.Authentication.JwtBearer 8.0.21 → 8.0.25 (AZ-496)
5 (Test-Support, NEW) SatelliteProvider.TestSupport NEW project (AZ-491). IsPackable=false. Public surface: JwtTokenFactory (the canonical HS256 mint helper, with iss/aud parameters added by AZ-494) + IntegrationTestResetGuard (the two-guard model added by AZ-493). NuGet refs: Microsoft.IdentityModel.Tokens 7.0.3 + System.IdentityModel.Tokens.Jwt 7.0.3.
6 (Tests) SatelliteProvider.Tests +ProjectReference to SatelliteProvider.TestSupport (AZ-491); removed local TestUtilities/JwtTokenFactory.cs
6 (Tests) SatelliteProvider.IntegrationTests +ProjectReference to SatelliteProvider.TestSupport (AZ-491); +PerfBootstrap.cs (AZ-492); +IntegrationTestDatabaseReset.cs (AZ-493); JwtTestHelpers.cs extended with MintAuthenticated/MintExpired/ResolveIssuerOrThrow/ResolveAudienceOrThrow (AZ-491 + AZ-494); removed direct Microsoft.IdentityModel.JsonWebTokens PackageReference

Project count: 9 (+1 from cycle 2; new SatelliteProvider.TestSupport).

Cross-Project Import Edges (compile-time ProjectReference)

Edge Count
Api → {Common, DataAccess, TileDownloader, RegionProcessing, RouteManagement} 5 (unchanged)
TileDownloader → {Common, DataAccess} 2 (unchanged)
DataAccess → {Common} 1 (unchanged)
RegionProcessing → {Common, DataAccess} 2 (unchanged)
RouteManagement → {Common, DataAccess} 2 (unchanged)
Tests → {Api, TileDownloader, RegionProcessing, RouteManagement, Common, DataAccess} 6 (unchanged; cycle-2 baseline)
Tests → TestSupport +1 (AZ-491)
IntegrationTests → TestSupport +1 (AZ-491)

Total ProjectReference edges: 20 (+2 vs cycle 2). Both new edges go INTO TestSupport; no production-layer dependency on TestSupport (the IsPackable=false guarantee blocks accidental shipping).

Source-import sites — cycle 3 delta

Importer Imports from Cycle 3 delta
WebApi Authentication Microsoft.IdentityModel.Tokens +1 site (ResolveRequiredOrThrow extension; ValidateIssuer/ValidateAudience flags on TokenValidationParameters)
IntegrationTests SatelliteProvider.TestSupport +N sites (JwtTokenFactory, IntegrationTestResetGuard) — replaces removed local helpers
Tests SatelliteProvider.TestSupport +N sites (JwtTokenFactory in 5 test files; IntegrationTestResetGuard in unit IntegrationTestResetGuardTests)
IntegrationTests Npgsql +1 site (IntegrationTestDatabaseReset uses NpgsqlConnection + NpgsqlCommand)
IntegrationTests SixLabors.ImageSharp (already present) +1 site (PerfBootstrap.CreateValidJpeg)

Graph properties

  • Cycles in project import graph: 0 (clean DAG — unchanged)
  • Average ProjectReferences per component: 20 / 9 = ~2.2 (cycle 2 = 12 / 8 = 1.5; growth is concentrated in test surface, not production)
  • Max in-degree: Common (still highest at 6 — Api, TileDownloader, DataAccess, RegionProcessing, RouteManagement, Tests). TestSupport in-degree = 2 (Tests + IntegrationTests).
  • Max out-degree: Tests (7 — adds the new TestSupport edge to its existing 6).
  • TestSupport position: leaf-of-test-subgraph; no production-layer importers. Out-degree = 0 from a project-graph standpoint (it does not depend on any other satellite-provider project). NuGet-only dependencies.

NuGet dependency hygiene (cycle 3)

Package Version Status
Microsoft.AspNetCore.OpenApi 8.0.21 → 8.0.25 RESOLVED D1 (AZ-496)
Microsoft.AspNetCore.Authentication.JwtBearer 8.0.21 → 8.0.25 RESOLVED D3 (AZ-496)
Microsoft.IdentityModel.Tokens (TestSupport) 7.0.3 (NEW) NEW D4 — CVE-2024-21319, test-only, bump to 7.1.2 tracked as future PBI
System.IdentityModel.Tokens.Jwt (TestSupport) 7.0.3 (NEW) NEW D4 — same advisory; same disposition
SixLabors.ImageSharp 3.1.11 (unchanged) clean
Npgsql 9.0.2 (unchanged) clean (now consumed by AZ-493's reset hook)
Microsoft.Extensions.* 9.0.10 (unchanged across DataAccess, TileDownloader, Tests, RegionProcessing, RouteManagement) consistent across all 5 sites

Architecture / contract surface (cycle 3 delta)

  • No new public-API contracts under _docs/02_document/contracts/ this cycle. AZ-494 strictly tightens token acceptance (rejects with 401 on iss/aud mismatch) without changing the public HTTP surface.
  • The Microsoft.AspNetCore.Authentication.JwtBearer middleware now validates four claim-shape invariants instead of two (signing key + lifetime + issuer + audience).
  • Cycle-2 contract _docs/02_document/contracts/api/uav-tile-upload.md v1.0.0 unchanged.

Net Architecture delta vs cycle 2

  • Resolved: F-AUTH-2 (iss/aud unvalidated), D1 (OpenApi 8.0.21 patch line), D3 (JwtBearer 8.0.21 patch line), PT-07/PT-08 cycle-2 leftover. Total: 4 resolved.
  • Newly introduced: D4 (Low, test-only NU1902 pin), F-AUTH-3 (Informational, test-runner log), F-AUTH-4 (Informational, by-design DEV-ONLY placeholders), F-DBR-2 (Low, test-only TRUNCATE guard), F-PERF-1 (Low, operator-CLI token-on-stdout). F-DBR-1 explicit false-positive. Total: 3 new Low + 2 Informational + 1 FP.
  • Net Architecture delta: -1 finding overall, -3 Medium-or-above (the 3 cycle-3 introductions are all Low or Informational; the 3 prior resolutions were 2 Medium + 1 Low).

First cycle with a net-negative architecture delta. Pattern: prior-retro Action items + targeted dependency bumps + spec hardening combined to retire more debt than they introduced.