docs(ADR-151): reconcile presence-field ADR with shipped v0.1.1 - #76
Open
proffesor-for-testing wants to merge 2 commits into
Open
docs(ADR-151): reconcile presence-field ADR with shipped v0.1.1#76proffesor-for-testing wants to merge 2 commits into
proffesor-for-testing wants to merge 2 commits into
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ADR-151 described a design that no longer matches the code, and read
Status: Proposed (WIP — still-person detection pending)whilepresence-fieldv0.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 againstsrc/cogs/presence-field/src/main.rs,cog.toml, the liveapp-registry.json, seedv0.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
cognitum-csi-relayis the single binder; agent injectsCOG_CSI_BIND, this cog is a consumer (always 5259, deterministic hash of cog id)--quorumor--breath-*--breath-*and--windoware not incog.toml, so unreachable via API--window <ms>{presence_score, node_count, thresh, source}{score, nodes, threshold, method, per_node_ratio, breathing_*, nodes_over_thresh, quorum}— every documented field name was wrongAlso 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:
present=falseafter ~15 s (cognitum-8b40)main.rs:430-434: still person 10-68× on every node, with 3 nodes and a clean calibrationBaseline 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
flooris 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./calibrateendpoint.PUTcan look like a no-op even for keys that work. Theargsarray in the/startresponse 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.0tag.0b2280dcorrects it:v0.24.1tagged 2026-07-31 14:02 UTC;e7e7489(#294) confirmed an ancestor viagit merge-base --is-ancestor, and #297 is in it too. Golden imagesseed-v0.24.1-image/seed-v0.24.2-imagefollowed the same day.POST /api/v1/apps/{id}/calibrateis inv0.24.1and answers on hardware — a seed reportingfirmware_version: 0.24.2returns400 "secs must be an integer from 1 through 600", not 404.v0.24.1match"integer" | "float" | "number"and"string" | "select", sothreshnow applies throughPUT /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--calibratefalls 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_detectedfor 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
baseline.jsonso a consumer can reportcalibration_suspectthreshasfloat— the builder acceptsnumberfrom v0.24.1, but older seeds in the field still drop it--window/--breath-*incog.tomlif they are meant to be tunable per siteRefs: #38, #75, seed#289, seed#290, seed#291, seed#294
🤖 Generated with Ruflo & AQE