# Cycle 5 — Documentation Ripple Log

**Cycle**: 5 (AZ-504 perf-script pipefail fix + AZ-503-foundation UUIDv5 tile identity)
**Generated by**: `/document` skill (task mode) during autodev Step 13
**Resolution method**: `Grep --type cs` against every new or changed symbol introduced by the two tasks. C# `using`-based import analysis on `Uuidv5`, `TileEntity` (new properties), `UavTileMetadata.FlightId`, `TileRepository.InsertAsync` (changed UPSERT key). No static-analyzer (NDepend, etc.) was used — the surface is small and the literal usage scan is exhaustive.

## Directly-changed source files (cycle 5)

- `scripts/run-performance-tests.sh` (AZ-504, lines 416–417) — wrapped `grep -o` counters in `{ … || true; }` to survive zero-match cases under `set -o pipefail`. Pure shell; no C# importers.
- `SatelliteProvider.Common/Utils/Uuidv5.cs` (AZ-503, **new**) — pure-C# UUIDv5 generator + `TileNamespace` constant.
- `SatelliteProvider.Common/DTO/UavTileMetadata.cs` (AZ-503, modified) — added optional `Guid? FlightId` property.
- `SatelliteProvider.DataAccess/Migrations/014_AddTileIdentityColumns.sql` (AZ-503, **new**) — adds `flight_id`, `location_hash`, `content_sha256`, `legacy_id`; backfills `location_hash`; supersedes the AZ-484 unique index with `idx_tiles_unique_identity`.
- `SatelliteProvider.DataAccess/Models/TileEntity.cs` (AZ-503, modified) — 4 new properties (`FlightId`, `LocationHash`, `ContentSha256`, `LegacyId`).
- `SatelliteProvider.DataAccess/Repositories/TileRepository.cs` (AZ-503, modified) — `InsertAsync` UPSERT now uses the integer-only + flight-aware conflict key; `id` not overwritten on conflict; `UpdateAsync` writes all four new columns.
- `SatelliteProvider.Services.TileDownloader/TileService.cs` (AZ-503, modified) — `BuildTileEntity` computes deterministic `Id`, `LocationHash`, `ContentSha256`; `FlightId` always null for Google Maps.
- `SatelliteProvider.Services.TileDownloader/UavTileUploadHandler.cs` (AZ-503, modified) — `PersistAsync` reads `metadata.FlightId`, computes deterministic identity fields, writes file to `./tiles/uav/{flight_id or 'none'}/{z}/{x}/{y}.jpg`.
- `SatelliteProvider.IntegrationTests/SatelliteProvider.IntegrationTests.csproj` (AZ-503, modified) — added `ProjectReference` to `SatelliteProvider.Common` so seed SQL can call `Uuidv5.Create`.
- `SatelliteProvider.IntegrationTests/UavUploadTests.cs` (AZ-503, modified seeder + 2 new tests).
- `SatelliteProvider.IntegrationTests/MigrationTests.cs` (AZ-503, 3 new assertions; renamed AZ-484 supersession test).
- `SatelliteProvider.Tests/Uuidv5Tests.cs` (AZ-503, **new** — 10 Python-parity reference vectors).
- `SatelliteProvider.Tests/UavTileFilePathTests.cs` (AZ-503, **new** — per-flight on-disk path).
- `SatelliteProvider.Tests/UavTileUploadHandlerTests.cs` (AZ-503, 2 new tests added; existing tests unchanged).

## Importer scan results

