699 lines
47 KiB
Markdown
699 lines
47 KiB
Markdown
# nigig-traffic — Remediation Execution Plan
|
||
|
||
**Plan date:** 2026-09-12
|
||
**Audit baseline:** `e899a271c69efca0e11ae274b879378d2f26485f` (`main`)
|
||
**Scope:** `crates/apps/nigig-traffic`, its Makepad game dependencies, learning content, persistence, assets, UI, and release evidence
|
||
**Status:** Proposed; no implementation tranche below is complete
|
||
**Release posture:** **Not releasable as a driving-theory assessment. The pinned dependency does not compile, several lessons do not evaluate what they advertise, and current progress/paywall copy is false.**
|
||
|
||
---
|
||
|
||
## 1. Executive verdict
|
||
|
||
`nigig-traffic` has a compact codebase and a useful fixed-step simulation seam, but its educational claims are not supported by the implementation. The app currently rewards reaching a finish circle for most advertised lessons. Roundabout exits/give-way, signs, priority, and much of hazard behavior are encoded in objective payloads but not evaluated. Some hazard scenarios spawn no hazard. Parking ignores required orientation. Collision feedback is inferred from a coarse distance/AABB approximation rather than a confirmed contact. A learner can therefore “pass” behaviors they did not perform.
|
||
|
||
The core coordinate bug is worse than missing rules: lane evaluation compares absolute world `z` with a lane's relative authored lateral offset. Translation and road orientation change the verdict. The first scenario records repeated lane-drift mistakes while the car is idle at its authored start, and a unit test explicitly treats those false mistakes as the expected performance distribution.
|
||
|
||
Lifecycle semantics are also broken. Intro accepts and simulates player input. Complete and Failed runs continue simulating. `Scenario.max_points` is ignored in favor of 100. There is no progress persistence despite settings copy saying scores are saved locally. Mobile/touch has no driving controls. The render loop schedules frames continuously, even after terminal phases. The Kenney asset path is comments and a no-op while runtime code suggests props will load.
|
||
|
||
Before any of that can run, the workspace's pinned Makepad revision is internally inconsistent: `makepad-game-blocks` and render call `camera_boom_limit` with four arguments while the pinned `makepad-game-sim` signature requires a fifth `ignore: u64` argument. The Traffic workflow's clippy wrapper can suppress Cargo failure and then report zero Traffic-owned diagnostics, so the dependency break can evade that gate.
|
||
|
||
Finally, settings reintroduced an `MTB Premium` sales panel and inert Upgrade action after accepted ADR 001 explicitly prohibited fictional paywall copy. This is a product-integrity failure, not a styling preference.
|
||
|
||
**Current grade:** buildability F, simulation correctness D, assessment validity F, UX/accessibility D-, persistence F, performance evidence D+, code quality C-, policy compliance F.
|
||
|
||
---
|
||
|
||
## 2. Evidence and baseline
|
||
|
||
### 2.1 Observed validation
|
||
|
||
| Check | Result at baseline | Interpretation |
|
||
|---|---:|---|
|
||
| `cargo check --locked -p nigig-traffic --all-targets` | **Fails in pinned Makepad dependency** | No Traffic target is currently buildable at the repository pin. |
|
||
| Failure | `controller.rs:279`/renderer call `camera_boom_limit` with 4 args; `queries.rs:241` requires 5 including `ignore: u64` | Repair/pin a coherent upstream revision; never edit Cargo's checkout. |
|
||
| Runtime tests in `tests/ui.rs` | **All 4 ignored** | Real Makepad navigation/render/settings behavior is not an effective gate. |
|
||
| `tests/ui_basic.rs` | 4 headless simulation/label smoke tests | It does not launch the GUI or render a frame. |
|
||
| Scenario catalog | 47 scenarios at the documented baseline | Count does not establish lesson validity. |
|
||
| Performance baseline | Debug, idle input, partial timing; no current compiling release build | Not a release budget or GPU/rendering measurement. |
|
||
|
||
### 2.2 Primary evidence locations
|
||
|
||
- `src/traffic/scenario.rs`: recursively self-calling `Scenario::object_type`, advertised objective payloads, static catalog and product descriptions.
|
||
- `src/traffic/road.rs`: coordinate conversion, oriented visual boxes vs axis-aligned physics bounds, incomplete hazard spawns and metadata.
|
||
- `src/traffic/objective.rs`: absolute-world lane bug, finish-circle-only rules, ignored payloads, approximate collision/parking/U-turn checks.
|
||
- `src/traffic/world.rs`: phase/input simulation, ignored `Scenario.max_points`, scoring and false-idle test.
|
||
- `src/ui/game_view.rs`: keyboard-only input, continuous `NextFrame`, partial timing, no-op prop seam, build-tree resource path.
|
||
- `src/game_frame/pages/settings.rs`: fictional Premium panel/action and false persistence claim.
|
||
- `.forgejo/workflows/traffic.yml`, `tests/{ui,ui_basic,perf}.rs`, `docs/{ADR,PERF*}`: suppressed dependency error, ignored runtime tests, idle benchmark limitations, and policy contradictions.
|
||
|
||
---
|
||
|
||
## 3. Non-negotiable product invariants
|
||
|
||
1. **Coherent pinned dependencies.** A clean checkout builds without modifying registry/git checkouts. Cargo/clippy failure always fails CI, including dependency failures.
|
||
2. **One coordinate contract.** Authored, course-local, and world coordinates are distinct types. Every rule uses course-local geometry or transformed world primitives consistently.
|
||
3. **Transform invariance.** Translating/rotating an otherwise identical course cannot change educational verdicts.
|
||
4. **No motion outside Active.** Player drive input is zeroed during Intro, Paused, Complete, and Failed. Terminal attempts are immutable.
|
||
5. **Rules assess claims.** A scenario is marked assessable only when every claimed required behavior has world observability, stateful rule logic, success/violation tests, and curriculum approval.
|
||
6. **No finish-circle laundering.** Reaching the finish cannot imply sign compliance, yielding, correct roundabout exit, hazard response, or correct parking orientation without evidence.
|
||
7. **Real contact is named contact.** Collision uses physics contact/sweep events or a precisely documented geometric intersection. Proximity warnings are not labelled collisions.
|
||
8. **Scenario payloads are enforced or absent.** Reserved/ignored fields do not appear in assessable scenario descriptions or scoring.
|
||
9. **Scenario-defined score.** `max_points`, criteria weights, penalties, threshold, and terminal result use one validated scoring policy without overflow.
|
||
10. **Deterministic attempts.** Fixed scenario/content version + seeded initial state + tick-indexed normalized input produces the same rule trace/result on a supported target within declared numeric guarantees.
|
||
11. **Persistent claims are true.** Scores/progress are only said to be saved after versioned, atomic, recovery-tested persistence exists.
|
||
12. **No fictional commerce.** ADR 001 remains binding until intentionally superseded by a real entitlement architecture and product decision.
|
||
13. **Supported devices can drive.** Mobile/touch is first-class; keyboard-only cannot be a mobile release.
|
||
14. **Assets are explicit.** Required signs/hazards/models are bundled, licensed, bounded, and validated. Missing visual assets disable dependent lessons rather than silently substituting cubes.
|
||
15. **Performance evidence covers the shipped path.** Release profile, active input, actual rendering/GPU, target hardware, frame pacing, input latency, and idle/terminal lifecycle are measured.
|
||
|
||
---
|
||
|
||
## 4. Severity-ranked findings
|
||
|
||
### P0 — release blockers
|
||
|
||
| ID | Finding | Failure mode |
|
||
|---|---|---|
|
||
| TRAFFIC-P0-01 | Pinned Makepad game crates have incompatible `camera_boom_limit` APIs. | Clean build fails before Traffic code compiles. |
|
||
| TRAFFIC-P0-02 | Clippy command ignores Cargo exit and filters only Traffic package diagnostics. | Dependency compiler failure can be reported as zero owned diagnostics. |
|
||
| TRAFFIC-P0-03 | `Scenario::object_type()` calls itself unconditionally. | Any call stack-overflows instead of returning objective/category type. |
|
||
| TRAFFIC-P0-04 | Lane rule compares `player_pos.z` to relative `lane_y`, ignoring road origin and orientation. | False mistakes/correct passes vary with translation/rotation. |
|
||
| TRAFFIC-P0-05 | Existing idle histogram test intentionally expects repeated false lane mistakes. | Test suite protects the bug and invalidates the benchmark workload. |
|
||
| TRAFFIC-P0-06 | Roundabout/sign/priority/hazard payloads such as `enter`, `exit_at`, `give_way`, `signs`, `yield_`, `stop`, and hazard `brake` are ignored; completion feedback asserts behavior from finish position. | Learners pass unperformed safety/rule behaviors. |
|
||
| TRAFFIC-P0-07 | Hazard scenarios `haz_child_run`, `haz_branch`, and `haz_rain` spawn no hazard, as an existing test expects. | Advertised hazard practice contains no corresponding hazard event/model. |
|
||
| TRAFFIC-P0-08 | Intro and terminal phases still run player/physics simulation. | Countdown start advantage and post-result movement mutate attempt/world state. |
|
||
| TRAFFIC-P0-09 | `Scenario.max_points` is overwritten with 100. | Catalog contract and displayed results diverge. |
|
||
| TRAFFIC-P0-10 | Settings' Premium panel and no-op Upgrade action directly contradict accepted ADR 001. | The app advertises a nonexistent subscription and locked content. |
|
||
| TRAFFIC-P0-11 | Settings says per-learner progress/scores are saved, but no Traffic persistence exists. | User is promised durable learning history that is discarded. |
|
||
| TRAFFIC-P0-12 | Accepted ADR 002 honestly locks finish-circle/proximity behavior, but that deliberately limited evaluator cannot support the catalog's assessment-like lesson claims. | Keep it only for explicitly labelled practice, or supersede it criterion-by-criterion with geometry, observation, rules, tests, and reviewed copy. |
|
||
|
||
### P1 — major correctness and learning-validity defects
|
||
|
||
| ID | Finding | Consequence |
|
||
|---|---|---|
|
||
| TRAFFIC-P1-01 | Parking passes on near-stop AABB overlap and ignores `BayOrientation`, vehicle heading, full containment, slope, gear, and handbrake claims. | Incorrect parking passes. |
|
||
| TRAFFIC-P1-02 | U-turn checks a world forward-x threshold, not heading relative to course/start or turn zone. | Rotated courses and three-point/legal-zone lessons are wrong. |
|
||
| TRAFFIC-P1-03 | Signs are generic geometry and objective checks no recognition, stop line, dwell, approach speed, or downstream action. | Sign lessons assess only finish reach. |
|
||
| TRAFFIC-P1-04 | Priority/yield checks only coarse overlap/proximity with at most one crossing car. | Passing does not prove a stop, yield, accepted gap, or right-of-way behavior. |
|
||
| TRAFFIC-P1-05 | Hazard collision computes centre-distance with one half-extent scalar and labels negative clearance a collision. | False positives/negatives for rotated/unequal bodies and misleading feedback. |
|
||
| TRAFFIC-P1-06 | Speed creates repeated throttled mistakes but does not define grace distance/time, zone entry, duration, or scoring trace. | One sampling artifact can determine assessment inconsistently. |
|
||
| TRAFFIC-P1-07 | Scenario descriptions require indicators/mirror/blind-spot/gear behavior for which no input or observation exists. | Unobservable criteria are presented as assessed skills. |
|
||
| TRAFFIC-P1-08 | Keyboard is the only drive input; focus/page loss can leave held state and mobile cannot drive. | Major supported-device and safety/accessibility failure. |
|
||
| TRAFFIC-P1-09 | Frame scheduling continues indefinitely after completion/failure and while view lifecycle does not need simulation. | Battery/CPU/GPU waste and misleading idle metrics. |
|
||
| TRAFFIC-P1-10 | `ensure_props` only comments the intended loader and sets `props_loaded`; it never parses/uploads assets. | Asset-present path still does nothing while logs/docs imply upgrade behavior. |
|
||
| TRAFFIC-P1-11 | Runtime UI tests are ignored due harness failure; headless smoke is labelled UI coverage. | Navigation, render, touch, lifecycle, and persistence regressions are untested. |
|
||
| TRAFFIC-P1-12 | Scenario data and learning copy have no jurisdiction/content version or qualified curriculum sign-off. | Rules can be legally/pedagogically wrong or become stale. |
|
||
| TRAFFIC-P1-13 | The workflow's `supply-chain` job only checks lockfile presence and whitespace; tool installer/action integrity, advisories, source policy, and licenses are not gated. | A pinned but vulnerable/unlicensed dependency or compromised mutable CI bootstrap can enter builds without Traffic's named gate detecting it. |
|
||
|
||
### P2 — performance, design, and maintainability debt
|
||
|
||
- `Objective` mixes lesson definition with weak implementation-specific flags and has no explicit ordered criteria/state machine.
|
||
- Rule evaluation returns one verdict string, not a trace of observations, satisfied criteria, violations, and evidence.
|
||
- Scenario geometry uses yawed boxes while collision metadata often remains axis-aligned and approximate.
|
||
- Render/game view owns input, timing, simulation, camera, assets, rendering, HUD, and instrumentation.
|
||
- Performance docs quote averages as scenario medians and infer rendering health from CPU submission/tick timing.
|
||
- Catalog count and test floors reward quantity rather than valid scenario coverage.
|
||
|
||
### Security and privacy posture
|
||
|
||
Traffic is currently an offline, non-authenticated app with no legitimate payment or network boundary. Do not invent web-style encryption/authentication work. Its real security surfaces are the Rust/CI dependency supply chain, parsing of packaged or future imported scenario/asset/profile data, path and resource exhaustion, and local learner privacy. Source-level `unsafe` grep does not constrain unsafe code in dependencies. Progress should be anonymous by default, bounded, and protected by platform storage; do not collect names, telemetry, or instructor data without a separately reviewed purpose, retention policy, consent flow, and threat model.
|
||
|
||
---
|
||
|
||
## 5. Target architecture
|
||
|
||
```text
|
||
ScenarioPackage (id + content_version + jurisdiction + reviewed claims)
|
||
├─ CourseSpec -> validated CourseFrame + geometry/zones/routes/assets
|
||
├─ ObjectiveSpec -> ordered criteria + violations + scoring policy
|
||
└─ Capability requirements -> input/physics/asset/rule features
|
||
│ validate before catalog publication
|
||
▼
|
||
AttemptController
|
||
├─ phase: Intro | Active | Paused | Complete | Failed
|
||
├─ FixedStepSimulation (seeded, bounded catch-up)
|
||
├─ InputRouter -> normalized tick-indexed DriveIntent
|
||
├─ ObservationBuilder
|
||
│ ├─ course position/heading/lane occupancy
|
||
│ ├─ speed/acceleration/brake/handbrake/gear/indicator
|
||
│ ├─ zone entry/exit/stop dwell/path history
|
||
│ ├─ physics contacts/clearance
|
||
│ └─ traffic state/gap/priority
|
||
├─ RuleEngine -> RuleTrace / criterion state / violation
|
||
└─ ScoreEngine -> immutable AttemptResult
|
||
│
|
||
├─ LearnerRepository (versioned local progress)
|
||
└─ RenderSnapshot (presentation only)
|
||
```
|
||
|
||
### Coordinate types
|
||
|
||
- `AuthoredPoint2`: scenario file coordinates only.
|
||
- `CoursePoint { along, lateral }`: relative to a validated `CourseFrame { origin, tangent, normal }`.
|
||
- `WorldPoint3`: simulation XZ plane.
|
||
- `Heading`: normalized angular type; `relative_heading(course_frame)` for rules.
|
||
- No public rule API accepts an unlabelled `[f64; 2]`, raw `Vec3f`, or “x component means forward.”
|
||
|
||
### Assessment state
|
||
|
||
A rule yields structured evidence such as `EnteredZone`, `StoppedAtLine { ticks }`, `YieldedTo { vehicle, min_gap }`, `SelectedExit`, `IndicatorActive`, `Contact`, `ContainedInBay`, and `HeadingWithin`. Feedback text is rendered from evidence; text itself is not the rule state.
|
||
|
||
---
|
||
|
||
## 6. Initial resource and performance budgets
|
||
|
||
Budgets are release targets to measure on declared devices after build correctness. They are not inferred from current debug/idle logs.
|
||
|
||
| Resource | Initial limit/target | Enforcement/evidence |
|
||
|---|---:|---|
|
||
| Simulation rate | 60 fixed ticks/s | Tick-indexed input/replay. |
|
||
| Catch-up per rendered frame | max 5 ticks | Record/drop excess wall-time; no 15-tick UI stall. |
|
||
| Entities per scenario | 256 | Scenario validator before load. |
|
||
| Simultaneous movers | 32 | Scenario validator; revisit spatial index at threshold. |
|
||
| Static course primitives | 2,048 | Scenario validator. |
|
||
| Objective criteria | 64 | Objective validator. |
|
||
| Rule/observation events per attempt | 4,096 retained plus bounded summary | Ring/journal cap. |
|
||
| Attempt duration | 30 minutes | Pause/timeout policy. |
|
||
| Simulation CPU | p99 <= 2 ms/tick on max-content scenario, target device | Release scripted workload. |
|
||
| Main-thread non-render event | p95 <= 8 ms | Instrumented runtime. |
|
||
| Frame time | p95 <= 16.7 ms desktop 60 Hz; <=33.3 ms supported mobile 30 Hz | CPU + GPU timestamps. |
|
||
| Input-to-visible response | p95 <= 50 ms | Device/runtime measurement. |
|
||
| Scenario load | p95 <= 100 ms after shared assets warm | Runtime trace. |
|
||
| Draw submissions | <= 200 visible per reference scenario | Render stats, not entity count proxy. |
|
||
| Visible triangles | <= 500,000 | Asset/scenario manifest validation. |
|
||
| Texture residency | <= 256 MiB desktop / 128 MiB mobile | Renderer metrics/eviction. |
|
||
| Curated packaged assets | <= 150 MiB compressed | Build artifact gate with license manifest. |
|
||
| Learner profile | <= 8 MiB; 10,000 attempts before compaction/export | Repository. |
|
||
| Idle/hidden/terminal simulation | 0 ticks and no continuous redraw | Lifecycle test. |
|
||
|
||
An over-budget scenario is excluded from the production catalog until deliberately reviewed; budgets are not weakened to make a count pass.
|
||
|
||
---
|
||
|
||
## 7. Dependency-ordered implementation tranches
|
||
|
||
### TRAFFIC-00 — Remove false product claims immediately
|
||
|
||
**Priority:** P0
|
||
**Effort:** 1–2 person-days
|
||
**Depends on:** none; can land before dependency repair as a source-tested policy patch
|
||
|
||
**Change**
|
||
|
||
- Delete `section_paywall`, `PaywallAction`, Upgrade dispatch, and all Premium/FREE/locked sales copy in accordance with accepted ADR 001.
|
||
- Remove “progress and scores are saved locally per learner” until persistence is real.
|
||
- Add one capability/assessment-status matrix. Hide or label every unvalidated scenario as `Practice preview — finish marker only`; do not render behavior-confirming completion text.
|
||
- Remove counts/copy that conflate scenario existence with free/validated content.
|
||
|
||
**Tests / exit**
|
||
|
||
- Source/UI snapshot gate rejects `MTB Premium`, Upgrade, subscription/unlock claims, and local-save claims.
|
||
- Default catalog/action dispatch remains available equally regardless of reserved `premium` field.
|
||
- Unsupported scenarios cannot show “priority respected,” “sign obeyed,” or equivalent assessment success.
|
||
- Update ignored UI expectations rather than keeping tests that require policy violations.
|
||
|
||
**Rollback:** false sales/persistence/assessment claims stay removed.
|
||
|
||
### TRAFFIC-01 — Pin a coherent Makepad game API and make CI fail honestly
|
||
|
||
**Priority:** P0
|
||
**Effort:** 3–6 person-days depending on upstream fix
|
||
**Depends on:** none
|
||
|
||
**Change**
|
||
|
||
- Repair the four-vs-five argument `camera_boom_limit` mismatch in the upstream Makepad fork and pin the workspace to that reviewed coherent commit, or select an existing coherent commit after full compatibility review.
|
||
- Do not patch files under Cargo's checkout and do not add a local unreviewed copy solely for Traffic.
|
||
- Update all workspace references/lockfile atomically and document relevant API change.
|
||
- Rewrite clippy step to preserve and fail on Cargo's exit status before/alongside diagnostic ratcheting. Dependency errors are hard failures even when no Traffic package diagnostic exists.
|
||
- Add a build matrix for all packages using changed Makepad game crates.
|
||
|
||
**Tests / exit**
|
||
|
||
- Fresh cache/clean checkout passes `cargo metadata --locked` and Traffic all-target check.
|
||
- A fixture dependency compiler error makes both check and clippy jobs fail.
|
||
- `makepad-game-sim`, `makepad-game-blocks`, and `makepad-game-render` API/unit tests pass at the pin.
|
||
- Workspace consumer checks show no hidden regression; exact affected package list comes from `cargo metadata` reverse dependencies.
|
||
|
||
**Rollback:** revert to the prior workspace pin only if it is coherent for all released apps; otherwise block Traffic. Never mutate checkout or suppress failure.
|
||
|
||
### TRAFFIC-02 — Catalog schema and integrity validation
|
||
|
||
**Priority:** P0
|
||
**Effort:** 4–6 person-days
|
||
**Depends on:** TRAFFIC-01
|
||
|
||
**Change**
|
||
|
||
- Fix `Scenario::object_type` to delegate to the objective/category and add a regression test that calls it for every scenario.
|
||
- Introduce `ScenarioId`, `ContentVersion`, jurisdiction/curriculum metadata, typed positions/headings, validated positive `max_points`, seed, and required capabilities.
|
||
- Validate unique IDs, finite coordinates/headings/limits, nonzero course length, finish reachability, valid bay/exit/sign references, supported objective fields, asset availability, and budgets before catalog publication.
|
||
- Replace closure-heavy static construction with data definitions/builders that return `Result` and produce a validation report.
|
||
- Treat scenario count as informational; require per-scenario validity/coverage instead of a floor.
|
||
|
||
**Tests / exit**
|
||
|
||
- All catalog entries validate; malformed duplicate/non-finite/zero-length/missing-reference/unsupported-capability fixtures fail precisely.
|
||
- Every scenario's category/objective type agrees without recursion.
|
||
- Catalog order changes do not change persistent identity.
|
||
- A scenario cannot be marked Assessable without a named success and violation replay.
|
||
|
||
**Migration:** reserve current string IDs and set content version 1 after review; persistence maps by ID/version, never list index.
|
||
|
||
**Rollback:** invalid entries are excluded; do not bypass catalog validation.
|
||
|
||
### TRAFFIC-03 — One course/world coordinate model
|
||
|
||
**Priority:** P0
|
||
**Effort:** 6–9 person-days
|
||
**Depends on:** TRAFFIC-02
|
||
|
||
**Change**
|
||
|
||
- Implement typed `CourseFrame` from origin/start and normalized tangent; derive lateral normal and explicit world transform.
|
||
- Centralize authored ↔ course ↔ world point/vector/heading conversions with inverse functions.
|
||
- Store lane centre/width, bay oriented rectangle, stop lines, zones, routes, exits, signs, and finish in course geometry or explicit world primitives—not mixed relative scalar/AABB fields.
|
||
- Remove `lane_y` comparison and raw world-forward-x rule assumptions.
|
||
- Distinguish visual mesh bounds from rule/physics geometry.
|
||
|
||
**Tests / exit**
|
||
|
||
- Round-trip coordinate/heading properties across translations, all quadrants, near-axis angles, and valid magnitudes.
|
||
- Metamorphic tests translate/rotate complete scenarios and prove identical course observations/verdict traces.
|
||
- Idle car starts inside its intended lane with zero drift mistakes in every lane scenario.
|
||
- Delete/replace `verdict_histogram_proves_continue_dominates`; a new test rejects any idle false violation.
|
||
|
||
**Rollback:** disable affected scenarios. Never restore absolute-world vs relative-lane comparisons.
|
||
|
||
### TRAFFIC-04 — Correct phase/input/fixed-step lifecycle
|
||
|
||
**Priority:** P0
|
||
**Effort:** 4–6 person-days
|
||
**Depends on:** TRAFFIC-01, TRAFFIC-03
|
||
|
||
**Change**
|
||
|
||
- Replace ad hoc phase bookkeeping with explicit `AttemptController` transitions and timestamps/ticks.
|
||
- Normalize drive input through one gate; force neutral player input in Intro/Paused/Complete/Failed.
|
||
- Decide whether non-player traffic animates during Intro; test it separately. Terminal phases freeze assessment simulation and result.
|
||
- Cap wall-clock catch-up at five ticks/frame and report discontinuity; reset accumulator safely on hide/resume/pause.
|
||
- Clear held input on focus loss, page switch, app suspend, restart, scenario switch, and terminal transition.
|
||
- Make no-scenario state explicit instead of transitioning to Driving after 60 ticks.
|
||
|
||
**Tests / exit**
|
||
|
||
- Holding throttle during Intro produces no displacement/velocity/head start.
|
||
- Complete/Failed result/world state is stable over 10,000 frames/ticks.
|
||
- Pause/resume/focus loss and 250 ms stall cannot cause stuck input or unbounded catch-up.
|
||
- Transition table rejects illegal/repeated terminal transitions.
|
||
- Same tick-indexed input replay produces same phase/world/rule result twice.
|
||
|
||
**Rollback:** freeze simulation outside Active even if countdown animation is temporarily lost.
|
||
|
||
### TRAFFIC-05 — Observation and real-contact layer
|
||
|
||
**Priority:** P0/P1
|
||
**Effort:** 7–11 person-days
|
||
**Depends on:** TRAFFIC-03, TRAFFIC-04
|
||
|
||
**Change**
|
||
|
||
- Build immutable per-tick `Observation`: course pose/relative heading, speed/accel, controls, lane occupancy/crossings, zone entries/exits/dwell, path, vehicle footprint, traffic states/gaps, and physics contacts.
|
||
- Expose actual contact/sweep events from Makepad simulation with involved entity IDs and contact class.
|
||
- Use oriented vehicle/bay geometry for containment and clearance. If only proximity is available, call it proximity and never terminal collision without policy.
|
||
- Bound event history and make state transitions edge-triggered to prevent repeated-frame penalties.
|
||
|
||
**Tests / exit**
|
||
|
||
- Contact vs near-miss, rotated unequal bodies, grazing edge, static prop, traffic car, road boundary, and tunnelling/sweep fixtures.
|
||
- Observation is translation/rotation invariant in course coordinates.
|
||
- Zone/lane/contact events fire once per transition and retain deterministic tick IDs.
|
||
- Rule layer has no direct raw `GameWorld` coordinate guessing after this tranche.
|
||
|
||
**Rollback:** scenarios requiring unavailable contact/observation stay non-assessable.
|
||
|
||
### TRAFFIC-06 — Stateful objective/rule engine
|
||
|
||
**Priority:** P0 educational validity
|
||
**Effort:** 10–16 person-days
|
||
**Depends on:** TRAFFIC-05
|
||
|
||
**Change**
|
||
|
||
- Replace one-tick `Verdict` matching with validated ordered criteria, violation rules, state, and structured evidence trace.
|
||
- Supersede ADR 002 one objective variant at a time only when geometry/query plumbing and success/violation tests land together; retain its honest finish-only scope for clearly labelled practice until then.
|
||
- Implement only observable claims, in this order:
|
||
1. lane occupancy/change sequence and road departure;
|
||
2. speed-zone grace/duration/overspeed;
|
||
3. parking target, full containment, relative heading, stop dwell, handbrake/gear if claimed;
|
||
4. U-turn legal zone, relative reversal, path/kerb limits, three-point sequence if claimed;
|
||
5. sign approach/recognition response, stop line/dwell and relevant downstream action;
|
||
6. priority/yield with conflict zone, right-of-way, accepted gap, stop/yield behavior;
|
||
7. roundabout approach/give-way/entry/circulation/lane/indicator/selected exit;
|
||
8. hazard detection zone, speed/brake/clearance/contact response.
|
||
- Finish is one criterion at most, never proof of preceding criteria.
|
||
- Generate feedback from unsatisfied/satisfied evidence rather than unconditional success strings.
|
||
|
||
**Tests / exit**
|
||
|
||
- For each rule: one minimal valid replay, every named violation replay, boundary/grace cases, and transform-invariance test.
|
||
- Wrong roundabout exit, no yield, rolling stop, no indicator, wrong parking angle, wrong bay, forbidden turn, absent hazard response, and finish-only shortcuts cannot pass.
|
||
- Reordered/duplicate observation delivery cannot double-score.
|
||
- Rule trace explains result with criterion IDs/ticks/evidence.
|
||
|
||
**Rollback:** individual rule/capability is disabled and dependent scenarios return to clearly labelled practice mode.
|
||
|
||
### TRAFFIC-07 — Scenario scoring and immutable results
|
||
|
||
**Priority:** P0
|
||
**Effort:** 4–6 person-days
|
||
**Depends on:** TRAFFIC-02, TRAFFIC-06
|
||
|
||
**Change**
|
||
|
||
- Construct `ScorePolicy` from validated scenario `max_points`, weighted criteria, penalties, terminal violations, and pass threshold.
|
||
- Use checked integer/fixed-point arithmetic; define rounding and bounds.
|
||
- Award once per criterion transition; repeated telemetry cannot farm or multiply penalties.
|
||
- Freeze `AttemptResult` at terminal transition with scenario ID/content version, ticks/duration, criteria, violations, score/max/percent/pass, and replay digest.
|
||
- Separate Failed (terminal safety violation) from CompletedButNotPassed where needed.
|
||
|
||
**Tests / exit**
|
||
|
||
- Non-100 `max_points` fixture proves HUD/result/use all scenario value.
|
||
- Weight sum, overflow, negative/zero max, duplicate criteria, boundary threshold, penalty floor, repeated events, and terminal immutability.
|
||
- Result recomputation from rule trace equals displayed/persisted score exactly.
|
||
- HUD never renders impossible `score/max` or a pass unsupported by criteria.
|
||
|
||
**Migration:** no old in-memory scores are durable; content-versioned results start when persistence lands.
|
||
|
||
**Rollback:** show criterion completion without numeric score; never hardcode 100.
|
||
|
||
### TRAFFIC-08 — Curriculum and complete scenario-content review
|
||
|
||
**Priority:** P0 before assessment release
|
||
**Effort:** 10–20 person-days plus expert review
|
||
**Depends on:** TRAFFIC-02, TRAFFIC-06, TRAFFIC-07
|
||
|
||
**Change**
|
||
|
||
- Choose/document target jurisdiction, learner level, curriculum source/version, and date.
|
||
- Build a 47-row matrix: learning claim, required input, geometry/assets, actors/hazards, observations, rule criteria, success replay, violation replays, scoring, accessibility, and reviewer.
|
||
- Add real hazards for child/branch/rain or remove/rename those scenarios. Model rain/braking-distance effects if claimed.
|
||
- Add correct signs/road markings/routes/traffic for sign, junction, and roundabout lessons.
|
||
- Remove mirror/blind-spot, signal, gear, slope, weather, or kerb claims until corresponding controls/observations exist.
|
||
- Have a qualified driving instructor/traffic-law expert approve content and feedback; version approved packages.
|
||
|
||
**Tests / exit**
|
||
|
||
- Every production Assessable scenario has complete matrix, assets, success/violation replays, and signed review.
|
||
- Automated validator detects ignored objective fields/capabilities and missing actors.
|
||
- Scenario descriptions, lesson pages, HUD feedback, and actual criteria derive from one content source.
|
||
- Law/curriculum version and known limitations are visible.
|
||
|
||
**Rollback:** remove the scenario from assessable catalog; practice content remains plainly non-assessment.
|
||
|
||
### TRAFFIC-09 — Unified keyboard, touch, and controller input
|
||
|
||
**Priority:** P1
|
||
**Effort:** 7–11 person-days
|
||
**Depends on:** TRAFFIC-04; add criteria controls before TRAFFIC-08 sign-off
|
||
|
||
**Change**
|
||
|
||
- Add `InputRouter` producing normalized `DriveIntent` from keyboard, touch, and supported controller.
|
||
- Provide reachable mobile steering/throttle/brake/handbrake and required indicator/gear controls; support left/right-handed layout and safe zones.
|
||
- Define brake-to-reverse behavior explicitly and avoid accidental reverse on touch.
|
||
- Clear/cancel all sources on focus/page/suspend/terminal lifecycle.
|
||
- Add keyboard remapping where feasible, accessibility labels, non-color feedback, scalable controls, and optional haptics.
|
||
|
||
**Tests / exit**
|
||
|
||
- Equivalent scripted input across keyboard/touch/controller produces equivalent normalized tick stream.
|
||
- Multi-touch steering+throttle+indicator, finger cancellation, viewport rotation, notch/safe area, focus loss, and stuck-control tests.
|
||
- Real Android/iOS or supported mobile-device run completes at least one validated scenario without keyboard.
|
||
- Input-to-visible latency meets §6.
|
||
|
||
**Rollback:** unsupported platform is excluded from release; do not show an undriveable game.
|
||
|
||
### TRAFFIC-10 — Event-driven frame lifecycle and rendering correctness
|
||
|
||
**Priority:** P1
|
||
**Effort:** 5–8 person-days
|
||
**Depends on:** TRAFFIC-04, TRAFFIC-09
|
||
|
||
**Change**
|
||
|
||
- Schedule continuous frames only while visible and Active or during a bounded camera/UI animation.
|
||
- Stop simulation/redraw in hidden/paused/terminal states; schedule one redraw on state/setting/result changes.
|
||
- Reset wall-clock accumulator on lifecycle changes.
|
||
- Separate simulation timing, render preparation, draw submission, GPU duration, frame presentation, and HUD shaping metrics.
|
||
- Ensure render mode changes affect presentation only, not assessment coordinates/rules.
|
||
|
||
**Tests / exit**
|
||
|
||
- Hidden/paused/Complete/Failed view produces zero ticks and no continuous `NextFrame` requests over an observation window.
|
||
- Resume has no catch-up burst.
|
||
- All modes show the same scenario/result and pass transform/render consistency snapshots.
|
||
- Runtime metrics prove CPU/GPU frame budgets under active representative play.
|
||
|
||
**Rollback:** cap to lower frame rate or disable expensive mode; lifecycle stop behavior remains.
|
||
|
||
### TRAFFIC-11 — Versioned atomic learner progress
|
||
|
||
**Priority:** P1
|
||
**Effort:** 6–9 person-days
|
||
**Depends on:** TRAFFIC-07, TRAFFIC-08
|
||
|
||
**Change**
|
||
|
||
- Define local `LearnerProfile` and `AttemptRecord` schema with opaque learner ID, scenario ID/content version, best/latest result, attempts, timestamps, settings, and migration version.
|
||
- Persist only immutable terminal results through an injected repository using unique temp, flush/sync, atomic replace, bounded input, and recovery states.
|
||
- Distinguish absent, valid empty, corrupt, unsupported future, permission, and I/O failure. No false success/reset.
|
||
- Add export/reset/delete profile and privacy copy; do not imply instructor sharing or accounts unless implemented.
|
||
- Decide result invalidation/migration when scenario rule/content version changes; never compare incomparable scores silently.
|
||
|
||
**Tests / exit**
|
||
|
||
- Complete/pass/fail/retry/best-score semantics, non-100 max, content version change, 10k attempt compaction, A/B learner isolation, restart, and clock changes.
|
||
- Fault injection at serialize/write/flush/sync/rename preserves previous profile and surfaces failure.
|
||
- Corrupt/future data enters recovery/read-only state, not empty defaults.
|
||
- Only after these pass may settings say scores are saved locally.
|
||
|
||
**Migration:** current app has no legitimate Traffic history; do not infer it from unrelated `nigig-core` state.
|
||
|
||
**Rollback:** retain in-memory results and remove persistence claim; preserve unreadable profile bytes.
|
||
|
||
### TRAFFIC-12 — Curated licensed asset pipeline
|
||
|
||
**Priority:** P1
|
||
**Effort:** 7–12 person-days
|
||
**Depends on:** TRAFFIC-02, TRAFFIC-08
|
||
|
||
**Change**
|
||
|
||
- Delete the no-op “one implementation away” seam and runtime `CARGO_MANIFEST_DIR` lookup.
|
||
- Curate only required road signs, vehicles, people/hazards, markings, and environment models; check in or reproducibly package them according to license.
|
||
- Add manifest with logical ID, content hash, license/attribution, source, byte/triangle/texture bounds, scale/up axis, material set, and collider/rule geometry reference.
|
||
- Load through Makepad's packaged resource system with bounded GLB/image parsing and deterministic fallback.
|
||
- Keep rule geometry independent and reviewed. Missing required visual asset disables dependent scenario; decorative fallback cannot alter assessment.
|
||
|
||
**Tests / exit**
|
||
|
||
- Clean packaged desktop/mobile build resolves every required asset without source tree/network.
|
||
- Corrupt/oversized/missing/hash-mismatch/unsupported GLB fails clearly within budgets.
|
||
- License/attribution artifact covers every asset.
|
||
- Visual sign/hazard identity matches scenario metadata and curriculum screenshots.
|
||
- Render residency/submission/triangle budgets pass.
|
||
|
||
**Rollback:** use explicit reviewed primitive assets for supported practice modes or disable scenario; no phantom auto-upgrade claim.
|
||
|
||
### TRAFFIC-13 — Supply-chain, parser, and learner-privacy hardening
|
||
|
||
**Priority:** P1 security/release integrity
|
||
**Effort:** 5–8 person-days
|
||
**Depends on:** TRAFFIC-01; integrate with TRAFFIC-02, TRAFFIC-11, TRAFFIC-12
|
||
|
||
**Change**
|
||
|
||
- Write a scoped threat model for the offline app: dependency/toolchain compromise, malicious/corrupt scenario/profile/asset input, path traversal, decompression/resource exhaustion, local data disclosure, and log leakage. Explicitly record that network/payment/auth are absent.
|
||
- Pin third-party CI actions to reviewed immutable commit SHAs. Provision the declared Rust toolchain from a controlled runner image or verify downloaded installers against an independently pinned digest/signature before execution.
|
||
- Add lockfile-scoped advisory, license, duplicate/ban, yanked, and allowed-source policy with reviewed, owned, expiring exceptions. Pin git dependencies by full commit and audit the coherent Makepad fork change.
|
||
- Generate an SBOM/license/source manifest for release dependencies and packaged assets; archive it with build provenance and content hashes.
|
||
- Put byte/count/depth/string/path limits before allocation/parse for scenario, profile, replay, and asset inputs. Reject absolute/parent-traversal asset IDs and unsupported file types. Fuzz the parsers/converters that accept bytes or structured data.
|
||
- Use anonymous local learner IDs by default, restrictive platform file permissions, bounded logs with no profile contents/home paths, and explicit export/delete controls. Do not add telemetry, names, cloud sync, instructor sharing, or home-grown at-rest encryption in this tranche.
|
||
|
||
**Tests / exit**
|
||
|
||
- CI fixture with an unapproved git source, advisory, yanked/unlicensed dependency, mutable action reference, or unverified installer fails the appropriate gate; every exception has owner/reason/expiry.
|
||
- Traversal, oversized length/count/depth, malformed UTF-8/serialization, decompression-bomb, corrupt GLB/image, and fuzz corpus cases fail within memory/time budgets without panic.
|
||
- Release artifact includes SBOM, licenses/attributions, dependency/source hashes, scenario content hashes, and build commit.
|
||
- Profile/export/log inspection contains no undeclared personal data or absolute developer path; delete/reset behavior is verified.
|
||
|
||
**Rollback:** disable imports/assets/export/persistence surface that cannot meet bounds; keep the offline minimal-data model rather than adding unverifiable security claims.
|
||
|
||
### TRAFFIC-14 — Real runtime and end-to-end learning tests
|
||
|
||
**Priority:** P0 release gate
|
||
**Effort:** 7–12 person-days
|
||
**Depends on:** TRAFFIC-01 through enabled UX/content/security tranches
|
||
|
||
**Change**
|
||
|
||
- Repair Makepad test harness so Traffic binary reaches `AppStarted` in CI; remove ignores.
|
||
- Add runtime journeys for navigation, scenario selection, every render mode, keyboard/touch, phase gating, result, restart/next/previous, persistence/restart, settings, and asset failure.
|
||
- Drive validated scenario replays through production UI/input/simulation/rules, not copied headless logic.
|
||
- Capture screenshot/widget/log artifacts on failure without substituting a fake success path.
|
||
|
||
**Tests / exit**
|
||
|
||
- All runtime tests execute assertions; harness exit is a failed job.
|
||
- `ui_basic` remains a headless smoke test and is labelled/counts as such, not GUI coverage.
|
||
- At least one success and each critical violation per category run end to end.
|
||
- Mobile touch journey runs on real/emulated supported target with rendering.
|
||
- No unexplained/expired ignored test.
|
||
|
||
**Rollback:** release blocked or affected platform/scenario excluded.
|
||
|
||
### TRAFFIC-15 — Valid performance, soak, and release evidence
|
||
|
||
**Priority:** P0 final release gate
|
||
**Effort:** 6–10 person-days plus device lab/content review
|
||
**Depends on:** all enabled tranches
|
||
|
||
**Change**
|
||
|
||
- Replace idle-only timing with deterministic active workloads: steering, braking, contacts, traffic, rule transitions, HUD updates, and worst validated scenario.
|
||
- Measure release builds on declared desktop/mobile hardware: fixed-step CPU, input latency, main thread, draw submission, GPU, presented frame pacing, startup/load, memory/texture residency, persistence, idle/terminal battery behavior.
|
||
- Report statistically correct sample distribution; do not call averages medians.
|
||
- Profile p95/p99 hitches before optimization. Revisit ADR 003 only at its measured thresholds.
|
||
- Run 30-minute active soak, repeated scenario switching, suspend/resume, and 10k attempt persistence.
|
||
- Publish build/test/curriculum/capability/performance evidence by commit and content version.
|
||
|
||
**Tests / exit**
|
||
|
||
- All §6 budgets pass on every supported tier or documented mode/platform is disabled.
|
||
- Measurement includes actual rendering/GPU and active input; debug/Rosetta results are historical only.
|
||
- No unbounded memory/entity/event growth over soak.
|
||
- Qualified curriculum sign-off and all scenario evidence remain tied to shipped content hashes.
|
||
- Clean release build, migration/recovery, runtime UI, assets/licenses, accessibility, and policy gates are green.
|
||
|
||
**Rollback:** lower visual mode/frame tier or remove unvalidated scenarios; do not alter rule correctness or falsify documentation.
|
||
|
||
---
|
||
|
||
## 8. Persistence and content migration
|
||
|
||
1. Current scenario IDs remain aliases into versioned content records; list indices are never persisted.
|
||
2. Assign a content version only after the scenario's geometry/rules/copy are reviewed. Existing static catalog is `LegacyUnvalidated`, not automatically version 1 assessment content.
|
||
3. Attempt records bind scenario ID, content version, rule-engine version, score policy, replay/input digest, and result.
|
||
4. When rules change materially, retain old attempts with their version and recalculate only if a deterministic compatible migration is explicitly provided.
|
||
5. Settings migrate independently from attempts. Unknown future fields/version open read-only/recovery and are not overwritten.
|
||
6. Repository migration operates on copies, writes atomically, reopens/verifies, and preserves original bytes until rollback window ends.
|
||
7. Reserved `premium` may remain internal for compatibility but has no user-facing semantic and is excluded from assessment/access until a separate accepted entitlement ADR and implementation exist.
|
||
8. Demo/perf attempts are never written into learner progress.
|
||
|
||
---
|
||
|
||
## 9. Required CI command matrix
|
||
|
||
After TRAFFIC-01 establishes a coherent pin:
|
||
|
||
```bash
|
||
cargo metadata --locked --format-version 1 >/dev/null
|
||
cargo fmt -p nigig-traffic -- --check
|
||
cargo check --locked -p nigig-traffic --all-targets
|
||
cargo test --locked -p nigig-traffic --lib -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test ui_basic -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test scenario_replays -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test runtime_ui -- --test-threads=1
|
||
cargo clippy --locked -p nigig-traffic --all-targets -- -D warnings
|
||
git diff --check
|
||
```
|
||
|
||
Dependency-pin changes additionally run all reverse dependencies of `makepad-game-sim`, `makepad-game-blocks`, and `makepad-game-render`, derived from `cargo metadata`. The workflow must fail on Cargo exit status even if diagnostics belong to a dependency.
|
||
|
||
Scheduled/release jobs:
|
||
|
||
```bash
|
||
cargo test --locked -p nigig-traffic --test coordinate_properties -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test rule_adversarial -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test persistence_faults -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test asset_validation -- --test-threads=1
|
||
cargo test --locked -p nigig-traffic --test perf_release -- --test-threads=1 --nocapture
|
||
```
|
||
|
||
Rules:
|
||
|
||
- No Cargo/clippy failure suppression or package-only filtering that can hide dependency errors.
|
||
- No test-count floor substitutes for named per-scenario success/violation coverage.
|
||
- Ignored runtime/device tests require issue, owner, reason, and expiry and still block supported-platform release.
|
||
- Timing from idle, debug, CPU-only, or no-GPU paths is labelled diagnostic, never a release pass.
|
||
|
||
---
|
||
|
||
## 10. Release gates
|
||
|
||
### Practice-preview release
|
||
|
||
- [ ] Coherent Makepad pin builds all targets and CI fails honestly on dependency errors.
|
||
- [ ] Premium/Upgrade and false persistence/assessment copy is absent.
|
||
- [ ] Recursive `object_type`, lane coordinate, phase/input, terminal simulation, and score-max bugs are fixed.
|
||
- [ ] Every visible scenario is labelled Practice unless its assessment gates pass.
|
||
- [ ] Keyboard and supported touch controls work with lifecycle input clearing.
|
||
- [ ] Runtime UI tests execute and no required test is ignored.
|
||
- [ ] Missing/no-op assets cannot be presented as loaded functionality.
|
||
- [ ] Performance lifecycle proves no continuous hidden/terminal work.
|
||
|
||
### Assessment release (additional)
|
||
|
||
- [ ] Typed coordinate model passes translation/rotation metamorphic tests.
|
||
- [ ] Observation/contact layer distinguishes collision, proximity, zones, and course geometry correctly.
|
||
- [ ] Every production scenario enforces every claimed objective field with success/violation replays.
|
||
- [ ] Finish-only shortcuts cannot pass behavior lessons.
|
||
- [ ] All required hazards/signs/traffic/routes/inputs/assets exist and are packaged/licensed.
|
||
- [ ] Scenario scoring uses validated `max_points`/criteria and immutable result trace.
|
||
- [ ] Curriculum/jurisdiction/content version has qualified sign-off.
|
||
- [ ] Versioned atomic learner persistence/recovery passes before saved-progress copy appears.
|
||
- [ ] Desktop/mobile end-to-end assessment journeys pass.
|
||
- [ ] Release active-render performance, input latency, memory, soak, suspend/resume, and idle/terminal budgets pass.
|
||
- [ ] ADR 001 is obeyed; any future entitlement requires a separate explicit product/architecture decision and real enforcement.
|
||
|
||
---
|
||
|
||
## 11. Delivery, remote-safety, and rollback protocol
|
||
|
||
For every `TRAFFIC-NN` tranche:
|
||
|
||
1. Start from a clean worktree and record the parent SHA/current failing evidence.
|
||
2. Add a regression/replay/runtime test that fails against that parent.
|
||
3. Run targeted tests, dependency consumers when applicable, and `git diff --check`.
|
||
4. Commit one independently reviewable criterion using the tranche ID.
|
||
5. Immediately before push, run `git fetch origin main` and inspect merge-base/remote changes.
|
||
6. Rebase/merge without dropping remote work; rerun the complete tranche matrix after conflict resolution.
|
||
7. Push without force and verify the exact commit is on remote before beginning the next pushed chunk.
|
||
8. If authentication is unavailable, report the blocker and preserve the tested local commit. Never claim it was pushed or overwrite remote history later.
|
||
|
||
Rollback prioritizes learner safety and product honesty: disable the scenario/mode/asset/persistence claim while preserving valid profiles. Never roll back to false completion feedback, absolute-coordinate rules, input during Intro/terminal phases, suppressed build failures, or fictional commerce.
|
||
|
||
---
|
||
|
||
## 12. Critical path and cross-plan dependencies
|
||
|
||
```text
|
||
TRAFFIC-00 policy containment
|
||
TRAFFIC-01 coherent build → TRAFFIC-02 catalog → TRAFFIC-03 coordinates → TRAFFIC-04 lifecycle
|
||
└──────────────→ TRAFFIC-05 observations
|
||
└→ TRAFFIC-06 rules
|
||
└→ TRAFFIC-07 score
|
||
└→ TRAFFIC-08 curriculum
|
||
TRAFFIC-04 → TRAFFIC-09 input → TRAFFIC-10 frame lifecycle
|
||
TRAFFIC-07 + TRAFFIC-08 → TRAFFIC-11 persistence
|
||
TRAFFIC-08 → TRAFFIC-12 assets
|
||
TRAFFIC-01 → TRAFFIC-13 security; TRAFFIC-02/11/12 feed its parser/privacy/asset gates
|
||
All enabled paths → TRAFFIC-14 runtime → TRAFFIC-15 release evidence
|
||
```
|
||
|
||
- The Makepad dependency fix is workspace-wide and must be tested as such; do not patch dependency checkouts.
|
||
- Traffic persistence may reuse a proven repository primitive from `nigig-core`, but only after verifying its atomic/recovery semantics; importing a module name is not evidence.
|
||
- No CAD/Build/Site work is required to ship a safe Traffic practice preview, so those plans do not justify delaying P0 policy/build/correctness fixes.
|