Repository navigation
fix: route legacy Lavish captain answers safely - #63
Merged
Merged
Conversation
…ce field The Lavish answers adapter only read an unversioned question/answer row when it had no note field. Lane-composed decision decks emit note, task, owner, recommended and decision_key beside answer, and some name the pick choice, so their captured answers produced no keyed row and never reached the intake. Require only a slug-shaped question and one nonempty string answer (or choice) for a row with no schema and no selection, keep the reserved reconcile values refused, and append a nonempty note to the label so the record keeps the captain words.
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.
Intent
I would like all bugs to be fixed so tomorrow can be focused entirely to Vernant and not problems preventning Vernant from getting built.
A recommended architecture should come with proof.
Context (the backlog record for this bug, as filed): Lavish answers adapter returns nothing for older page choice formats, so captured captain answers (e.g. Backpass A) never route; adapt the legacy shape and replay unrouted captured answers safely (repo: firstmate) (kind: ship) (priority: 0) (since 2026-09-30) ... Found by fm-open-loops-audit 2026-09-30 (data/fm-open-loops-audit/report.md root cause 2): 46 of 251 captured structured answers lack proved routing; lavish-43b2c19414f5cd4f.1.result holds key backpass-path answer A-upstream-optin-plus-fork-bridge but the answers adapter emits no keyed row. Fork MrGTV-love/firstmate only. mode=no-mistakes yolo=off.
What Changed
choicewhenansweris absent and preserving notes in answer labels.Risk Assessment
🚨 High: The newly accepted legacy path can close a task using a superseded answer, and the explicitly required recovery of previously captured answers remains undelivered.
Testing
Five real Lavish browser submissions and an idempotent capture replay passed, with screenshots, raw captures, CLI resolutions, and persisted-state evidence saved. The base adapter reproduced the dropped-answer regression, and all four focused regression selectors passed after completing the initially timed-out invocation separately. Disposable resources were removed.
Evidence: Consolidated live results, raw captures, baseline comparison, and replay evidence
Source: Consolidated live results, raw captures, baseline comparison, and replay evidence
Evidence: Product CLI task resolutions and unchanged replay state
Source: Product CLI task resolutions and unchanged replay state
Evidence: Persisted backlog after live routing
Source: Persisted backlog after live routing
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
bin/fm-procevent-lavish.sh:827- A later legacy Reconcile choice does not invalidate an earlier ordinary answer for the same question. For example, a capture containing {question:"sample-call",answer:"A",note:""} followed by {question:"sample-call",answer:"reconcile",note:"check first"} now emits A: the second row exits before the last-choice replacement at line 846. The bound runner consequently closes the held task using the superseded answer. Before this change, both note-bearing rows were skipped. The same invariant must hold for the answer/choice alternatives at line 823, bare and annotated reconcile values at line 827, duplicate replacement at line 846, and both answers/reconciles outputs at lines 853–866. Resolve the latest structurally valid choice per question before filtering legacy reconcile values, so those values suppress earlier answers without entering either intake.bin/fm-procevent-lavish.sh:821- The required recovery is absent from this deliverable. The authoritative criterion is “adapt the legacy shape and replay unrouted captured answers safely”; the changed hunk only broadens the unversioned extraction branch, and the new test at tests/fm-captain-hold-lifecycle.test.sh:1810 feeds a fresh synthetic capture once. Existing routing runs only after a new capture (bin/fm-procevent.sh:1373); restart reconciliation merely republishes pending notifications (lines 1688 and 895–903), without feeding stored answers. Thus upgrading the adapter alone does not route previously captured answers such as the reported Backpass capture. Deliver a bounded replay procedure or executable recovery path using the existing binding and keyed-answer intake, preserving original source/sequence provenance and reporting applied, already-resolved, and unresolved outcomes, together with recovery evidence. This is an unmet intent requirement, not a request for general retry machinery.🔧 Fix applied.
1 error still open:
bin/fm-procevent-lavish.sh:821- The required recovery is absent from this deliverable. The authoritative criterion is “adapt the legacy shape and replay unrouted captured answers safely”; the changed hunk only broadens the unversioned extraction branch, and the new test at tests/fm-captain-hold-lifecycle.test.sh:1810 feeds a fresh synthetic capture once. Existing routing runs only after a new capture (bin/fm-procevent.sh:1373); restart reconciliation merely republishes pending notifications (lines 1688 and 895–903), without feeding stored answers. Thus upgrading the adapter alone does not route previously captured answers such as the reported Backpass capture. Deliver a bounded replay procedure or executable recovery path using the existing binding and keyed-answer intake, preserving original source/sequence provenance and reporting applied, already-resolved, and unresolved outcomes, together with recovery evidence. This is an unmet intent requirement, not a request for general retry machinery.✅ **Test** - passed
✅ No issues found.
Started reallavish-axi server --verboseversion 0.1.79 on private port 54468 with worktree-localLAVISH_AXI_STATE_DIRand isolatedFM_HOME.Created held tasks usingbin/fm-captain-hold.sh hold, explicitly bound four sources, and registered real Lavish polling throughbin/fm-procevent.sh register lavish ... -- bin/fm-procevent-lavish.sh poll ....Drove five actual Lavish browser decks: clicked their choice controls andSend & End, then observed real runner captures, adapter outputs, persisted task resolutions, and reconcile requests.Executed the base-commit adapter against feedback captured during this run: it emitted no ordinary legacy answers; the current adapter emitted all four.Replayed the ordinary capture throughbin/fm-captain-hold.sh answers --source 'the captured result lavish-53b7a2f80d4ae0c6 sequence 1'; all four deliveries were accepted and the persisted backlog remained byte-for-byte unchanged.Ranbash tests/fm-captain-hold-lifecycle.test.sh test_unversioned_deck_shapes_with_extra_fields_still_route test_legacy_reconcile_replaces_previous_choices test_bound_channel_answers_close_at_answer_time test_unbound_source_closes_no_hold. The first two selectors passed before the command reached its 240-second deadline.Ran the remaining selectors separately:bash tests/fm-captain-hold-lifecycle.test.sh test_bound_channel_answers_close_at_answer_time test_unbound_source_closes_no_hold; both passed.Inspected screenshots andtasks-axi show <task-id> --fulloutput; closed all test tabs, stopped the isolated server, confirmed no sources remained registered, and removed this run's disposable worktree files.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.