| Symbol | Importer count | Importer files | Component touched |
|--------|----------------|----------------|-------------------|
| `SatelliteProvider.Common.Utils.Uuidv5` / `Uuidv5.Create` / `Uuidv5.TileNamespace` | 5 | `TileService.cs`, `UavTileUploadHandler.cs`, `Uuidv5Tests.cs`, `MigrationTests.cs`, `UavUploadTests.cs` | TileDownloader (production), Tests (unit + integration) |
| `UavTileMetadata.FlightId` (new field) | 2 | `UavTileUploadHandler.cs` (read), `UavUploadTests.cs` (serializer payload) | TileDownloader, Tests (integration) |
| `TileEntity.FlightId` / `LocationHash` / `ContentSha256` / `LegacyId` (new columns) | 3 | `TileRepository.cs`, `TileService.cs`, `UavTileUploadHandler.cs` | DataAccess, TileDownloader |
| `TileRepository.InsertAsync` (changed UPSERT conflict key) | 4 | `TileService.cs`, `UavTileUploadHandler.cs`, `RegionService.cs`, `TileServiceTests.cs` (via mock) | TileDownloader, RegionProcessing, Tests (unit) |
| `pgcrypto` extension (new DB dependency from migration 014) | 1 | `014_AddTileIdentityColumns.sql` (in-migration temp PL/pgSQL only) | DataAccess (migration-only; runtime code does not depend on pgcrypto) |

## Doc refresh decisions

All importers land inside components that already received targeted updates during Step 10 (Implement) and this Step 13:

- **Common** — created `_docs/02_document/modules/common_uuidv5.md` (new utility module doc). Updated `_docs/02_document/modules/common_dtos.md` `UavTileMetadata` section to document `FlightId` + the `null`-vs-flight semantics.
- **DataAccess** — updated `_docs/02_document/modules/dataaccess_models.md` (4 new `TileEntity` properties) and `_docs/02_document/modules/dataaccess_tile_repository.md` (new UPSERT semantics; `id`-not-overwritten invariant). Updated `_docs/02_document/components/02_data_access/description.md` (data-access patterns table, caveats — replaced AZ-484 5-col index entry with AZ-503 6-col integer-only index; documented deterministic identity).
- **TileDownloader** — updated `_docs/02_document/modules/services_tile_service.md` (`BuildTileEntity` deterministic identity; SHA-256 dependency; new module dependencies on `Uuidv5` and `SHA256`).
- **TileDownloader / `UavTileUploadHandler`** — no dedicated module doc exists for this handler; its surface is already covered by `api_program.md` and the `uav-tile-upload.md` contract. Both updated below.

System-level docs also updated this pass:
- `architecture.md` — extended the append-by-source bullet to append-by-source-and-flight (AZ-503), added a cross-repo deterministic-id principle, refreshed ADR-004 (file-storage layout) and the multi-source-producers section to mention `flightId` and the deterministic `id`.
- `data_model.md` — added the 4 new `tiles` columns, the new index `idx_tiles_unique_identity`, the new index `idx_tiles_location_hash`, the new UPSERT contract semantics, and migration 014 in the migration history.
- `contracts/api/uav-tile-upload.md` — minor version bump v1.0.0 → v1.1.0: added optional `flightId` field, documented per-flight on-disk path, documented deterministic `tileId`. Backward-compatible by design.
- `tests/blackbox-tests.md` and `tests/traceability-matrix.md` — updated during Step 12 (Test-Spec Sync) with BT-19 … BT-22 + per-AC trace rows.

## No-ripple components

These components were NOT touched by cycle-5 changes and require no doc update:

- **RegionProcessing** — `RegionService` consumes `ITileRepository.InsertAsync`/`GetTilesByRegionAsync` unchanged. Region read path uses the AZ-484 selection rule which AZ-503 preserved.
- **RouteManagement** — no imports against cycle-5 symbols; route processing reads tiles only via the unchanged region read path.
- **WebApi (`Program.cs`)** — endpoint contract surface unchanged on the wire (the optional `flightId` field is transparent at the routing level; deserialization is owned by `UavTileBatchMetadataPayload` / `UavTileMetadata` in Common). No `api_program.md` edits needed for AZ-503.

## Parse-failure / heuristic notes

None — every symbol resolved via direct `Grep`. No fallback heuristic was needed.

## AZ-504 ripple

`scripts/run-performance-tests.sh` is a shell harness with no code-side importers. Its docs are owned by the test-spec sync layer (`tests/traceability-matrix.md` AC-1..AC-4 rows, updated during Step 12) and the `_docs/02_tasks/done/AZ-504_*.md` task spec. No module-doc ripple.
