diff options
| author | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:31:28 +0200 |
|---|---|---|
| committer | Jackson Moore <jacksonmoore@tuta.io> | 2026-09-04 12:31:28 +0200 |
| commit | d3b2783bf1ac2804336a7e1cfa02fe90e03488eb (patch) | |
| tree | 716e4806cd3f15f8d7d18f4661b9c54fd5b1f918 | |
| parent | 44de5ebbdea0193ef4072175795410b9d5d22afa (diff) | |
Build persistent target plans
| -rw-r--r-- | lua/clever_f/feedback_service.lua | 11 | ||||
| -rw-r--r-- | tests/run.lua | 27 |
2 files changed, 36 insertions, 2 deletions
diff --git a/lua/clever_f/feedback_service.lua b/lua/clever_f/feedback_service.lua index 084b30a..b6552ef 100644 --- a/lua/clever_f/feedback_service.lua +++ b/lua/clever_f/feedback_service.lua @@ -307,7 +307,7 @@ function M.persistent_context_eligible(context) or context.key == "cvr" end -function FeedbackService:request_persistent(specification) +function FeedbackService:build_persistent(specification) if type(specification) ~= "table" then fail("persistent feedback request must be a table", 2) end @@ -321,13 +321,20 @@ function FeedbackService:request_persistent(specification) if not domain.ResolvedMotionPlan.is(specification.motion_plan) then fail("persistent feedback request requires a ResolvedMotionPlan", 2) end - local request = { + if specification.motion_plan.target_plan ~= specification.target_plan then + fail("persistent feedback must reuse the movement TargetPlan", 2) + end + return { context = context, anchor = domain.Position.coerce(specification.anchor), target_plan = specification.target_plan, motion_plan = specification.motion_plan, window = specification.window, } +end + +function FeedbackService:request_persistent(specification) + local request = self:build_persistent(specification) local requests = service_records[self].persistent_requests requests[#requests + 1] = request return request diff --git a/tests/run.lua b/tests/run.lua index 136231d..8c66ca3 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -5817,6 +5817,33 @@ test("Target-plan errors remain inside acquisition cleanup guard", function() same("search planning failed", host:diagnostics()[1].text) end) +test("Persistent feedback reuses the movement TargetPlan", function() + fresh_sequence_state() + local host = MemoryHost.new() + local feedback = feedback_service.new(host) + local shared_target = target_plan.build(target("a"), matching_policy()) + local movement = motion_plan.build(shared_target, "f") + local persistent = feedback:build_persistent({ + context = "n", + anchor = domain.Position.new(1, 1), + target_plan = shared_target, + motion_plan = movement, + window = "window-1", + }) + + same(shared_target, persistent.target_plan) + same(shared_target, persistent.motion_plan.target_plan) + fails(function() + feedback:build_persistent({ + context = "n", + anchor = domain.Position.new(1, 1), + target_plan = target_plan.build(target("b"), matching_policy()), + motion_plan = movement, + window = "window-1", + }) + end, "reuse the movement TargetPlan") +end) + for _, item in ipairs(tests) do local ok, failure = xpcall(item.body, debug.traceback) if not ok then |
