Skip to content

docs(ADR-151): reconcile presence-field ADR with shipped v0.1.1 - #76

Open
proffesor-for-testing wants to merge 2 commits into
mainfrom
docs/adr-151-current-status
Open

docs(ADR-151): reconcile presence-field ADR with shipped v0.1.1#76
proffesor-for-testing wants to merge 2 commits into
mainfrom
docs/adr-151-current-status

Conversation

@proffesor-for-testing

@proffesor-for-testing proffesor-for-testing commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

ADR-151 described a design that no longer matches the code, and read Status: Proposed (WIP — still-person detection pending) while presence-field v0.1.1 is published in the public registry and being installed by design partners. Docs only — no code changes.

Found while answering a design partner who could not get presence_detected: true. Every claim below was checked against src/cogs/presence-field/src/main.rs, cog.toml, the live app-registry.json, seed v0.24.1 / origin/main, and a seed running 0.24.2.

The headline

The breathing-band detector this ADR named as its exit criterion has landed — but it ships advisory-only and never sets presence_detected (main.rs:439-444). The reason is recorded in the implementation: empty-room respiration SNR can equal or exceed still-person SNR, because CSI passes through walls. So the criterion is satisfied by the code and not by the outcome, and the ADR's question is still open. The ADR did not say this anywhere.

Drift corrected

ADR said Code does
"the cog owns UDP 5006" ADR-104 P2: cognitum-csi-relay is the single binder; agent injects COG_CSI_BIND, this cog is a consumer (always 5259, deterministic hash of cog id)
CLI without --quorum or --breath-* all four exist; --breath-* and --window are not in cog.toml, so unreachable via API
--window <ms> a frame count
output {presence_score, node_count, thresh, source} {score, nodes, threshold, method, per_node_ratio, breathing_*, nodes_over_thresh, quorum} — every documented field name was wrong

Also added to the Decision: quorum fusion, and the calibration-quality guard.

What I deliberately did not resolve

Two still-person measurements are on record, both dated 2026-06-15, and they contradict each other:

  • this ADR: seated person ~1.2-1.9×, 14/14 present=false after ~15 s (cognitum-8b40)
  • main.rs:430-434: still person 10-68× on every node, with 3 nodes and a clean calibration

Baseline quality plus node count is the likely reconciliation, but it is untested, so it is written as a hypothesis. Neither figure should be quoted as this cog's behaviour until a controlled run settles it. The cognitum-4e61 3-node proof this ADR asked for was never recorded anywhere. I did not touch the contradicting comment in main.rs — which one is right is an open question, not a typo.

Added to Limitations

  • Contaminated baseline is the dominant field failure mode. floor is the mean in-sample residual of the calibration frames and the projected-out eigenmodes come from those same frames, so an occupant present during calibration lands in both and every later reading pins near 1.0. Bench-verified 2026-06-15 (6× → 2×); observed in the field 2026-07-31, where the guard warned, the baseline was saved anyway, and a person walking into the room peaked at 4.6 against a 4.0 threshold. The guard warns and continues — it should refuse.
  • Calibration is API-driven from seed v0.24.1, CLI-only below it. Seeds still on 0.22.x — which includes design-partner units — have no /calibrate endpoint.
  • A config value equal to the declared default emits no argv on any firmware, so a PUT can look like a no-op even for keys that work. The args array in the /start response is the reliable check.

Second commit: release-status correction

