Day-level events now score Vimshottari/Narayana transition closeness so
nearby candidate minutes can diverge, with gated quality probes and
answer-prior ranking so high-base-rate existence questions stay out.
Co-authored-by: Cursor <cursoragent@cursor.com>
deliveryCapability no longer ties adoption to minute separation or holdout;
those stay on the exact-minute confirmation gate so users can save a range.
Co-authored-by: Cursor <cursoragent@cursor.com>
Spoken collect no longer renders a second visual prompt; choice legends stay screen-reader only and live cards share the assistant inset. Exhaustion collect avoids colliding with the opening question id, and a successful billed turn no longer surfaces run_failed after the exit gate.
Co-authored-by: Cursor <cursoragent@cursor.com>
The previous pass closed the "adoptable on one event" hole but left no
forward path: case 645ba774 ends with can_adopt false and
current_question null, so the user is stuck with neither a result nor a
next question. Two causes: answer_choice never reaches
ensureNonTerminalTurnExit or persistNextInterviewIfIdle, all of whose
call sites sit in the message/opening branches; and once every probe is
answered or dropped, decideRectification returns offer_provisional_range
before the holdout branch, ignoring unused oos_blind prompts and the
nakshatra boundary question.
Same defect class as BUG-456, which was fixed by patching one branch
rather than gating every exit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVapmh2oGNyr6ECHKjPJY8
The registry packagePath points at versions/<version>/, but the root
SKILL.md copy makes it easy to hash the package root instead. Hashing
the root pulls the entire versions/ subtree into the digest and still
returns a value, so the mistake surfaces only as a failing gate later.
Records BUG-459 and corrects the task brief's D-2 table, which listed
the root SKILL.md as the hash target.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVapmh2oGNyr6ECHKjPJY8
The engine receipt says acceptance_allowed/selection_allowed false with
reasons insufficient_events and insufficient_domain_diversity, yet the
top-level projection flips both to true and renders adoptable candidates
after a single piece of evidence. Records the four structural causes:
dual decision authority where overlayPublicDecision lets TS override the
engine, insufficient-evidence sharing an exit with exhausted, capability
flags hardcoded across eleven branches, and several fail-open paths
including holdout "unavailable" granting adoption.
Also folds in the skill bump (D-2) after verifying that existing cases
bind their own skill_version and deprecated packages still resolve, so
no case migration is required.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVapmh2oGNyr6ECHKjPJY8
Traces the staging run_failed on the first user message to a missing
feature_pricing row: the opening turn is free and skips reserve(), so
the first `message` action is the first request to hit
resolve_feature_pricing, which raises feature_pricing_missing and maps
to the generic run_failed fallback. Also records the independent
opening-turn defect that leaves current_question null.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVapmh2oGNyr6ECHKjPJY8
Verified both round-1 briefs against the code rather than the progress
notes. Billing 0/1/2/3/6 and rectification 0/1/2/3/6 are in and clean, and
neither the confirmation gate nor the sealed holdout was loosened.
Two gaps remain. Prompt caching only emits its marker for Anthropic, so on
a DeepSeek-class provider it buys observability and no cost reduction, and
the membership fair-use numbers are untouched — correctly so, since no
real unit cost has been measured yet. The round-2 brief gates those on a
staging measurement pass and pulls the per-answer narrowing table forward,
since it is the deliverable and depends on nothing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
Two real local sessions are archived. In them the agent states twice that
its minute came from a report already in the upstream repo rather than
from the user's answers, and the follow-up "fix" wired that answer into
the scoring chain; upstream now carries a Narayana tie-break derived from
that single case. This repo was checked and is clean, so two red lines now
keep it that way and gate any upstream sync.
The same records show what the answers genuinely bought: a 30-minute
window narrowed to 3. Tasks 7-10 add what makes that deliverable — the
per-answer narrowing table, an explain surface, mid-case window changes
with evidence retained, and the batched first round.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
The upstream interview playbook and evidence thresholds resolve task 0.
Upstream stops and reports when evidence is thin — fewer than three dated
events, fewer than two domains, or a tie — while this repo treats the same
kind of thresholds as a confirmation gate and keeps asking when they are
not met. Its label ladder has no confirmed rung at all, and every contract
test asserts candidate_range_not_birth_time_truth.
Task 1 capped the interview by round count, which is half of it. Task 6
adds the evidence-state stop rules, reframes exhausted as a normal
delivery, adopts the upstream label ladder and closing wording, and keeps
the 4/3 confirmation gate separate from the 3/2 delivery floor.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
Comparing against the upstream skill repo overturned v1's premise. The
three methodology files are byte-identical across both repos, and the
production v5 scorer imports the same upstream event engine the v4 ranker
does, so swapping engines is off the table and v1's three-way bake-off is
dropped.
What productization actually dropped is the stopping mechanism: upstream
terminates on a fixed 8-question bank and a one-shot adjudication, while
the production decision path discriminates as long as a probe exists. The
round budget is computed but never read by that path, and the "exhausted"
branch it needs already exists. Tasks now wire that budget in, restore the
upstream next-step summary, and keep the report readable from turn zero.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
Audit found three unrelated rectification scoring paths: the local-agent
methodology references, the production v5 server scorer, and the v4 fact
ranker that only the eval scripts import. The sealed holdout numbers
measure the third one, so neither the production path nor the local path
has ever been evaluated.
Task 0 is therefore a blind three-way bake-off on one case set, gating
every later task. The remaining tasks cover a single convergence function
with property tests, moving question authority fully to the server, making
the deliverable exist from turn zero, and the calibration data shortage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
Records the billing gaps found by reading the live code paths: report.full
has no authorizeUsage call at all, rectification charges model.creditCost
once per case, and pricing is bound to the model rather than the feature.
Seven tasks, with task 0 as a measurement gate so no price lands in the
database from an estimate. Task 6 adds an admin pricing simulator next to
the model config page so margins stay computable against live data.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
.personal-report-reader declared --report-paper, --report-rule and
--report-accent on itself. A custom property resolves from the nearest
element that declares it, so an element-local declaration beats :root
regardless of media queries or source order — the dark override added
with the theme was dead the moment it was written.
The inks did follow the theme, because they live on :root. So dark mode
put --color-ink (#f2f0ea) on paper that stayed #f8f5ee: 1.05:1 for
headings and 1.22:1 for body. The report was effectively invisible.
Printing had the same defect from the other side: the print block forces
white backgrounds but never reset the inks, so printing from a dark
screen produced a blank page. It now pins the palette back to light —
paper is always paper.
Every report ink now clears AA on report paper in both themes, and the
new contract test forbids re-declaring the report palette anywhere but
:root, which is the trap that caused this.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155nFCgCHtoA7jhSDGmZmMu
When coverage still blocks adopt and no renderable discriminator remains, narrate the numeric range and persist a spoken collect instead of promising a time card that cannot be clicked. Recompute probe information gain on active candidates and drop zero-split probes explicitly.
Co-authored-by: Cursor <cursoragent@cursor.com>