feat(jev): advisory question families and graceful degradation #57
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/issue-21-advisory"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
lifekeeps Jev strictly advisory: calendar and task commands must never depend on a semantic model, and a model answer must never authorize anything. #19 delivered the typed HTTP adapter — wire validation and the pinned-model requirement — but nothing that asked a question. This change adds the code-owned, versioned question families that the next-task policy (#22–#24), review (#30) and memory-offer paths will consume, together with the graceful degradation that keeps every deterministic path working when Jev is disabled, unreachable, slow, rate limited, or answering wrongly.Changes
Five families, each code-owned and versioned independently of the model version, all dispatching through the #19 adapter so its strict wire validation and pinned-model requirement are inherited rather than re-implemented:
src/jev/questions/alignment.rs—alignment_v1,scoreover 5 ordered criteria; the rubric forbids inventing a fact the caller supplied as unknown (missing blockers or energy requirements stay unknown).src/jev/questions/consequence.rs—consequence_v1,scoreover 5 levels of cost of delay.src/jev/questions/readiness.rs—readiness_v1,scoreover 4 levels; a prerequisite the state does not state stays unknown and is never scored as ready.src/jev/questions/review_flag.rs—review_flag_v1,noul; the counts and their coverage come from the deterministic side, and the answer is an interpretation to offer for discussion, never a diagnosis.src/jev/questions/meaningful_memory.rs—meaningful_memory_v1,noul, matching the documented wire example exactly; the answer only ever offers retention.Supporting changes:
src/jev/advisory.rs—JevServiceis the single dispatch point, andJevDegradationthe explicit classification. Disabled ([jev].enabled = false, or no[jev]section) is a named capability that dispatches nothing and reportsjudgment_unavailablewith a configuration reason — never an outage, never an empty success. Transport, timeout, credential, rate-limit and unusable-configuration failures arejudgment_unavailable; a wrong model, drifted probabilities, a mismatched legend, a different question id or a malformed primitive isjudgment_invalid. Every dispatch is bounded by the service budget and cancellable, and no judgment path writes anything: no journal row, no calendar request, and no confidence threshold anywhere in the layer.candidate_advice()returns the three per-candidate scores alongside the degradations that replaced any of them;is_semantic()is false unless all three answered, so a partially judged candidate can never be presented as a semantic ranking.JevDegradation::warning()produces the envelope warning a caller attaches.life::jev::advisory::{JevService, JevDegradation, CandidateAdvice}andlife::jev::questions::{alignment, consequence, readiness, review_flag, meaningful_memory};ScoreAnswer/NouLAnswerare re-exported fromlife::jev. No route, no candidate filtering/ranking, nolife next, nolife resolve, no planning, no new dependency.Out of scope for this change (as agreed):
reference_match.v1and the resolve route belong to #20;interruption_impact.v1andcapture_class.v1are not part of this issue's scope boundary.Verification
nix develop --command cargo test— all suites green (393 tests, including the 19 new ones intests/jev_advisory_tests.rs);cargo clippy --all-targets -- -D warningsandcargo fmt --checkclean.noulcarrying aconfidencefield are eachjudgment_invalid.judgment_unavailable; a cancelled call leaves the backend immediately usable.[jev]enabled against a dead port produces a calendar write identical — modulo the generatedUIDand creation timestamps — to one with no[jev]section, carrying no warning;GET /v1/tasks,GET /v1/agendaandPOST /v1/tasksmake zero Jev calls.noul0.99) leaveoperations,life_events,item_projectionandoutboxempty and issue no calendar request; the same counters move on an explicit deterministic write, so the zero is not vacuous.state, the captured log across the accepted, unavailable, invalid and disabled paths is non-empty, contains the request fingerprint and both failure codes, and never contains the marker — while the mock confirms the state really was sent.Related Issues
Closes #21
Coordinator review — APPROVED
Verified
928f581myself (read the module and the rubrics, ran the suite on a tree based on currentmain).What I checked beyond the summary:
alignment.v1forbids the exact thing an advisory answer must never do. ItsINSTRUCTIONSstate that a fact marked unknown stays unknown and that no blocker, dependency, deadline, estimate or energy requirement may be invented or reported as satisfied, and it treats the state as data. That is the ruledocs/technical/jev.mdsets, enforced at the rubric rather than in a comment.CandidateAdvicefields areOption<ScoreAnswer>withis_semantic()requiring all three scores — a conservative choice I agree with, since two of three is not a ranking.judgment_answers_are_never_turned_into_rows_or_calendar_requestsproves strongest-possible answers produce zero CalDAV calls and zerooperations/life_events/item_projectionrows, then issues an explicitPOST /v1/tasksto show the same counters do move. That is the right way to assert an absence.a_jev_outage_never_changes_a_calendar_resultruns a Jev-enabled daemon against a dead port and a Jev-disabled daemon and asserts identical items and stable ICS bodies (modulo UID/DTSTAMP) — a real differential, not a single-path smoke test.Independent verification on
928f581:cargo test393 passed / 0 failed (19 new advisory tests);cargo clippy --all-targets -- -D warnings0 errors;cargo fmt --checkclean. Diff is 9 files, additive, and touches no route — #22–#24 own the filtering, ordering andlife next.Cargo.tomluntouched, so the deferred authors chore stays pending.Merging.
feat(jev): advisory question families and graceful degradation (#21)to feat(jev): advisory question families and graceful degradation