be post recursion into an ALREADY-ATTACHED sub tries to CREATE its synth dot-branch (PUTDUP) instead of FF — aborts the parent commit
A be post recursing into a submodule that is ALREADY on its synthetic dot-branch ?/<sub>/.<parent>/<pbranch> issues a CREATE (be put ?<synth>) for that branch — which already exists — and fails PUTDUP → BEDOGEXIT, aborting the whole parent commit. Per Submodules §"Committing detached subs" the create must be idempotent: "later posts fast-forward it" (exists → FF/attach, never re-create). SUBS-035 fixed the POSTDET / detached-commit half; this is the DISTINCT create-vs-FF half its hermetic test never exercised (there the sub was freshly created, not already attached). This is the ORIGINAL-session PUTDUP, still unfixed. Hit live 2026-06-26 committing COMMIT-004; worked around with be post --nosub. Will also block the journal-level gitlink bump (journal → be → be/test). Method: Issues.
~/journal/be, be post recursed post test into be/test (clean,
attached at c47f767f on ?/beagle-ext-tests/.beagle-ext/.journal) → sniff: put: ?/beagle-ext-tests/.beagle-ext/.journal already exists / PUTDUP / BEDOGEXIT / "aborting parent commit — sub recursion failed (worst=BEDOGEXIT)".
CREATE rather than an FF/no-op. So be post on a sub already at its synth tip cannot be driven by the parent.
ATTACHED and clean; the bug is the non-idempotent synth-branch CREATE.
be post --nosub (skips recursion; the
gitlink bump was already correctly staged as put test#c47f767f).
be post recursing into a sub already on ?/<sub>/.<parent>/<pbranch>
FF/attaches (or no-ops if already at tip), NEVER PUTDUP. Per Submodules: first post creates the branch, later posts fast-forward it.
parent still bumps the gitlink.
absent → create. Reuse SUBSDirty / the SUBS-027b R2 emit; ragel/REFS only.
(clean sub no-op), or SUBS-027b (R2). Repro-first (CLAUDE §17).
PUTDUP — likely
sniff/PUT.c (the put ?<synth> arm) and/or beagle/SUBS.c bepost_bump_sub / the recurse cb / bepost_synth_child_uri.
bepost_anchor_sub (the R2 anchor): it issued
bare be put ?<synth> → PUTCreateBranch (create-ONLY, errs PUTDUP if present). FIX: read the sub tip (R4) via SNIFFSubReadTip and issue be put ?<synth>#<tip>, routing through PUTSetBranch (create-or-repoint) — idempotent: absent → create, present → re-point/FF to the tip. The forward-only bump gate (bepost_bump_sub returns OK only on a real advance) already guarantees the tip is forward.
be put ?<branch> keeps its strict create-only PUTDUP (DIS-020);
only the internal anchor switched to the tip-form. No PUTCreateBranch change.
be post →
assert FF, NO PUTDUP, the parent commit completes and the gitlink bumps. test/post/55-sub-attached-reanchor-idempotent (RED bare-synth, GREEN tip-form).
beagle/BE.cli.c bepost_anchor_sub → ?<synth>#<tip> (PUTSetBranch).
still pass; ctest 439/439 (WITH_SSH=ON, WITH_JS=OFF), 0 fail.
be post (the journal-level gitlink bump uses it);
--nosub is no longer needed once this lands.
ae64dc7f ("SUBS-036 idempotent sub synth-branch anchor", beagle trunk 26Jun); test/post/55-sub-attached-reanchor-idempotent registered in test/CMakeLists.txt. CLOSED (audit 2026-07-07).bepost_anchor_sub
(beagle/BE.cli.c:3025) anchored the SUBS-027b R2 keep-alive with bare be put ?<synth>, which dispatches (sniff/SNIFF.exe.c:1156) to PUTCreateBranch (sniff/PUT.c:1220) — a CREATE-ONLY writer that returns PUTDUP when the dot-branch already exists. On a LATER advance of an already-attached sub the branch IS present → PUTDUP → BEDOGEXIT, aborting the parent commit. SUBS-035/post-54 only exercised the FIRST anchor (branch absent), never the re-anchor; this is that create-vs-FF half.
beagle/BE.cli.c bepost_anchor_sub (~3025) — read the sub
tip (R4) via SNIFFSubReadTip and issue be put ?<synth>#<tip> instead of bare ?<synth>. The #<tip> form routes through PUTSetBranch (create-or-repoint), idempotent: absent → create, present → FF to the tip. SUBSNOSEC (no tip yet) → no-op. ~16 LoC, single function; no other file changed in beagle/sniff.
test/post/55-sub-attached-reanchor-idempotent (SSH-gated, registered in
test/CMakeLists.txt). RED pre-fix: sniff: put: ?/sub/.parent already exists / PUTDUP / BEDOGEXIT / "aborting parent commit". GREEN post-fix: round-1 CREATEs the synth branch, round-2 FFs it to the new tip, parent commit completes, gitlink bumps.
SUBS-006 (post/29), SUBS-027b (post/49/50/51/52) all green.
beagle/BE.cli.c,
test/post/55-sub-attached-reanchor-idempotent/run.sh (new), test/CMakeLists.txt (register the case). STOPPED before committing.