-
Notifications
You must be signed in to change notification settings - Fork 2
plat 074
| Coordination | Value |
|---|---|
| Assigned agent | unassigned |
| Ticket state |
implemented — 4 of 6 call sites fixed and tested; 2 reclassified (not platform bugs) |
| Last synchronized | 2026-08-10 |
- Priority: P2 — provenance gap, not data loss; makes changelog-based review/revert unreliable for a known subset of tools
-
Owner: plan changelog writer (
writePlanChangelogEntry/completePlanChangelogEntry,planning_agent.go) -
Found on: cross-workflow, PLAT-073 Cluster C (9 findings: build-in-public
x3, linkedin x2, rtslatency, social-media, tectonicusadaytrading, upwork).
Headline evidence: "159 of 231 plan-mutation entries carry neither a
changes[]array norbefore_ref/after_ref" (tectonicusadaytrading69f4a8a7).
One shared writer, not six independent bugs (PLAT-056 shape). Every
plan-mutation tool funnels through logPlanChange →
writePlanChangelogEntry → completePlanChangelogEntry, which computes
before_ref/after_ref in priority order: an explicit BeforeSnapshot/
AfterSnapshot first, then (before this fix) a Changes[] field-diff, and
if neither was supplied, both refs collapsed to the same
sha256("[]") placeholder — a value that is real and stable, but carries no
information (this is the exact placeholder PLAT-033 already named and fixed
for update_step_config).
10 of 16 call sites already supply Changes or a real snapshot (fixed under
PLAT-033/PLAT-055). The remaining 6 did not — but 4 of those 6 already had
the real before/after content sitting in scope at the call site (deleted-step
JSON, added-step JSON, route JSON, full plan.json before/after a rewrite); it
just was never wired into the entry. Only 2 of the 6 needed new data capture.
completePlanChangelogEntry fallback (planning_agent.go:1028-1057) — when
no explicit snapshot is given, fall back to hashing DeletedSteps for
before_ref and AddedSteps for after_ref before collapsing to the
placeholder. This single change fixes 3 call sites at once, since all three
already populate one of those fields with real content:
-
delete_plan_steps(planning_agent.go:3852) — already captured full deleted-step JSON asDeletedSteps. -
add_scripted_step/add_routing_step/add_message_sequence_step/add_human_input_step/add_todo_task_step(shared adder,planning_agent.go:4768) — already captured full added-step JSON asAddedSteps. -
delete_todo_task_route(planning_agent.go:5555) — already captured the deleted route's JSON asDeletedSteps.
add_todo_task_route (planning_agent.go:5302) — now marshals the route as
it actually landed in the plan (post orphan-ref resolution) and passes it as
AddedSteps.
update_todo_task_route (planning_agent.go:5458) — the only site with no
pre-existing capture of any kind. Now marshals *routeToUpdate before any
field mutation and again after, passing both as BeforeSnapshot/
AfterSnapshot.
migrate_message_sequence_code_items (message_sequence_code_migration.go:188)
— planContent (pre-migration) and migratedPlan (post-migration) were
already read/built in scope for the write+rollback path; now also passed as
BeforeSnapshot/AfterSnapshot.
All four fixes use data the caller already had — none required a new read, diff, or capture pass, so there is no added I/O cost.
-
add_todo_task_route/update_todo_task_routeneeded the new capture above (not pre-existing data) — see fix list; included for completeness since the investigation initially treated them as "not structurally blocked" alongside the other four, which undersold the actual gap. -
Cluster C's 3 build-in-public and 2 linkedin findings, plus rtslatency,
social-media, tectonicusadaytrading, upwork — not independently
triaged per-finding against which of the 6 call sites produced each one;
the fix addresses the mechanism, and closure of individual fingerprints
should happen via
pulse_close_stale.pyonce this is live and a fresh run reproduces (or fails to reproduce) each one.
-
go build ./...clean. - New tests:
plat074_changelog_added_deleted_steps_test.go— 5 tests covering theDeletedSteps/AddedStepsfallback (including that an explicit snapshot still wins over both, and that a pure delete'safter_refand a pure add'sbefore_refcorrectly stay at the placeholder since nothing real exists on that side), plus one exercising themigrate_message_sequence_code_itemssnapshot shape end-to-end throughlogPlanChange. - Full baseline (
go test ./cmd/server/... ./pkg/orchestrator/agents/workflow/step_based_workflow/...) still shows exactly 22 pre-existing failures (19 guidance, 1 virtual-tools, 2 step_based_workflow) — no new failures. -
Not yet reverified live — requires a server restart (these are
go run-loaded via thereplacedirective) and a workflow run that exercisesdelete_plan_steps/an adder tool/a route tool/the migration tool before any of the 9 Cluster C findings can be closed withpulse_close_stale.py.
- A
delete_plan_steps,add_*_step,add_todo_task_route,update_todo_task_route, ormigrate_message_sequence_code_itemscall produces a changelog entry whosebefore_ref/after_refreflect real content, not thesha256("[]")placeholder, whenever real before/after content exists. -
delete_todo_task_routeis covered transitively by the samecompletePlanChangelogEntryfallback that fixesdelete_plan_steps.
Auto-synced from docs/ on main. Edit there, not here.