Repository navigation
docs(spec): taste-residual-v1 taste profile and learning spec with machine-checked contracts - #146
Conversation
…chine-checked contracts Rule-anchored residual ranker spec (SPEC.md), JSON Schema contracts for taste events, exposures, profile statements, and golden fixtures, plus 17 validated examples, a stdlib checker that re-runs the reference model over the golden fixture at 6-decimal precision, and the example generator. check.py: 17 examples valid and self-consistent (exit 0); planted-failure negative test exits 1. Co-authored-by: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Independent review (Obvious, Autobuild + Max) Verdict: changes needed — as a draft, this is close: the normative math verified correct against an independent reimplementation, the checker genuinely bites on every expected section, and CI is green. But §6's coverage claims outrun what the contracts actually check, and two normative-math inconsistencies (GLOBAL_CLAMP semantics, hedged-statement rule) would force implementation PRs to guess on parity-critical behavior. All fixable with small spec/checker edits; no existing code touched, no regression surface (adds files only). Findings (ranked by severity)1. Medium — 2. Medium — the reference model ignores every non- 3. Medium — GLOBAL_CLAMP is specified two inconsistent ways, and the checks enforce neither effective semantics. 4. Medium — the hedged-statement rule in §4 contradicts §9's disposition, and 5. Medium — three inconsistent definitions of the canonical form the parity contract depends on. 6. Low — contract/SPEC drift in enums, pointers, and decay constants.
7. Low — 8. Low — timestamp pattern accepts a malformed form; canonical checks narrower than §6 states. 9. Low — SPEC.md:124 "the golden fixture pins the tiebreak" doesn't hold. The fixture's events have distinct timestamps and no two recipes tie on totalScore, so neither the What I verified (commands and results)
What I couldn't verify
|
…racts Address the nine independent-review findings on the taste spec contracts: per-kind event payload branches with unknown-field rejection, loud failure on unconsumed evidence events, one GLOBAL_CLAMP over pins plus learned sums with the raw contribution preserved, statement over-claim gates (hedged requires numerator == denominator, confident requires ratio >= 0.6, denominator >= 3), one canonical-serialization wording, corrected schema/spec references, household-size cap removed, calendar-valid whole-second UTC timestamps and document-wide 6-decimal float scans, and a fixture tie-break exercised by the rank order. Adds mutation_matrix.py (52 adversarial cases, all caught, plus copy and positive controls) and reworks the golden fixture: unrated cook followed by a rated merge, a save, a skip, an active pin, and a featureless 60.0 tie; the example inventory is now 19 files. SPEC.md carries the review-response table and the regenerated worked-example values.
Human author: Sam Gu (sgu07966@gmail.com)
Taste Profile & Learning — SPEC (
taste-residual-v1)Draft spec + machine-checked contracts for household taste learning: a rule-anchored residual ranker — today's rule score, plus small bounded evidence-weighted feature adjustments — with exposure logging, a three-layer profile statement model (restriction / inferred / pinned) with first-class correction, and deterministic verification contracts. Addresses the same problem as the two failed full-learning attempts (FLTaste trailed the rule ranker by ~11% NDCG@10 in the reduced campaign) without repeating their failure mode: personalization starts at today's behavior and earns deviations slowly.
This PR changes only
docs/spec/taste/— no app, backend, CI, or deploy code.What's here
SPEC.md— normative math (§2), worked golden fixture (§3), statement model (§4), privacy/household (§5), verification (§6), alternatives (§7), scope (§8), adversarial review + independent-review response (§9), verification record (§10). Opens with the load-bearing assumption: bounded residuals must improve pairwise order in replay without moving top-10 composition more than a few percent, or the data is too thin to learn from at all.contracts/*.schema.json— four JSON Schema (draft-2020-12 subset) contracts; the event schema validates per-kind payload branches throughallOf/if/thenwithadditionalProperties: false.contracts/examples/— 19 canonical examples: one per event kind (12), one exposure, five statement variants, and the golden fixturecoriander-v1.json(three rated coriander cooks, an unrated cook +recipe_ratedmerge, a save, a skip, an active pin, and a featureless 60.0 ranking tie).contracts/check.py— stdlib-only checker: schema validation, canonical serialization of the committed bytes, calendar-valid whole-second UTC timestamps, 6-decimal float scans, exposure/slate-position cross-references, statement evidence gates, a required-example manifest, and a full recompute of the golden fixture's expected state (byte-compare at 6 decimals).contracts/gen_examples.py— regenerates every example; implements the model independently from the checker against the same constants.contracts/mutation_matrix.py— 52 adversarial mutations, each required to fail the checker, gated by copy and positive controls.Why the second commit
An independent review of
ef37a82returned nine findings; all nine landed as contract changes with a corresponding mutation case (per-kind payload validation, loud failure on unconsumed evidence events, oneGLOBAL_CLAMPover pins + learned sums with the raw contribution preserved, hedged/confident statement over-claim gates, one canonical-serialization wording, corrected schema/spec references, household-size cap removal, calendar-valid timestamps + document-wide float scans, and an exercised ranking tie-break). §9.1 of the SPEC maps each finding to its disposition and verification. Two further invariants came out of the fix round itself: a required-example manifest, and a canonical(at, id)input-log order for committed fixtures — which immediately caught an out-of-order regeneration of the fixture.How I checked
python3 docs/spec/taste/contracts/gen_examples.py— regenerates all 19 examples; fixture values:ingredient:101alpha 0.495379 / beta 1.126520, contribution −0.546217; pin-bound applied contributions −8.0 with raw −8.646369 / −8.546217; ranking totals 60.0 / 60.0 / 59.075155 / 55.0 / 53.0.python3 docs/spec/taste/contracts/check.py—checked 19 examples … all examples valid and self-consistent, exit 0.python3 docs/spec/taste/contracts/mutation_matrix.py— 52 cases: every mutation caught, the size-4-household control validates, the untouched-copy positive control passes, exit 0.ef37a82before fixing (wrong-kind payload fields, malformed timestamp, over-precision float, over-claiming hedged statement all passed the old checker; household size 4 was rejected; an unmergeablerecipe_ratedwas silently ignored).git log/git statusreviewed before commit: 15 files underdocs/spec/taste/only.What I could not check
check.pyimplements the subset the schemas use; a full validator was deliberately not added as a dependency.Assumptions
ingredient:101= coriander,cuisine:indian) are illustrative fixture identifiers, not catalog IDs to resolve.🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact