Files
ui/_docs/06_metrics/retro_2026-05-13_cycle3.md
Oleksandr Bezdieniezhnykh eef3bdf7db [AZ-509][AZ-510][AZ-511] Cycle 3 closure: deploy + retro + state
Steps 16 (Deploy) and 17 (Retrospective) outputs for cycle 3.

- 03_implementation/deploy_cycle3_report.md — ui/ dev pushed
  (15838c5..09449bd, 5 commits); stage/prod cutover deferred
  per push-scope gate option A.
- 06_metrics/retro_2026-05-13_cycle3.md — cycle 3 retro: 6/9
  pts shipped (AZ-510, AZ-511); AZ-512 deferred to backlog
  at cross-workspace prereq gate (AZ-513 filed on admin/).
- 06_metrics/structure_2026-05-13.md — structural snapshot
  referenced by retro.
- LESSONS.md — appended 3 cycle-3 lessons (process x2,
  architecture x1).
- _autodev_state.md — cycle 3 closed; cycle 4 Step 9 not
  started.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:15:37 +03:00

18 KiB
Raw Permalink Blame History

Retrospective — 2026-05-13 (Phase B Cycle 3)

Mode: cycle-end (autodev existing-code Step 17) Scope: Phase B, cycle 3 (state.cycle = 3) Epic: AZ-509 (UI workspace cycle 3 — Auth bootstrap fix + classColors carve-out + admin edit) Cycle duration: 3 batches over 1 working day (2026-05-13) Previous retro: _docs/06_metrics/retro_2026-05-12_cycle2.md (cycle 2)

Implementation Summary

Metric Value Δ vs cycle 2
Tasks attempted 3 (AZ-510, AZ-511, AZ-512) +1
Tasks delivered 2 (AZ-510, AZ-511) 0
Tasks deferred at spec gate 1 (AZ-512 — cross-workspace prereq) +1 (new pattern)
Total batches 3 (batch 13, 14, 15) +1
Total complexity points planned 9 (3+3+3) 2
Total complexity points delivered 6 (3+3) 5 (cycle 2 shipped 11)
Avg tasks per batch 1 1
Avg complexity per (completed) batch 3 2.5
Source files mutated ~37 production + test (AZ-510 ~25, AZ-511 ~12, AZ-512 0) + 9 docs n/a (different shape)

Sources: batch_13_cycle3_report.md, batch_14_cycle3_report.md, batch_15_cycle3_report.md, implementation_report_auth_classcolors_cycle3.md, implementation_completeness_cycle3_report.md, deploy_cycle3_report.md, security_report_cycle3_delta.md.

Quality Metrics

Code Review Results

Verdict Count Percentage Δ vs cycle 2
PASS 2 (batches 13, 14) 67 % +2
PASS_WITH_WARNINGS 0 0 % 1
FAIL 0 0 % 0
(no formal review — deferred at gate) 1 (batch 15) 33 % n/a

Note: batch 15 (AZ-512) hit a spec-defined Cross-Workspace Verification BLOCKING gate before implementation began. No source code was written, no review fired. The "no review" row is not a process gap — it is the spec working correctly.

Findings by Severity (code review only)

