Skip to content

[Bug]: explore-todo-result-node-linkage-smoke fails on main — the archive section drops a token the readback still returns #8134

Open

Description

@Weimr2627

Impact / 影响

examples/explore-todo-result-node-linkage-smoke.py fails deterministically on current main, so the nightly Full Public Smokes sweep is red for this smoke and contributors lose a green signal for the Explore→archive linkage guarantee it exists to protect (#1819).

The failure is a self-contradiction inside one run: the same Todo keeps its explore_result_node_refs through the readback path, but the shipped smoke also requires the token to still be rendered inline in the display Markdown after todo archive-completed, and that inline repetition is gone.

Preflight

  • I searched existing issues and discussions for this behavior.
  • This report is not an unpatched security vulnerability.
  • The report and attachments contain no credentials or private/internal material.

Issue origin

Reproduced in a real environment (clean source checkout of main, local runner, no model calls).

LoopX version or commit

4d8b79692d13ea17a43d2369d35282b023be311e (current main). The same failure is recorded in the scheduled Full Public Smokes run 41937099939 (shard 3, 2026-11-05T00:00:07Z).

Host or runtime surface

Not host-specific. Python 3.12 / macOS runner; synthetic fixture data only.

LoopX area

Control plane (todos, archive projection).

Problem

check_todo_lifecycle asserts the same linkage token at three points, and they do not agree:

Step Assertion Result
after todo complete explore_result_node_refs == ["node_live", "node_dead"] on the terminal Todo (:156) passes
after todo complete the active state Markdown contains explore_result_node_refs=node_live%2Cnode_dead (:158) passes
after todo archive-completed --max-active-done 0 --execute the archived state Markdown contains explore_result_node_refs=node_live%2Cnode_dead (:172) fails
after todo archive-completed todo list --todo-id <id> still returns archive_state == "archive" and explore_result_node_refs == ["node_live", "node_dead"] (:176-177) passes

The rendered archive section after the drop contains only pointer comments, with no item rows and no refs token:

## Completed Work Archive
<!-- loopx:todo-region-v0 role=archive begin -->
<!-- loopx:todo-section-projection-v0 role=archive provider_revision=sqlite:<digest>:4 records_sha256=<digest> -->
<!-- loopx:todo-archive-pointer authority=sqlite_v0 archived_count=1 active_done_omitted=0 query="loopx todo list --goal-id <goal-id> --include-archived" -->
<!-- loopx:todo-archive-pointer authority=sqlite_v0 archived_count=1 active_done_omitted=0 goal_id=explore-todo-linkage-smoke query="loopx todo list --goal-id explore-todo-linkage-smoke --include-archived" -->
<!-- loopx:todo-region-v0 role=archive end -->

So the authority readback is intact (the archived record and its explore_result_node_refs are still readable through --include-archived), while the display projection no longer repeats the token inline. The shipped smoke still requires the inline form. One of the two is wrong, and I cannot decide which from source inspection alone, so I am reporting the gap instead of changing either side.

Minimal reproduction

uv sync --extra test
PYTHONUTF8=1 python examples/explore-todo-result-node-linkage-smoke.py

Observed twice in a row on a clean checkout, both times at the same line:

File "examples/explore-todo-result-node-linkage-smoke.py", line 172, in check_todo_lifecycle
    assert "explore_result_node_refs=node_live%2Cnode_dead" in archived, archived
AssertionError

Expected behavior

One owned answer, recorded where the archive projection contract lives:

  • if archived items are represented by a pointer plus --include-archived readback (which is what the projection code now does, and what :177 already proves), then the shipped smoke should assert the pointer and the readback instead of inline repetition, and the Explore linkage guarantee should be stated in terms of the readback path; or
  • if the inline archive record is still the guarantee, the archive section lost it and this is a projection regression.

Actual behavior

The two surfaces disagree, and the shipped public smoke fails on main.

Existing related work / what is not duplicated here

Scope of this claim

One smoke, two local reruns plus one hosted nightly record. I am not claiming the whole nightly fleet's state, not claiming a data-loss or authority defect, and not claiming which side should change.

中文补充:归档条目现在只留指针,正文里不再重复 explore_result_node_refs;但用 --include-archived 回读仍能拿到完整记录。随仓 smoke 却仍在断言"正文里要看得见"。权威数据没丢,两边口径不一致,所以先报出来请维护者定夺,而不是我自己改一侧。

Activity

  1. Weimr2627 commented on Nov 5, 2026

    @Weimr2627
    ContributorAuthor

    Follow-up: onset pinned, consumer-side PR opened

    The bisect closes the question this issue left open: the drop is an intentional sqlite_v0 change that landed without this consumer.

    Reading Result
    nightly 41356265689 (2026-11-01T22:16:06Z) smoke absent from the failed log (1,097,104 bytes retrieved, 0 mentions) — green
    nightly 41557935873 (2026-11-03T01:10:15Z) and 41740364791 smoke appears 11 times in each — red
    commits touching machine_section_projection.py in that window all from #7834 (+377/-5), which added the pointer-capped archive rows
    commits touching examples/explore-todo-result-node-linkage-smoke.py in that window none

    Positive control: the file arm still renders the archived row inline and passes its inline assertion on main, so the omission is sqlite_v0-specific, not a general archive defect — consistent with the readback at :193-194 returning explore_result_node_refs == ["node_live", "node_dead"].

    I opened #8136 to reconcile the shipped smoke on the consumer side only: the file arm keeps the inline assertion, the sqlite arm asserts the emitted pointer (archived_count=1 plus the goal-scoped --include-archived query). Each new guard was poisoned once and all four poisons were caught. I am deliberately leaving this issue open instead of Closes-ing it: if maintainers rule that sqlite_v0 should still render archived rows inline, that is a projection bug and the PR should be reverted rather than merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions