docs: CHECKLIST sweep + .gitignore session artifacts + UI CSS catchup

- CHECKLIST.md: refresh head sha (12e1cf9d), date (2026-05-18),
  count (47 → 50 Done), explicit Done entries for ADR-118/119/120
  with the full session accuracy trajectory (40.4% → 90.40%).
- .gitignore: stop tracking deployment-specific training artifacts:
  v2/data/recordings/ (175 MB each), v2/data/adaptive_model.json
  (regenerated on each retrain), v2/data/baseline.json (regenerated
  on /api/v1/baseline/calibrate).
- ui/style.css: ship the .sensing-class-label color rules for
  present_moving (yellow), waving (purple), transition (orange) —
  written during ADR-117 conversation but missed by that commit.
- git rm --cached v2/data/adaptive_model.json (stays on disk; untracked).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
arsen 2026-05-18 10:32:39 +07:00
parent 12e1cf9d5e
commit e2c68191a2
4 changed files with 81 additions and 276 deletions

8
.gitignore vendored
View File

@ -258,3 +258,11 @@ v2/crates/rvcsi-node/*.node
v2/crates/rvcsi-node/binding.js
v2/crates/rvcsi-node/binding.d.ts
v2/crates/rvcsi-node/npm/
# ADR-117/118/119/120: deployment-specific training artifacts.
# - recordings/ are large (175 MB each) and room/operator-specific
# - adaptive_model.json is regenerated by `POST /api/v1/adaptive/train`
# - baseline.json is regenerated by `POST /api/v1/baseline/calibrate`
v2/data/recordings/
v2/data/adaptive_model.json
v2/data/baseline.json

View File

@ -5,15 +5,39 @@ at the end of every session. Pair with
[`docs/references/espectre-gap-analysis.md`](docs/references/espectre-gap-analysis.md)
for the technical detail behind each line.
Last sweep: **2026-05-17**, branch `feat/ota-rssi-mobile`, head `0ec1e4b0`.
Status: 47 Done / 0 Open in-scope. Deferred items (out of session scope,
Last sweep: **2026-05-18**, branch `feat/ota-rssi-mobile`, head `12e1cf9d`.
Status: 50 Done / 0 Open in-scope. Deferred items (out of session scope,
each with explicit reason) listed at the bottom.
This count includes the ADR-100..114 carry-in from the prior agent + this
session's ADR-115 (FW set-target REST), ADR-116 (WiFlow-v1 Rust loader),
ADR-116 cosmetic (UI dropdown), and ADR-117 (process hygiene + audit
follow-ups). ADR-111 is intentionally absent (folded into ADR-109 during
the AP-MAC tracking work).
This count includes the ADR-100..114 carry-in from the prior agent +
this session's:
* **ADR-115** — FW `/ota/set-target` REST endpoint
* **ADR-116** — WiFlow-v1 supervised pose loader in Rust + UI dropdown
* **ADR-117** — process hygiene (ping zombies, loopback filter, audit sweep)
* **ADR-118** — feature decorrelation + multi-node 22-feature extractor
* **ADR-119** — frame-level MLP classifier (22→32→6) replacing LogReg fallback
* **ADR-120** — windowed temporal classifier (W-MLP, 440→64→6) +
hybrid priority (rule-based owns 4 base classes, W-MLP owns
waving/transition) + two-layer label smoothing +
`/api/v1/adaptive/debug` diagnostic endpoint
ADR-111 is intentionally absent (folded into ADR-109 during the AP-MAC
tracking work).
Adaptive classifier accuracy trajectory across the session:
```
2-node 15-feat LogReg 40.4% baseline
6-node 15-feat LogReg 44.4% +4.0 (more sensors)
6-node 22-feat LogReg 49.58% +5.2 (ADR-118 feature engineering)
6-node 22-feat MLP 53.53% +3.95 (ADR-119 non-linear)
6-node 22-feat W-MLP 90.40% +36.87 (ADR-120 temporal context)
─────
total +50.0 pts vs baseline
```
W-MLP 90.40% is training-set accuracy; live `transition` class is
over-represented (model overfit to ambiguous training frames).
Held-out test set + cleaner per-class re-records are the recommended
next step.
---
@ -91,6 +115,30 @@ the AP-MAC tracking work).
runtime classifier; sensing tab container restored; multi-node
test guards external :5005; docs/typo/range sweep.
### Adaptive Classifier (data pipeline + model)
- [x] **ADR-118** Feature decorrelation + multi-node extractor —
audit on 6-node 151k-frame set found 21 multicollinear pairs +
1 dead feature (`amp_min` constant 0); refactored to 22 features
(4 global + 6 nodes × 3) with proper z-score normalisation.
Accuracy 44.4% → 49.58% (commit `e86f6506`).
- [x] **ADR-119** Frame-level MLP (22→32→6 ReLU+softmax) replaces
LogReg fallback — manual backprop, no external ML crate,
~3k weights, trains in seconds. Accuracy 49.58% → 53.53%
(+3.95 pts, concentrated on motion classes — exactly where
non-linear combinations matter; commit `94330708`).
- [x] **ADR-120** Windowed temporal classifier (W-MLP, 440→64→6) —
stacks 20 frames × 22 features for temporal pattern recognition.
Captures walking cadence (~2 Hz), sit-stand cycles (~0.5 Hz),
gesture rhythm (1-2 Hz). Accuracy 53.53% → 90.40% training
(+36.87 pts; held-out generalisation TBD). Hybrid priority:
rule-based owns 4 base classes (ESPectre F1>96%), W-MLP owns
`waving`/`transition` exclusively. Two-layer label smoothing
(15-tick mode + 2-tick confirm) stops UI flicker.
`/api/v1/adaptive/debug` exposes raw model labels for
operator diagnostics (commits `da4c123d`, `442c03da`, `3e12686a`,
`c3f00f3a`, `77d404d6`, `2956414b`, `12e1cf9d`).
### Tests / fixtures
- [x] **ADR-114** `tests/fixtures/replay_idle.jsonl` +
@ -112,7 +160,7 @@ the AP-MAC tracking work).
### Documentation
- [x] **ADR-100..117** all written (ADR-111 intentionally absent), each ≤ 200 lines
- [x] **ADR-100..120** all written (ADR-111 intentionally absent), each ≤ 200 lines
- [x] `docs/references/espectre-techniques.md` — Pace technique catalogue
- [x] `docs/references/espectre-gap-analysis.md` — section-by-section gap
- [x] Documentation actualization sweep — every Open Items section
@ -178,7 +226,7 @@ an explicit reason. Bring them back only if scope changes.
| Doc | Purpose |
|---|---|
| [`docs/adr/`](docs/adr) | All ADRs 001-117 (111 absent); 100-117 are this session |
| [`docs/adr/`](docs/adr) | All ADRs 001-120 (111 absent); 100-120 are this session |
| [`docs/references/espectre-techniques.md`](docs/references/espectre-techniques.md) | Pace technique catalogue + RuView adoption |
| [`docs/references/espectre-gap-analysis.md`](docs/references/espectre-gap-analysis.md) | Section-by-section gap with priority table |
| [`docs/references/ota-pipeline.md`](docs/references/ota-pipeline.md) | OTA recipe — port 8032, three FW prereqs |

View File

@ -2033,6 +2033,22 @@ canvas {
color: var(--color-error);
}
/* ADR-117 follow-up: extended class vocabulary from adaptive_classifier. */
.sensing-class-label.present_moving {
background: rgba(var(--color-warning-rgb), 0.15);
color: var(--color-warning);
}
.sensing-class-label.waving {
background: rgba(155, 89, 182, 0.15); /* purple — gestures, body still */
color: rgb(155, 89, 182);
}
.sensing-class-label.transition {
background: rgba(230, 126, 34, 0.18); /* orange — discrete event */
color: rgb(230, 126, 34);
}
.sensing-confidence {
display: grid;
grid-template-columns: 70px 1fr 40px;

View File

@ -1,267 +0,0 @@
{
"class_stats": [
{
"label": "absent",
"count": 862,
"mean": [
66.68196972264862,
67.23973219951662,
65.0340640002779,
205.65861248066514,
1.2587006960556917,
8.192575406032482,
0.0,
9.823395623712905,
6.970045450727901,
-0.04488812678641681,
-0.9594767860850162,
10.78889030301701,
0.8330000846014487,
22.47189099978742,
22.47189099978742
],
"stddev": [
64.0493846652119,
90.27545165651007,
40.157907144682206,
161.60550836256004,
1.3807130815029451,
3.2814660018571113,
0.0,
2.219723108446689,
1.6521309619598676,
0.342852106459665,
0.30620004291079783,
3.529722483499124,
0.17574148506941875,
5.519861526721805,
5.519861526721805
]
},
{
"label": "present_still",
"count": 852,
"mean": [
66.39259262094396,
64.42298266818027,
68.34546366405283,
203.34049479166666,
1.1900821596244182,
8.200704225352112,
0.0,
10.032339700775715,
7.234479413048846,
0.027056637948278107,
-0.9161490234231624,
10.991429347401095,
0.8298622589530178,
23.588978503428145,
23.588978503428145
],
"stddev": [
59.144593976065984,
82.61098004853669,
40.08306971525127,
152.89405234329087,
1.2031203046363153,
3.0571012493320526,
0.0,
2.22294769203091,
1.6508044238677446,
0.3315329147240876,
0.29437997092330526,
3.3214071045026303,
0.17096813624285292,
5.622953396738593,
5.622953396738593
]
},
{
"label": "present_moving",
"count": 808,
"mean": [
65.17005228763453,
66.55424930761484,
63.785855267654334,
208.73719832920793,
1.3400990099009942,
7.570544554455446,
0.0,
10.069915394050431,
6.923405617584522,
-0.1440461642917184,
-1.0022460352626226,
10.664608744841848,
0.8384559212414682,
21.798331033369895,
21.798331033369895
],
"stddev": [
66.1800697503931,
93.22042148141067,
42.07226450730718,
164.93282045618218,
1.3706144246607475,
3.1453995481213224,
0.0,
2.431170975696439,
1.672707406405861,
0.35643090355922863,
0.30897080072710387,
3.325911716352165,
0.1806597020966414,
5.418714527442832,
5.418714527442832
]
},
{
"label": "active",
"count": 794,
"mean": [
61.85289600233076,
61.12723986655727,
62.468831971775344,
193.2018524349286,
1.2329974811083138,
8.083123425692696,
0.0,
9.747035051350043,
7.009904234422278,
0.007176072447431498,
-0.9950501087764124,
11.015545839210892,
0.8278984910895401,
22.445656559614797,
22.445656559614797
],
"stddev": [
50.44687370766278,
74.07914900524236,
31.558067649516538,
121.0762294406304,
1.2507304998955402,
3.4503520526220344,
0.0,
2.2730029390882156,
1.6768264387667406,
0.3214256392367928,
0.31003127617615406,
3.1187829194728285,
0.1772099351197549,
5.595050695741912,
5.595050695741912
]
}
],
"weights": [
[
0.9923736589617821,
-0.4600422332552322,
-0.3922101552522972,
-0.1686954616947851,
-0.08471937018349271,
0.033940973559074515,
0.0,
-1.116294981490482,
-0.213861080404439,
-0.41727297566573723,
0.08025552056009382,
0.20864577739519874,
0.36814779033318357,
0.46242679535538855,
0.46242679535538855,
0.09475205040199337
],
[
0.04661470129518883,
0.7974124099989739,
0.3953040913806362,
-1.2708868935843511,
0.10073070355913086,
0.0735810797517633,
0.0,
-0.3957608057630568,
0.22091779039114648,
-0.43105406953304665,
0.24907697332262252,
-0.17604200203759515,
-0.5059663705836186,
0.5740861193153091,
0.5740861193153091,
0.020569218347928304
],
[
-0.5295363836864718,
0.14729609046092632,
0.16131671233151712,
0.15039859740752318,
0.08189110214725194,
-0.1429062024394049,
0.0,
2.459247211223509,
-0.162133339181718,
0.6345474095048843,
0.16626892477248892,
0.2710091094981082,
-0.08197569509399917,
-1.2007197895193034,
-1.2007197895193034,
-0.10027402587742726
],
[
-0.5094519765704947,
-0.48466626720467487,
-0.1644106484598614,
1.2891837578716183,
-0.0979024355228887,
0.0353841491285671,
0.0,
-0.9471914239699604,
0.15507662919500606,
0.2137796356938993,
-0.49560141865520463,
-0.30361288485571664,
0.21979427534444013,
0.16420687484859928,
0.16420687484859928,
-0.015047242872495047
]
],
"global_mean": [
65.08291570815048,
64.88537161757283,
64.96650236787292,
202.8304440905207,
1.25474969843183,
8.016887816646562,
0.0,
9.918865477040464,
7.036167472733628,
-0.038097952045357715,
-0.9672836370393502,
10.86491812646321,
0.8323017200972911,
22.58850497890069,
22.58850497890069
],
"global_std": [
60.376895354908775,
85.49291935872783,
38.814475392686795,
151.54766198012683,
1.3049002582695195,
3.2446975526483737,
1e-9,
2.2904371592847603,
1.667114434239705,
0.34470363318292857,
0.3067332188136679,
3.334427501751985,
0.17614366955910027,
5.577838072123601,
5.577838072123601
],
"trained_frames": 3316,
"training_accuracy": 0.4149577804583836,
"version": 1
}