Severity Count Δ vs cycle 2
Critical 0 0
High 0 0
Medium 0 0
Low 0 1 ✓ (cycle 2's pre-existing trim-trailing-slash F1 was not re-flagged because cycle 3 did not touch the affected files)

Findings by Category (code review)

Category Count Top Files
Bug 0
Spec-Gap 0
Security 0 (in code review; security audit fires separately — see below)
Performance 0
Maintainability 0
Style 0
Scope 0

Security-Audit Findings (Step 14 — cycle 3 delta against cycle 2 baseline)

12 carried + 1 new = 13 total. Cycle 3 net delta:

Status change Count Notable IDs
Closed (HIGH → resolved) 2 F-DEP-1 (Vite/PostCSS CVEs — closed by cycle-2-tail bun update), OWASP A07 cold-load gap (closed by AZ-510)
Strengthened (defense-in-depth) 1 STC-ARCH-01 exemption removed (closed by AZ-511)
Newly introduced (LOW) 1 F-SAST-CY3-1 — __resetBootstrapInflightForTests exposed via src/auth barrel (AZ-510)
Carried forward unchanged (HIGH) 1 F-SAST-1 (Google key in mission-planner/ git history; production exposure NONE — see cycle 2 leftover L-AZ-501-GOOGLE-REVOKE)
Carried forward unchanged (MEDIUM) 7 F-SAST-2/3, F-INF-1..4 (infra hardening backlog)

Security verdict trajectory: cycle 2 verdict FAIL → cycle 3 verdict PASS_WITH_WARNINGS (driver: all HIGH findings closed; one LOW hygiene item introduced; one HIGH carried at git-history layer with NONE production exposure).

OWASP A06 (Vulnerable & Outdated Components): FAIL → PASS. OWASP A07 (Identification & Authentication Failures): PASS_WITH_KNOWN → PASS.

Structural Metrics

Source: _docs/06_metrics/structure_2026-05-13.md (this cycle), compared against structure_2026-05-12.md (cycle 1 close — cycle 2 introduced no structural changes).

Metric Cycle 1 close Cycle 2 close Cycle 3 close Δ vs cycle 2
Component count 12 12 12 0
Public-API barrels 11 / 11 (100 %) 11 / 11 (100 %) 11 / 11 (100 %) 0
STC-ARCH-01 carve-out exemptions 1 (classColors) 1 0 1
Commit-time static gates 31 / 31 PASS 33 / 33 PASS 33 / 33 PASS 0 (STC-ARCH-01 strengthened, no new gates added)
Architecture cycles 0 0 0 0
Architecture findings open (baseline F1F9) 7 of 9 7 of 9 6 of 9 1 ✓ (F3 closed)
Newly introduced architecture violations 0 0 0 0
Net architecture delta this cycle 2 0 1 continued improvement
Wire-contract assertions (endpoints.test.ts) 36 36 37 +1 (endpoints.admin.usersMe)
Fast-profile suite 209 PASS / 13 SKIP / 0 FAIL 229 PASS / 13 SKIP / 0 FAIL 231 PASS / 13 SKIP / 0 FAIL +2 PASS
Bundle (gzipped initial JS) not measured 290 465 B 290 575 B +110 B (+0.04 %; ~14 % budget)

Auto-lesson triggers (per skill Step 1)

  • Net Architecture delta > 0? No — delta is 1 (improvement). No architecture regression lesson required.
  • Structural metric regression > 20 %? No — every structural metric held or improved.
  • Contract coverage % decreased? No — wire-contract assertions +1 (37 vs 36).
  • New finding category emerged? No — security audit ran in delta mode against the cycle 2 baseline; categories are stable.

Efficiency

Metric Value Δ vs cycle 2
Blocked tasks (cycle-internal) 0 0
Tasks deferred to backlog at spec gate 1 (AZ-512) +1 (new pattern)
Cross-workspace prerequisite tickets filed 1 (AZ-513 on admin/) +1 (new pattern)
Pre-existing bugs surfaced as side observations 1 (AdminPage.tsx add+delete buttons broken end-to-end against live admin/) +1
Tasks pending external user action (cycle-3 close) 7 +4 vs cycle 2's 3
Tasks requiring fixes after review 0 0
Batch with most findings none — 0 findings cycle-wide n/a
Auto-fix loops invoked 0 0
Stuck-agent incidents 0 0
Unplanned implementation-time test stabilization loops 4 in batch 13 (AZ-510 module-scoped state ripple) +4 (new pattern)

Blocker Analysis

Blocker Type Count Prevention
Spec-defined cross-workspace BLOCKING gate (AZ-512) 1 Working as intended; the spec design (Cross-Workspace Verification gate) is the prevention. Codify as a reusable task spec template — see Improvement Action #1.
Cycle-2 manual third-party action (key revocation) 2 (carry; not actioned this cycle) Action #1 from cycle 2 retro still valid; user-action backlog grew rather than drained. See Improvement Action #3.
Cycle-2 cross-workspace deploy gate (satellite-provider) 1 (carry; not actioned this cycle) Same as above.
Cycle-3 deploy push deferred (stage / main / admin/ dev) 3 (new) User chose option A (real cutover) but option A in push-scope (ui/ dev only); intentional, but adds to the backlog.

User-action backlog at cycle close (NEW METRIC — see Improvement Action #3)

Category Count Items
Manual third-party console action 2 L-AZ-499-OWM-REVOKE, L-AZ-501-GOOGLE-REVOKE (carry from cycle 2)
Cross-workspace deploy gate 1 L-AZ-498-DEPLOY (carry from cycle 2)
Cross-workspace prerequisite ticket awaiting sibling-team work 1 AZ-513 implementation on admin/ (new this cycle; blocks AZ-512 in _docs/02_tasks/backlog/)
Cycle-3 deploy push pending 3 D-CY3-STAGE, D-CY3-MAIN, D-CY3-ADMIN-PUSH (new this cycle)
Total 7 (cycle 1 close: 0 → cycle 2 close: 3 → cycle 3 close: 7)

This metric is monotonically growing across cycles. The growth is not a process regression — every item is a deliberate conservative-path choice (file prereq ticket vs. invent workaround; defer prod cutover vs. push without satellite-provider gate; etc.) — but the trajectory means the cost of those choices accumulates without an offsetting drain mechanism.

User-decision points (cycle 3 only)

  • AZ-512 BLOCKING gate (Cross-Workspace Verification): user skipped the prompt → autodev defaulted to Option A (file prereq ticket on admin/, pause AZ-512). Spec-aligned, conservative, reversible.
  • Cycle-3 deploy gate (real cutover vs plan-only): user chose A (real cutover) — first time across cycles 1-3 the user chose anything other than plan-only.
  • Cycle-3 push-scope sub-gate: user chose A (ui/ dev only). Stage/main and admin/ dev push deferred.
  • Step 14 verdict (PASS_WITH_WARNINGS): no remediation gate fired (only LOW finding); auto-chained.
  • Step 15 (Performance Test): no separate report produced; static perf check confirmed green at deploy time (290 575 B / 14 % of budget).

Trend Comparison

Trend Cycle 1 Cycle 2 Cycle 3 Direction
Code review pass rate (formally-reviewed batches) 100 % 50 % (1 PASS_WITH_WARNINGS, 1 no-review sub-step) 100 % (2/2 reviewed batches PASS) ⬆ recovered to cycle-1 baseline
Test count (cumulative this cycle delta) +46 +20 +2 declining; cycle 3 was deeper-fix-narrower-surface
Static gate count +2 +2 0 (STC-ARCH-01 strengthened, no new gates) held
Architecture findings open (baseline) 7 (2) 7 (0) 6 (1) ⬆ resumed monotonic decrease
STC-ARCH-01 exemptions 1 1 0 first cycle to reach zero
Wire-contract assertions 36 36 37 (+1) first growth since cycle 1
Pending USER actions at cycle close 0 3 7 ⬆ ⬆ — accumulating
Tasks deferred to backlog at spec gate 0 0 1 (AZ-512) new pattern (working as designed)

The cycle 3 user-action backlog growth is a structural side-effect of running spec-defined BLOCKING gates correctly, not a process regression. AZ-512's gate caught a cross-workspace dependency that would otherwise have shipped a UI form against a 404 endpoint. The cost is one new entry in the backlog; the alternative was a production-broken affordance.

Top 3 Improvement Actions

  1. Codify "Cross-Workspace Verification BLOCKING gate" as a reusable task spec template. AZ-512's spec is the canonical example: pre-implementation gate that requires the implementer to verify a sibling-workspace endpoint exists, with a spec invariant ("Do not invent a workaround that bypasses the missing endpoint") and a fallback-A priority (file prereq ticket on the sibling workspace). Without that gate, batch 15 would have shipped a UI affordance against a 404 endpoint. Future tasks that touch UI ↔ admin / UI ↔ satellite-provider / UI ↔ annotations-service boundaries should always include this gate.

    • Impact: high — directly addresses the recurring cross-workspace coordination cost; prevents a class of "ships visibly broken in production" bugs that the AZ-512 / AdminPage.tsx add+delete side observation showed already exists in pre-AZ-512 code.
    • Effort: low — add _docs/02_tasks/_templates/cross_workspace_dependency.md with the gate scaffold (verify-step + spec invariant + 3-option fallback ladder) and reference from .cursor/skills/new-task/SKILL.md "Task Type Detection" section.
  2. Standardize a "module-scoped state introduction" task template / batch checklist. AZ-510's bootstrapInflight module-scoped promise was the right architectural choice for StrictMode-safe bootstrap dedupe but cost ~4 separate fix loops in test setup during implementation: (a) ProtectedRoute.test.tsx hangs from leaked never-resolving promise → fix via test-only reset hook; (b) STC-ARCH-01 violation when tests/setup.ts deep-imported the helper → fix via barrel re-export; (c) widespread test crashes from default MSW /users/me handler missing permissions field → fix via defensive hasPermission + handler seeding; (d) bulk handler swap in 15 test files (http.get('/api/admin/auth/refresh')http.post) needed because POST production behavior bypassed the existing GET overrides. Each was straightforward in isolation but compounded the batch's wall-clock cost. A pre-implementation checklist would have caught (a)+(b) before code was written.

    • Impact: medium — directly reduces ripple-cost of architecturally-correct module-scoped state introductions; the pattern recurs anywhere React 18 StrictMode dedupe is needed.
    • Effort: low — add _docs/02_tasks/_templates/module_scoped_state_introduction.md (NEW) with the 4-item checklist (reset-hook plan, afterEach audit, default-fixture invariant check, mock ripple plan); cite AZ-510 as canonical example.
  3. Track "user-action backlog at cycle close" as a first-class retrospective metric. Backlog grew 0 → 3 → 7 across cycles 1-3. Each item is a deliberate conservative-path choice (file prereq ticket; defer prod cutover; defer key revocation), but the monotonic accumulation is a process-shape signal. Without a per-cycle measurement and a draining mechanism, the backlog will keep growing and the "cost of conservative defaults" stays invisible. The drain mechanism could be a "Step 0 leftover sweep" in each cycle's first invocation (already partially defined in tracker.mdc Leftovers Mechanism), but today the autodev does not measure whether the sweep actually moved the backlog count down.

    • Impact: medium — surfaces accumulating debt that today is only visible by reading the leftovers folder. Makes user-action items first-class deliverables of the process, not silent drag.
    • Effort: low — extend .cursor/skills/retrospective/SKILL.md Step 1 metric collection with a "user-action backlog" subsection (categories: manual third-party / cross-workspace prereq / cross-workspace deploy / push pending), and add to the retrospective-report template.

Suggested Rule / Skill Updates

File Change Rationale
_docs/02_tasks/_templates/cross_workspace_dependency.md NEW file. Pre-implementation BLOCKING gate (verify the prerequisite exists in <sibling/> source); spec invariant ("Do not invent a workaround that bypasses the missing endpoint"); fallback-A priority (file prereq ticket on sibling, pause until lands); options B/C/D for the user; AZ-512 ↔ AZ-513 as canonical example. §Top 3 Improvement Action #1.
.cursor/skills/new-task/SKILL.md (Task Type Detection) Add "cross-workspace-dependent" trigger phrase set ("touches admin/", "depends on satellite-provider", "needs new endpoint in <sibling>", "calls /api/admin/<new>") that suggests the new template. §Top 3 Improvement Action #1 enablement.
_docs/02_tasks/_templates/module_scoped_state_introduction.md NEW file. 4-item pre-implementation checklist: (a) plan test-only reset hook in same batch; (b) audit afterEach hooks in tests/setup.ts; (c) check default test fixtures still satisfy invariants if helpers consume them; (d) plan ripple swaps in handler mocks (HTTP method / wire shape changes). Cite AZ-510 as canonical example. §Top 3 Improvement Action #2.
.cursor/skills/retrospective/SKILL.md (Step 1 metrics) Add "User-action backlog at cycle close" metric: count of unresolved leftover items, broken down by category (manual third-party / cross-workspace prereq / cross-workspace deploy / push pending). Also add cross-workspace prerequisite tickets count and pre-existing bugs surfaced as side observations. §Top 3 Improvement Action #3.
.cursor/skills/retrospective/templates/retrospective-report.md Add a "User-action backlog at cycle close" subsection under Efficiency with the same category breakdown; include trend across previous cycles. §Top 3 Improvement Action #3.
_docs/LESSONS.md (top) Append the 3 lessons in §LESSONS Append below; trim to ≤ 15 entries. Skill Step 4.

Notes — Step 16 outcome

Step 16 (Deploy) ran in real-cutover mode (option A) for the first time across cycles 1-3. Push scope was ui/ dev only (5 commits, fast-forward 15838c5..09449bd). Stage / main / admin/ dev pushes were deferred at the push-scope sub-gate (user chose option A — ui/ dev only).

  • Devices will not auto-pull cycle-3 changes until dev → stage → main completes (D-CY3-STAGE, D-CY3-MAIN).
  • AZ-513 task spec sits locally on admin/ dev — admin/ team cannot pick it up until D-CY3-ADMIN-PUSH lands.
  • No Dockerfile / .woodpecker/ / nginx / env changes in cycle 3, so no deployment-doc rewrites this cycle (verified via git diff --stat 70fb452^..HEAD on those paths — empty).

These four items add to the user-action backlog; see §Efficiency → User-action backlog table.

LESSONS Append (top 3, single-sentence, tagged)

  1. [process] When a task spec defines a Cross-Workspace Verification BLOCKING gate and the user skips the choice prompt, the autodev MUST default to the most conservative spec-aligned option (Option A: file prerequisite ticket on the sibling workspace, park the task in backlog/) — never invent a workaround that bypasses the missing dependency, never silently ship a UI affordance against a non-existent endpoint, and always preserve the user's ability to override at the next invocation, exactly as AZ-512 → AZ-513 demonstrated.
  2. [architecture] Introducing a module-scoped state guard in production source (e.g., a top-level let bootstrapInflight: Promise | null = null for React 18 StrictMode dedupe) requires the same batch to ship 4 coupled changes — (a) a test-only reset hook re-exported via the public barrel (STC-ARCH-01 compliance), (b) an afterEach reset in tests/setup.ts, (c) a defensive default-fixture invariant check (e.g., MSW handler must seed required nullable fields the helper consumes), (d) a planned ripple swap in handler mocks for any HTTP method or wire-shape change — skipping any one costs a separate test-stabilization loop, as AZ-510's ~4-attempt arc demonstrated.
  3. [process] Track "user-action backlog at cycle close" as a first-class retrospective metric (count of leftover items broken down by manual-third-party / cross-workspace-prerequisite / cross-workspace-deploy / push-pending categories) — backlog grew monotonically 0 → 3 → 7 across cycles 1-3 and that accumulation is a process-shape signal, not noise; surfacing it makes the cost of conservative-path defaults visible per cycle and creates pressure for an explicit drain mechanism (Step 0 sweep that actually closes items, not just notices them).