The first commit repeated "v0.24.0 publication is held, field devices run v0.23.x" from the seed#289-291 closing comments (2026-07-31T12:02Z) without checking the release list. That was wrong — the release shipped ~2 h after those comments as v0.24.1; there is no v0.24.0 tag. 0b2280d corrects it:

  • v0.24.1 tagged 2026-07-31 14:02 UTC; e7e7489 (#294) confirmed an ancestor via git merge-base --is-ancestor, and #297 is in it too. Golden images seed-v0.24.1-image / seed-v0.24.2-image followed the same day.
  • POST /api/v1/apps/{id}/calibrate is in v0.24.1 and answers on hardware — a seed reporting firmware_version: 0.24.2 returns 400 "secs must be an integer from 1 through 600", not 404.
  • Both argv builders in v0.24.1 match "integer" | "float" | "number" and "string" | "select", so thresh now applies through PUT /config (seed#289 shipped).

Two details taken from the shipped handler rather than the issue comment: it calls kill_app_processes() and takes over a running instance instead of answering 409, and because --calibrate falls through into detection the single call both calibrates and leaves the cog running.

Consequences changed

The old text said this "unblocks the Vitality Call deployment once the breathing-band detector lands". It landed, and it does not unblock them — they gate all vitals behind presence_detected for a patient who rests still, which is exactly the unproven case. Now stated plainly, alongside what the cog does deliver today: motion and arrival.

Follow-ups added

  • controlled still-person run (clean calibration, 1 vs 3 nodes, seated subject)
  • make the calibration guard fail closed, or persist the verdict into baseline.json so a consumer can report calibration_suspect
  • re-declare thresh as float — the builder accepts number from v0.24.1, but older seeds in the field still drop it
  • expose --window / --breath-* in cog.toml if they are meant to be tunable per site

Refs: #38, #75, seed#289, seed#290, seed#291, seed#294

🤖 Generated with Ruflo & AQE

The ADR described a design that no longer matches the code, and read as
"still-person detection pending" while the cog is published in the public
registry and installed by design partners. Verified against
src/cogs/presence-field/src/main.rs, cog.toml, the live app-registry, and
seed/src/cognitum-agent/src/{api.rs,data_source.rs}.

Status: Proposed (WIP) -> Accepted (shipped v0.1.1), with the exit criterion
restated. The breathing-band detector this ADR named as the condition for
leaving draft HAS landed, but ships advisory-only and deliberately never sets
presence_detected -- empty-room respiration SNR can equal still-person SNR
through walls. The criterion is met by the code and not by the outcome.

Corrected drift:
- "the cog owns UDP 5006" -- under ADR-104 P2 cognitum-csi-relay is the single
  binder; the agent injects COG_CSI_BIND and this cog is a relay consumer
  (presence-field is always 5259, deterministic hash of the cog id)
- CLI block was missing --quorum and all three --breath-* knobs
- --window is a frame count, not milliseconds
- documented output JSON was wrong in every field name; replaced with what the
  cog emits, incl. per_node_ratio / method / breathing_*
- added quorum fusion and the calibration-quality guard to the Decision

Limitations, without resolving what the evidence does not settle:
- the two still-person measurements on record (seated 1.2-1.9x on 8b40 vs
  10-68x on a 3-node clean-calibration bench, both 2026-06-15) are recorded as
  disagreeing; baseline quality is flagged as a hypothesis, not a conclusion
- the cognitum-4e61 3-node proof this ADR asked for was never recorded
- contaminated baseline added as the dominant field failure mode, with the
  bench (6x -> 2x) and field (2026-07-31 design partner) evidence
- thresh is unsettable via the seed API (declared `number`, argv builder drops
  it) and calibration is CLI-only on shipped firmware -- both fixed in seed
  main, both behind the held v0.24.0

Consequences: Vitality Call is NOT unblocked; landing the detector did not
change that, because it is advisory. Follow-ups added for a controlled
still-person run, failing closed on contaminated calibration, and re-declaring
thresh as float.

Refs: cogs#38, cogs#75, seed#289, seed#290, seed#291

Co-Authored-By: Ruflo & AQE
…I is live

The previous commit repeated "v0.24.0 publication is held / field devices run
v0.23.x" from the seed#289-291 closing comments (2026-07-31T12:02Z) without
checking the release list. The release went out ~2h after those comments, as
v0.24.1 — there is no v0.24.0 tag.

Verified:
- v0.24.1 tagged 2026-07-31 14:02 UTC; e7e7489 (#294) confirmed an ancestor via
  git merge-base --is-ancestor. #297 is in it too. Golden images
  seed-v0.24.1-image and seed-v0.24.2-image followed the same day.
- POST /api/v1/apps/{id}/calibrate is present in v0.24.1 and answers on
  hardware — cognitum-8b40 reports firmware_version 0.24.2 and returns 400
  "secs must be an integer from 1 through 600", not 404.
- Both argv builders in v0.24.1 match "integer" | "float" | "number" and
  "string" | "select", so thresh now applies through PUT /config.

Two details corrected against the shipped handler rather than the issue
comment: it calls kill_app_processes() and takes over a running instance
instead of answering 409, and since --calibrate falls through into detection
the single call both calibrates and leaves the cog running.

Kept as a live limitation: seeds below v0.24.1 have no endpoint and must use
the CLI flag, which includes design-partner units still on 0.22.x. Also kept:
a config value equal to the declared default emits no argv on any firmware.

Follow-up restated — thresh still declares `type = "number"`, so re-declaring
it `float` remains worthwhile for older seeds in the field, even though the
builder now accepts it.

Co-Authored-By: Ruflo & AQE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant