Files
lda-wf/docs/historical/research/2026-09-06-fork-gather
T

Fork/gather research evidence — 2026-09-06

These are historical research inputs, not approved specifications or production code. The current contract is the draft fork/gather spec. The ADR records the architectural direction. Both remain proposed.

Provenance

Eight files were copied, not moved, from random shit/research-chatgpt/. Every copy was checked against its original with SHA-256. The redundant ZIP, older citation-less exports, and other unrelated research were not imported.

Archived file under imported/ Original relative path
round-2-report.md deep-research-report060926 copy 3.md
round-2-citations.md deep-research-report060926 copy 2.md
audit-1.md research-audit060926.md
audit-2.md research-audit060926-002.md

The remaining four files retain their original basenames and were copied from the research-audit060926-002/ subdirectory:

  • fork_gather_reference.py
  • test_fork_gather_reference.py
  • README_fork_gather_reference.md
  • verification_test_results.txt

The report's inline citation numbers can be matched to the citations export. Uploaded-file citations concern an older repository snapshot, not necessarily current code. Original sandbox: download links are inert historical links; the actual supplied files are alongside the reports here.

Keep imported/ byte-identical to these source snapshots. Its local Markdown lint configuration disables style rules solely to preserve the imported text. This README and the live documents use normal lint rules. Future experiments belong outside imported/; do not silently repair the evidence.

Independent verification and limitations

On 2026-09-06, the 25 supplied tests passed locally. Reproduce from the repo root:

Push-Location 'docs/historical/research/2026-09-06-fork-gather/imported'
try { python -B -m unittest -v test_fork_gather_reference.py }
finally { Pop-Location }

Audit 2 explicitly labels its implementation a reconstruction: the scratch code claimed in audit 1 was not retained. The captured output is the author's record; the local test run is independent verification of the supplied code. Neither is a test of wf_core.

The reference uses a single owner, append-only example contributions, deep-copied transitions, and trusted in-process pickle snapshots. It does not establish production codec validation, durable storage atomicity, arbitrary reducers, external-effect idempotency, foreach, subgraphs, or cancellation. Never load an untrusted pickle checkpoint.

Known defects reproduced locally

Repeated write execution collides

w: append X -> pick
pick.again -> w
pick.done  -> END

SymbolicAnalyzer accepts this graph. Execute w, choose again, then execute w using the same token. _write() raises RuntimeError: duplicate semantic contribution w@T0 because its ID uses only node and token identity, not the execution occurrence. This is a valid loop that the simulator must eventually execute correctly.

Repeated gather occurrence is not rejected by analysis

g.a -> h.only -> pick
pick.again -> h.only
pick.done  -> final.left
g.b        -> final.right
final      -> END

The supplied model permits one-port gathers. Analysis accepts the graph with both gather anchors set to g. Execute g, fire h, choose again, then fire h again: _fire_gather_impl() raises RuntimeError: duplicate merged lineage merge:h@g@T0. The analyzer tracks current tokens but not past firings under an unresolved anchor. The proposed one-fire-per-occurrence contract requires validation to reject this case. Banning one-port gathers would not prove the general rule.

Both reproductions were executed independently during review. They are not included in the unchanged imported 25-test suite. Their regression requirements and the next verification gates live in the draft spec, not in this archive.