AZ-512 (Admin edit detection class) hit its spec-defined Cross-Workspace
Verification gate during cycle 3 batch 15. The admin/ service
(Azaion.AdminApi/Program.cs) exposes /login, /users*, /resources* only — no
/classes routes exist, so neither the PATCH this task needs nor the
POST/DELETE that AdminPage.tsx already calls today are wired end-to-end.
Per the spec's Choose A/B/C (user skipped, defaulted to A): file a
prerequisite ticket on admin/ and pause AZ-512 in backlog/. AZ-510 + AZ-511
already shipped this cycle; cycle 3 closes with 6 of 9 points delivered.
- Move AZ-512 spec from todo/ to backlog/ with a STATUS banner.
- Add Jira comment on AZ-512 documenting the blocker + replay path.
- Write leftover record _docs/_process_leftovers/2026-05-13_az-512-...
capturing the full prerequisite payload (suggested ticket summary,
description, ACs, story points) and the side observation that the
existing add+delete affordances on the Detection Classes table are
also broken end-to-end against admin/ (pre-existing bug, NOT
introduced by cycle 3).
- Write batch 15 deferral report.
- Write Product Implementation Completeness Gate report (PASS for
AZ-510 + AZ-511; AZ-512 deferred is outside the gate's scope).
- Write final cycle 3 implementation report with handoff to Step 11.
- Advance state: step 10 -> step 11 (Run Tests).
Co-authored-by: Cursor <cursoragent@cursor.com>
Move src/features/annotations/classColors.ts to its own component directory
src/class-colors/ with a proper barrel; update the 4 consumer imports to go
through the barrel; remove the F3-pending exemption from STC-ARCH-01 and from
the architecture test fixture; clean up the 5 coupled doc/script touchpoints.
Closes baseline finding F3 and retires the 5-coupled-places carry-over surface
logged in LESSONS.md 2026-05-12.
- Add `class-colors` to scripts/check-arch-imports.mjs COMPONENT_DIRS so deep
imports past the new barrel are caught symmetric to every other component.
- Replace the architecture test "exemption WORKS" fixture with the stronger
"deep import into class-colors NOW FAILS" assertion (Risk 4 mitigation).
- module-layout.md: Layout Rules + Per-Component Mapping (11_class-colors,
06_annotations, 03_shared-ui) + Verification Needed #1 + shared/class-colors
block all updated to reflect the new home.
- 11_class-colors/description.md: Caveats §7 + Module Inventory updated.
- architecture_compliance_baseline.md: F3 marked CLOSED with full pre-resolution
context preserved (mirrors AZ-485/F4 + AZ-486/F7 pattern); F4 carry-forward
exemption note retired.
- 04_verification_log.md: open questions #1 + #8 marked RESOLVED.
- Build passes with no circular-import warnings (AC-4); fast suite 231/13
skipped green (AC-5); static profile green (AC-3 — zero exemptions remain).
Batch report: _docs/03_implementation/batch_14_cycle3_report.md
Co-authored-by: Cursor <cursoragent@cursor.com>
Recovers cycle 3 Step 9 (New Task) outputs that were left uncommitted at
the prior session boundary. Adds AZ-509 epic to dependencies table and
the three task specs (AZ-510 auth bootstrap consolidation, AZ-511
classColors carve-out, AZ-512 admin edit detection class). Advances
autodev state to step 10 (Implement) in_progress.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Changed current step from 15 (Performance Test) to 9 (New Task) in _docs/_autodev_state.md, reflecting the transition to Cycle 3.
- Updated cycle count from 2 to 3 and modified sub-step details to indicate progress in gathering feature descriptions.
- Added new lessons to _docs/LESSONS.md, emphasizing best practices for API key management, dependency handling, and reporting inline fixes during security audits.
- Enhanced CI/CD pipeline documentation in _docs/02_document/deployment/ci_cd_pipeline.md to include new gates for vulnerability scans and SBOM emissions, along with dependency overrides for transitive dependencies.
- Expanded environment strategy documentation in _docs/02_document/deployment/environment_strategy.md to include the new Google Geocode API key management.
Co-authored-by: Cursor <cursoragent@cursor.com>
AZ-498 — self-hosted satellite tiles + drop classic/satellite toggle:
- Single TILE_URL via getTileUrl() (mirrors getOwmBaseUrl/getApiBase
pattern from AZ-449/AZ-450); env-var VITE_SATELLITE_TILE_URL with
dev default http://localhost:5100/tiles/{z}/{x}/{y}.
- FlightMap + MiniMap render one TileLayer with
crossOrigin="use-credentials" so Leaflet's <img> tile fetcher
attaches the same-origin satellite-provider auth cookie.
- ImportMetaEnv + .env.example collapse the prior OSM/Esri pair into
one var. The flights.planner.satellite i18n key is removed in
lockstep across en.json + ua.json (parity preserved).
- E2E harness wired end-to-end: compose passes the new var to
azaion-ui; tile-stub serves /tiles/{z}/{x}/{y} with
Content-Type=image/jpeg + Cache-Control + ETag matching the
contract; infrastructure.e2e.ts AC-2 asserts the new path; dead
OSM defenses removed from EXTERNAL_HOSTS route guard.
- Fast-profile MSW handlers rewritten for the cookie-auth path shape.
- 8 colocated fast tests under src/features/flights/__tests__/.
AZ-499 — mission-planner OWM env-var hardening + AZ-482 source-scan
gap close:
- WeatherService.ts reads VITE_OWM_API_KEY + VITE_OWM_BASE_URL;
fail-soft null when key unset (mirrors AZ-448 main-SPA contract).
Public signature getWeatherData(lat, lon) preserved.
- mission-planner/.env.example + vite-env.d.ts declare both vars.
- New owm_key_in_source banned-deps kind scans src/ AND
mission-planner/ for the rotated literal; STC-SEC1C row added to
scripts/run-tests.sh; check-banned-deps.mjs dispatch extended.
- 7 fast tests under tests/mission_planner_weather.test.ts cover
AC-1..AC-4 + trailing-slash + happy path + network-error fail-soft.
Spec drift (recorded in batch_11_report.md, user-approved Choose B
on 2026-05-12):
- AZ-498 AC-8 dropped (named tile_split_zoom* files belong to AZ-474
image-annotation surface, not map tiles).
- 4 missing files added in-scope (msw tiles handler, tile-stub
server, compose env, dead VITE_TILE_BASE_URL replaced).
- AZ-499 STC-S6 ID conflict resolved by using STC-SEC1C.
Pending USER ACTION (BLOCKING for AZ-499 close):
- Revoke OpenWeatherMap key 335799082893fad97fa36118b131f919 at
home.openweathermap.org/api_keys; capture evidence on AZ-499.
Cross-workspace deploy gate (handled at autodev Step 16, not a
Step-10 blocker for AZ-498):
- satellite-provider cookie-auth on GET /tiles/{z}/{x}/{y}
(separate AZAION ticket on the satellite-provider workspace).
Reports: _docs/03_implementation/batch_11_report.md and
_docs/03_implementation/reviews/batch_11_review.md (verdict
PASS_WITH_WARNINGS — 1 Low, pre-existing trim-trailing-slash
duplication across vite roots).
Static gates: STC-ARCH-01, STC-ARCH-02, STC-T1, STC-FP22, STC-FP23,
STC-SEC1C all PASS post-refactor. +15 fast tests; +1 STC-SEC1C row.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Changed current step from 16 (Deploy) to 9 (New Task) and updated cycle from 1 to 2 in _docs/_autodev_state.md.
- Closed Cycle 1 (Phase B) and noted that Steps 14, 15, and 16 were skipped due to no changes in auth, wire, or performance surfaces.
- Added new lessons to _docs/LESSONS.md, including insights on architecture gates and handling state discrepancies during session resumes, sourced from recent retrospectives.
Co-authored-by: Cursor <cursoragent@cursor.com>
Phase B cycle 1 was a structural refactor only: F4 (barrel imports +
STC-ARCH-01) and F7 (endpoint builders + STC-ARCH-02). This commit
brings docs in line with source after the cycle, no code changes.
Module docs (12 consumers): swap every /api/<service>/... literal in
code snippets and integration tables for the matching endpoints.*
builder; note the barrel import migration in Dependencies.
New module doc: src__api__endpoints.md (public surface, F4 barrel
re-export note, STC-ARCH-02 enforcement, contract-test reference).
Architecture compliance baseline: mark F4 + F7 CLOSED with commit
hashes (23746ec, 8a461a2).
01_api-transport component description: add endpoints.ts + barrel to
Internal Interfaces, close the F7 caveat, extend Module Inventory.
ripple_log_cycle1.md: Task Step 0.5 reverse-dep analysis records the
import-graph closure (no extra docs needed beyond the direct set).
Carry-over reports landed alongside the docs:
- test_run_report_phase_b_cycle1.md (Step 11 outcome)
- implementation_report_refactor_phase_b_cycle1.md (cycle summary)
State file: trimmed to the autodev <30-line target; Steps 14 + 15
recorded as SKIPPED with rationale (no security or perf surface
changed in this cycle); pointer moved to Step 16 (Deploy).
Co-authored-by: Cursor <cursoragent@cursor.com>
Closes architecture baseline finding F4. Every component now exposes
its Public API through `src/<component>/index.ts`; cross-component
imports go through the barrel. `scripts/check-arch-imports.mjs` plus
`STC-ARCH-01` in the static profile enforce the rule; tests in
`tests/architecture_imports.test.ts` cover AC-4/AC-5 + 2 exemption
cases. One F3-pending exemption (`classColors`) is documented in 5
places (barrel, consumer, script, doc, test) to avoid a circular
import.
Phase B cycle 1 batch 1 of 2 (epic AZ-447). Batch 2 is AZ-486
(endpoint builders) — blocked on this commit landing.
Co-authored-by: Cursor <cursoragent@cursor.com>
Closes Step 9 New Task cycle 1. Two refactor tasks created under epic
AZ-447 to address architecture compliance baseline findings:
- AZ-485 (5 pts) — F4 Public API barrels per component + STC-ARCH-01
- AZ-486 (5 pts) — F7 endpoint builders (endpoints.ts) + STC-ARCH-02
(depends on AZ-485; Jira "Blocks" link set)
F1 (mission-planner duplication) deliberately deferred. Baseline routes
it through 7+ Phase B port-group cycles requiring decompose pass into
its own Epic; out of scope for new-task.
_autodev_state.md advances to Step 10 (Implement), awaiting invocation
for AZ-485 first.
Co-authored-by: Cursor <cursoragent@cursor.com>
The Playwright base image
(mcr.microsoft.com/playwright:v1.49.1-noble) ships without
unzip, which bun's curl|bash installer requires:
error: unzip is required to install bun
process "/bin/sh -c curl -fsSL https://bun.sh/install ..."
did not complete successfully: exit code: 1
Found while user asked the agent to attempt to bring up the
suite-e2e compose stack. Latent bug — the runner image had
never been built successfully in any local workspace before.
Test report (test_run_report.md) updated with the concrete
error trace from the up attempt: the 6 azaion/<S>:test
service images are pull-access-denied (not in any reachable
registry from this host), confirming the legitimate
external-service env block. Local-build half (azaion-ui,
owm-stub, tile-stub, playwright-runner) is healthy.
No e2e tests were executed; Step 7 verdict unchanged
(PASS_WITH_DOCUMENTED_GATE; e2e deferred to CI / merge lane).
Co-authored-by: Cursor <cursoragent@cursor.com>
- static profile: 29/29 PASS (~13s)
- fast profile: 163 PASS / 13 SKIP / 0 FAIL across 26 files (~14.6s)
- e2e profile: user-approved env-block (suite service :test
images not available locally, not buildable from sibling
repos today, registry auth not configured in this workspace).
Deferred to CI / merge lane with registry access.
- 13 skips: all user-approved as Phase B feature quarantines
paired with control PASS tests; tracked in F-CUM-3 / F-CUM-5
drift backlog.
- System-Under-Test Reality Gate: PASS (no internal modules
faked; only external suite services are stubbed).
Step 7 closes; advance to Step 8 (Refactor — optional).
Co-authored-by: Cursor <cursoragent@cursor.com>
Final test-implementation report with handoff to test-run
skill per implement skill Step 16 (next flow step is Run
Tests; let test-run own the full-suite gate to avoid
duplicate runs).
27 test tasks delivered across 8 batches (1 + 4*6 + 4 + 2);
0 production source mutations; 26/26 ACs covered; 23
production drifts pinned to runnable contract tests; 29
commit-time static gates active (up from 13 at baseline).
State: existing-code Step 7 (Run Tests), not_started.
Co-authored-by: Cursor <cursoragent@cursor.com>
K=3 cadence cumulative review for the final 2 batches of
Phase A. Verdict: PASS_WITH_WARNINGS (0 Critical / 0 High;
F-CUM-5 lifts production-drift backlog to 23 entries;
F-CUM-4 long-running soak tagging carries over).
Phase A is now COMPLETE: 25 test tasks delivered across 8
batches; 0 production source mutations; 26/26 ACs covered
in this window; 100% cumulative AC coverage; 29 commit-time
static gates active.
Next autodev action: Step 7 (Run Tests).
Co-authored-by: Cursor <cursoragent@cursor.com>
- AZ-474 tile-split + YOLO parser + auto-zoom + indicator +
malformed (FT-P-51..55, FT-N-10): 13 fast (6 it.fails for
AC-1..6 + 7 controls) + 2 e2e (test.fail for FT-P-51 +
FT-P-53). The split surface is QUARANTINED today (D11) —
no Split-tile button, no parser, no <TileViewer>; all 6
ACs are documented drift, every it.fails paired with a
control PASS pinning current behaviour.
- AZ-480 prod image + nginx routing + RAM (NFT-RES-LIM-02
/03/08/09/10): 4 new static checks promoted into the
per-commit profile (STC-RES02 500M cap, STC-RES03
Dockerfile final-stage nginx:alpine no Node, STC-RES09
exactly 9 /api/* location blocks, STC-RES10 prefix-strip
on every route). 3 e2e (docker-no-Node probe, runtime
prefix-strip, long-running RAM soak — all gated on docker
availability + image build; RAM soak also on
RUN_LONG_RUNNING=1).
Phase A — One-time baseline setup is now COMPLETE. The
todo/ directory is empty after this batch's archival.
Cumulative review for batches 07-08 is the next autodev
action; after that, Step 7 (Run Tests) auto-chains.
Code review: PASS (0 findings). Fast: 26/26 files, 163
passed / 13 skipped. Static: 29/29 PASS (incl. 4 new
STC-RES* gates).
Co-authored-by: Cursor <cursoragent@cursor.com>
Implements 4 blackbox-test tasks for AZ-455 Phase A baseline:
- AZ-458 SSE lifecycle + bearer rotation: 9 fast tests (8 pass, 1
QUARANTINE for annotation-status); 4 e2e scenarios (gated by suite
stack). Uses tests/helpers/sse-mock.ts with globalThis.EventSource
monkey-patch per AC-3 (no stub of src/api/sse.ts). AC-2 bearer
rotation captured as documented drift via it.fails() — FlightsPage
useEffect deps do not include the token today.
- AZ-467 ProtectedRoute spinner + timeout + RBAC: 9 new fast tests
extending the AZ-457 file (6 pass, 3 QUARANTINE), plus 3 e2e
scenarios. FT-P-32 spinner a11y is it.fails() drift; FT-P-33 timeout
and FT-N-03/05 RBAC redirects are it.skip QUARANTINE (no production
behavior today). Positive control: admin_carol reaches /admin.
- AZ-468 Header flight-dropdown a11y: 6 fast tests (5 pass, 1
QUARANTINE). FT-P-30/31 are it.fails() drift (aria-expanded /
role=listbox / aria-activedescendant currently missing); FT-N-09
is it.skip QUARANTINE (no document keydown handler exists).
- AZ-482 Secrets + banned-libs + AC-N1 anti-criterion: 3 new static
checks (STC-SEC13 legacy integrations, STC-SEC14 concurrent-edit,
STC-SEC1B dist/ OWM key) plus refactor of 4 existing checks
(STC-N2/N4/S13/S6) to read from tests/security/banned-deps.json
via scripts/check-banned-deps.mjs per AZ-482 constraint
("deny-list lives in tests/security/banned-deps.json so additions
are visible in code review"). All 22 static checks PASS.
Totals: 57 fast tests pass + 9 skipped; 22/22 static checks pass.
Self-review verdict PASS_WITH_WARNINGS — all five findings are
documented drifts captured by it.fails() / it.skip QUARANTINE +
control tests. See _docs/03_implementation/batch_03_report.md
for the per-task / per-AC matrix and recommended Phase B follow-up
production tasks (Header a11y; ProtectedRoute spinner/timeout/RBAC;
SSE bearer-rotation reconnect; AnnotationsPage SSE).
Co-authored-by: Cursor <cursoragent@cursor.com>
/dist is already listed in .gitignore but three legacy files
(dist/index.html, dist/assets/index-B-KLvAXK.js,
dist/assets/index-Du68yxJU.css) remained in the index from before
the ignore rule was added. Untrack them so the working tree stays
clean across implement-skill batch cycles. Files remain on disk
where present; future build outputs will be ignored as intended.
Co-authored-by: Cursor <cursoragent@cursor.com>
Split the "Imports from" entry for the Blackbox Tests cross-cutting
component into two cases:
- Test bodies (*.test.{ts,tsx}, *.spec.{ts,tsx}, e2e specs) keep the
strict "00_foundation only / src/types only" rule per black-box
discipline (P9 / environment.md).
- Test infrastructure (tests/setup.ts, tests/msw/**, tests/helpers/**,
tests/fixtures/**, e2e/playwright.config.ts, e2e/stubs/**, etc.) MAY
import testability-purpose production accessors from any layer
(e.g. setToken on 01_api-transport, AuthProvider on 02_auth, i18n
on 00_foundation) — these helpers ARE the production-equivalent
composition root for tests.
Surfaced during AZ-456 self-review when render.tsx / auth.ts /
navigate.ts had to import production accessors that the task spec
explicitly mandated. The original rule was unambiguous-but-incomplete;
the doc now matches the practical reality without weakening the
black-box discipline for test bodies themselves.
Co-authored-by: Cursor <cursoragent@cursor.com>
Records that batch 1 = [AZ-456] is computed, file-ownership envelope
resolved, and Jira ticket transitioned to In Progress. Next step:
write the test-infrastructure scaffold (~30 files) and run the fast
+ static profiles. Suggests a session boundary here per Context
Management Protocol so phase 6 starts with fresh context.
Co-authored-by: Cursor <cursoragent@cursor.com>
Adds a cross-cutting "Blackbox Tests" entry to
_docs/02_document/module-layout.md so the implement skill's Step 4
(file ownership) can resolve OWNED / READ-ONLY / FORBIDDEN globs for
every AZ-455 test task (AZ-456..AZ-482). Owns: tests/**, e2e/**,
**/*.{test,spec}.{ts,tsx}, vitest.config.ts, test sections of
package.json, scripts/run-tests.sh + run-performance-tests.sh
(extension only). Imports from src/types/index.ts only (P9 black-box
discipline). Advances Step 6 sub_step to phase 1 (parse).
Co-authored-by: Cursor <cursoragent@cursor.com>
- Archive Batch 2 task specs (AZ-448, AZ-449, AZ-453) to
_docs/02_tasks/done/.
- Write testability_changes_summary.md (refactor Phase 4.5; user-acked
via autodev existing-code Step 4 gate).
- Write FINAL_report.md closing the 01-testability-refactoring run.
- Advance autodev state pointer to Step 5 (Decompose Tests).
Refactor Phases 5/6/7 are no-ops for testability runs (no tests exist
yet; doc updates are deferred to autodev Step 13). Verification axis
for this run is the static-check matrix recorded in
testability_changes_summary.md § Verification snapshot.
Co-authored-by: Cursor <cursoragent@cursor.com>
Batch 2 of testability refactor under epic AZ-447. All three changes are
minimal-surgical and preserve production behavior.
AZ-448 (C01) — Externalize OWM API key
- src/features/flights/flightPlanUtils.ts: read VITE_OWM_API_KEY at call
time; if unset, getWeatherData returns null (matches the existing
try/catch fallback contract, AC-3).
- Hardcoded literal removed; grep src/ for the old key returns no hits
(AC-2 / NFT-SEC-09 static-string check now green).
- AC-1 honored: when the key is set, the outbound URL contains
appid=<key>.
AZ-449 (C02) — Externalize OWM base URL
- Same call site reads VITE_OWM_BASE_URL with trim-trailing-slash
normalization; falls back to the public api.openweathermap.org/data/2.5
endpoint when unset (AC-1).
- Stub-friendly: VITE_OWM_BASE_URL=http://owm-stub:8081/data/2.5
redirects every call to the e2e stub (AC-2).
AZ-453 (C06) — Wrap login redirect in setNavigateToLogin accessor
- src/api/client.ts: navigateToLoginImpl module-level fn defaults to the
existing window.location.href = '/login' write; setNavigateToLogin(fn)
lets tests assert "redirect invoked" without globally stubbing
window.location.
- request() now calls navigateToLoginImpl() instead of writing
window.location directly.
Batch 1 task specs (AZ-450/451/452/454) moved from
_docs/02_tasks/todo/ to _docs/02_tasks/done/.
State pointer advanced to refactor Phase 4 (implement, batch 2 of 2).
Static checks:
- bun run tsc --noEmit: 0 errors
- grep '335799082893fad97fa36118b131f919' src/: 0 hits
- grep 'window.location.href' src/: 2 hits, both inside the
navigateToLoginImpl default (jsdoc + the default impl body) — no
caller writes window.location directly.
Co-authored-by: Cursor <cursoragent@cursor.com>
Refactor batch 1 of 2 for the 01-testability-refactoring epic
(AZ-447). Minimal-surgical edits to make the UI's external
dependencies overridable for the test profiles in
_docs/02_document/tests/environment.md.
- AZ-450 (C03): tile URLs externalized to VITE_OSM_TILE_URL and
VITE_ESRI_TILE_URL with the production strings as defaults.
Fixes the AC-N3 / NFT-RES-03 air-gap regression and lets the
e2e profile's tile-stub serve tiles deterministically.
- AZ-451 (C04): Leaflet marker icon imported from the pinned
leaflet package as a Vite asset; removes the unpkg.com CDN
reference (also fixes the leaflet@1.7.1 vs ^1.9.4 mismatch).
- AZ-452 (C05): getApiBase() accessor reading
VITE_API_BASE_URL. request(), refreshToken(), and createSSE()
prepend the prefix. Default '' preserves every call site.
- AZ-454 (C07): JSDoc on setToken/getToken documenting the
test-override intent so future cleanup doesn't delete them.
Also: .env.example documents every VITE_* var; vite-env.d.ts
declares ImportMetaEnv; .gitignore now excludes /dist and
*.tsbuildinfo (tracked-by-mistake cache file removed).
Build verification: `bunx tsc -b --noEmit` passes. No tests in
this run (testability-run exemption per refactor SKILL — tests
land in autodev Step 6).
Co-authored-by: Cursor <cursoragent@cursor.com>
Replaced HARBOR_USER and HARBOR_TOKEN with REGISTRY_USER and REGISTRY_TOKEN for Docker login. Adjusted image tagging to include 'azaion' in the registry path, ensuring proper image management in the new TLS-authenticated Harbor registry.
Add HARBOR_USER/HARBOR_TOKEN from Woodpecker secrets and a docker login
step before the existing build/push, so pipelines can push to the new
TLS-authenticated Harbor registry.