Skip to content

Faithful cluster DLM registration — Layer 1: MOUNT holds the standing volume lock (vms-3eb/25e) - #1035

Draft
baron-3dl wants to merge 28 commits into
mainfrom
feat/coord-rebuild-completion
Draft

Faithful cluster DLM registration — Layer 1: MOUNT holds the standing volume lock (vms-3eb/25e)#1035
baron-3dl wants to merge 28 commits into
mainfrom
feat/coord-rebuild-completion

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

Faithful cluster DLM registration (WIP, building through layers)

Reaching CN=3 honestly requires OVMX to register the real standing system locks a faithful VMS node holds — proven necessary by the lab (a content-free completion destabilizes the cluster). This PR builds that, layer by layer, each tested.

Layer 1 (vms-25e) — the executive genuinely holds the standing volume lock ✅ code + test

A real VMS MOUNT holds the per-volume lock from $MOUNT to $DISMOUNT; OVMX previously held only the transient XQP sync lock. Now:

  • acp_vol_resnam generalized to _kind (s/v/a); vms_lock_acp_vol_standing() takes an NL lock on F11B$v<label>, held for the mount life (presence marker, not serialization — never blocks the XQP or another node).
  • Taken best-effort at mount publish (never gates the mount, INV-6 honest-omission), released at $DISMOUNT.
  • Test (test_syssvc_acp_dlm): after $MOUNT, GET_RESMASTER on the reconstructed F11B$v<label> reports found + n_granted ≥ 1 — a read of real lock state, no fabrication.

Next

  • Layer 2 (vms-1f4) — clean executive accessor for scsd to enumerate the node's standing locks.
  • Layer 3 (vms-74f) — scsd registers the real handles to the coordinator via op-01→grant→op-04→op-03 (the content-free op-04/op-03 builders on this branch get real resnames+handles).

Draft until all layers land + the lab re-fire confirms CN 2→3. INV-6 throughout: only real locks the executive genuinely holds.

🤖 Generated with Claude Code

baron-3dl and others added 28 commits September 1, 2026 23:41
…or (vms-3eb)

The coordinator counts a joiner once it COMPLETES the light-mode DLM
directory-rebuild handshake on the coordinator's VMS$VAXcluster VC. OVMX
reaches admission (receives the coordinator's op-06 membership burst,
CSB member bit sets) and holds full connectivity, but stays BRK_NON /
CLUSTER_NODES=2 because it drives ~zero cat-02 rebuild to the coordinator:
it sends only the op-0d self-registration and never CLOSES that rebuild
transaction the way a real joiner does (op-01 registrations → op-04 →
op-03 COMMIT).

This adds the completion OVMX was missing. On receiving the coordinator's
op-06 admission burst, OVMX drives the op-04 completion + op-03 COMMIT to
the coordinator (one-shot per epoch, re-armed on each new transition open),
closing the directory-rebuild transaction its self-registration opened.

HONEST BY CONSTRUCTION (INV-6): OVMX holds no persistent cluster lock (its
DLM takes only transient RMS/ACP locks — scsd.c:1631 "OVMX holds no
locks... revisit when it has a real lock manager to answer FROM"). So the
completion registers NOTHING HELD — the builders zero the resource name
(body[48:]) and the per-lock handle words (body[20:28]) and keep mode NL
(body[30]=0): the honest "my rebuild contribution is complete, I hold
nothing" signal. It fabricates no lock state and names no resource OVMX
does not own. Frame structure reproduces the JOIN→COORD op-04/op-03
specimens on db20-b's validated member-body layout (Rule 8).

This is the minimal A/B test for the CN=3 blocker: if the coordinator
counts OVMX off a content-free completion, completion alone suffices; if
not, the standing system-lock set is genuinely required — an executive
completeness question (make OVMX's mount/XQP take real F11B$/MOU$/LNM$
locks), escalated separately.

test_scs_member: new test_dlm_completion_holds_nothing pins the honesty
guardrail (resname + handles + mode all zeroed). SEND SITE census updated
(cm_send_dlm_completion). Both files -fsyntax-only clean; member test + census green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
… life (vms-25e) [Layer 1, test pending]

Layer 1 of faithful cluster DLM registration (vms-3eb). A real VMS MOUNT holds
the per-volume lock from $MOUNT to $DISMOUNT; that standing lock is the
cluster-wide "this node has this volume mounted" marker the connection manager
re-registers to the coordinator during a directory rebuild. OVMX's executive
previously held only the TRANSIENT XQP sync lock (F11B$s, taken per on-disk
write and dropped) — nothing standing to register. This adds the standing one:

- Generalize acp_vol_resnam -> acp_vol_resnam_kind(vol, kind, ...) so the
  per-volume resource name is built for any sub-lock ('s' sync, 'v' volume,
  'a' allocation); acp_vol_resnam stays a 's' wrapper (call sites unchanged).
- vms_lock_acp_vol_standing() — an NL-mode $ENQ on F11B$v<label>, held (not
  dropped) for the mount life. NL asserts PRESENCE not exclusion: different
  resource from the XQP sync lock, holds nothing exclusive, so it never blocks
  the XQP, another writer, or another node — deadlock-free, cluster-safe.
- Taken at mount publish (best-effort, AFTER dropping the table lock; a DLM-less
  node just leaves vol_lkid 0 — the standing lock is a cluster facility, NEVER a
  gate on the mount, INV-6 honest-omission), released at $DISMOUNT (rundown is
  the backstop). vol_lkid stored on the executive-global volume row.

INV-6: this is a REAL lock the executive genuinely holds on a REAL mounted
volume — no fabrication. Mirrors the validated vms_lock_acp_vol_ex pattern
(only the mode differs, NL vs EX).

NOT DONE: vms-25e's done-condition needs the QEMU test (mount -> lock held via
GETLKI on F11B$v<label>; $DISMOUNT -> released). Next commit. Layers 2 (scsd
enumeration accessor, vms-1f4) + 3 (scsd registration FSM, vms-74f) follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…OUNT (vms-25e)

Layer 1's done-condition (vms-3eb): assert the executive genuinely holds the
standing volume lock a faithful MOUNT holds for the mount life. After $MOUNT of
the ODS-2 VDA0:, read the mounted volume's label via GETVOL (the same
vol->volname the executive built the resource name from -- getvol copies it
verbatim, so the reconstruction is byte-exact, trailing spaces and all), form
the F11B$v<label> resource name, and assert GET_RESMASTER reports it FOUND with
n_granted >= 1.

This is a READ of real lock-manager state (GET_RESMASTER counts all granted
locks including the local NL standing lock, unlike DLM_GET_GRANTED which filters
to remote-held) -- never a fabricated grant (INV-6). It holds whether the lock
was taken by PID 1 at the boot mount or by the test's idempotent re-mount; the
resource name matches either way (both from vol->volname). Skips cleanly when
/dev/vms is absent, like the rest of this executive-resident test.

Layer 1 (executive holds the standing lock, ee4d1f3) is now code + test. The
release-at-$DISMOUNT path is the symmetric dismount code; VDA0: is the live
system disk and is not dismounted in-test. Next: Layer 2 (scsd enumeration
accessor, vms-1f4) + Layer 3 (scsd registration FSM, vms-74f).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…ader (vms-25e)

The Layer 1 change (ee4d1f3) declared vms_lock_acp_vol_standing only in
src/kernel/vms_internal.h (Linux). kernel-core's vmsfs_acp.c resolves
"vms_internal.h" per build, so the NetBSD/vax cross-compile hit
  vmsfs_acp.c:724: implicit declaration of 'vms_lock_acp_vol_standing'
(-Werror). Mirror the declaration into src/kernel-netbsd/vms_internal.h next to
vms_lock_acp_vol_ex, exactly as #928 requires for kernel-core lock ops. Linux
build + the QEMU standing-lock test were already green; this restores the VAX
arch leg.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…em locks (vms-1f4) [Layer 2]

Layer 2 of faithful cluster DLM registration (vms-3eb): the clean seam between
the F11 layer that HOLDS the standing volume lock (Layer 1, vms-25e) and the
cluster layer (scsd) that REGISTERS it to the coordinator. A new read-only ioctl
returns this node's standing cluster-registrable locks -- today one entry per
mounted volume holding its F11B$v<label> lock: {resname, local lkid, mode}. The
lkid is exactly the op-0x01 requester handle scsd puts on the wire (Layer 3).

INV-6: a READ of REAL lock state. count is the number of standing locks the
executive genuinely holds; a volume whose best-effort acquire failed
(vol_lkid == 0) contributes nothing; never a fabricated lock.

Wired across all nine places a new /dev/vms ioctl touches (the "new-ioctl -> N
places" trap), each verified consistent:
- struct + ioctl def (NR 0x3c, next free after the 0x30-0x3b DLM/cluster group --
  0x39 was already CLUSTER_MEMBER_SET, caught before it collided) + size/encoding
  asserts, in BOTH src/kernel/vms_ioctl.h and src/kernel-netbsd/vms_lock_nb.h,
  byte-identical (656 bytes);
- handler vms_ioctl_dlm_enum_standing() in kernel-core/vmsfs_acp.c (walks the
  executive-global mounted-volume table under vms_acp_vol_lock, copyout outside
  the lock); handler decl in BOTH vms_internal.h (#928);
- dispatch in kernel/vms_module.c and both switches of kernel-netbsd/vms_netbsd.c;
- kif wrapper vms_kif_dlm_enum_standing() decl + impl (libvmssys), fail-honest.

Test (test_syssvc_acp_dlm): after $MOUNT, DLM_ENUM_STANDING surfaces the
F11B$v<label> lock with a real (nonzero) handle -- the (resname, lkid) pair scsd
will register. LCK_K_NLMODE + the struct are reachable in both the Linux and
NetBSD builds of the shared TU (verified, not assumed). Layer 3 (vms-74f) wires
scsd to register these to the coordinator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…vms-1f4)

Layer 2 (2d2f66b) added the enum-standing kif wrapper, whose header touch
re-armed the VMS-native toolchain legs (Layer 1's kernel-core-only diff had let
the path filter skip them). Two regressions surfaced, both here, both fixed:

1. kif_caller_census (INV-6 gate, "Build & Test" ctest): vms_kif_dlm_enum_standing
   had no product caller (only the QEMU test) and no unwired marker. Its product
   caller is Layer 3 (vms-74f, scsd registration). Add the OVMX-UNWIRED: marker on
   the decl, matching the existing pattern -- to be REMOVED when Layer 3 wires it.

2. LIBVMSSYS$SHR.EXE link (every *VMS-native Migration leg): the wrapper ended
   `*out = args;`, a 656-byte struct assignment GCC lowers to a libc memcpy() the
   freestanding libvmssys shareable cannot resolve (DECC$SHR exports no memcpy,
   vms-61f). Rewrite to write STRAIGHT into *out (no local + no struct copy) --
   consistent with how the file already avoids libc via the vms_memset shim. Add
   an SS$_BADPARAM null-guard, matching vms_kif_get_resmaster.

Census gate re-run locally: PASS. Main is green on all these legs (33550492582),
confirming this was my Layer-2 regression, not pre-existing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
… coordinator (vms-74f)

Layer 3 (faithful cluster DLM registration, vms-3eb) frame builder #1:
scs_member_build_dlm_reg_enq -- the cat 0x02 op 0x01 ENQ that registers one of
OVMX's REAL standing system locks (the F11B$v<label> volume lock a MOUNT holds,
Layer 1) to the COORDINATOR during a directory rebuild.

Unlike db20-b's NL-only presence ENQ (which zeroed the id fields because it held
nothing), this carries OVMX's OWN real values, at the reference-confirmed offsets
(conductor trace of F11B$aSYSDSK1 op-01):
  - req_lkid @ body[4:8]  = OVMX's real local lock handle (from the vms-1f4
    DLM_ENUM_STANDING accessor -- a lock the executive genuinely holds);
  - mst_csid @ body[20:24] = the real coordinator's csid;
  - resname @ body[48], NL mode @ body[30] (the mode OVMX genuinely holds).
Built on db20-b's VALIDATED frame (VAX1 granted 48/48). INV-6: only OVMX's own
real values; the ungrounded per-lock lock-mgmt fields (body[24:30]) stay ZERO --
VAX3's kernel-assigned handles are un-replayable and inventing them would be the
fabrication trap inverted (conductor's principle -- the coordinator keys on the
resource + requester identity, not a foreign handle match).

test_scs_member: new test_dlm_reg_enq_carries_real_values pins req_lkid@[4:8],
mst_csid@[20:24], cat/op, NL mode, resname, and the ungrounded-fields-zero
guarantee. Member suite ALL PASSED.

Next: op-04/op-03 real-handle builders + the await-grant receive FSM (scsd calls
the accessor, sends op-01 per lock, and on the coord's cat-82 op-01 grant ARRIVAL
-- a pure trigger, no value extracted -- sends op-04 -> op-03 with OVMX's own
handles).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…fire (vms-74f)

Layer 3 frame builders #2/#3 + the safe scsd checkpoint before the FSM:

- scs_member_build_dlm_op04 / _commit now take OVMX's OWN real per-lock handle
  (lkid) and write it at body[20:24] -- the handle the executive DLM holds for the
  lock (from the vms-1f4 accessor). Per the conductor's handle-chain trace, op-04
  and op-03 carry the JOINER's own node-local handle, NEVER VAX3's un-replayable
  kernel bytes nor the coordinator's granted mst_lkid; the ungrounded second handle
  word @[24:28] stays ZERO (INV-6 -- don't invent). lkid==0 reproduces the old
  content-free frame (null case). test_scs_member pins lkid@[20:24], the zeroed
  second word, NL mode, and no-resname; suite ALL PASSED.

- cm_send_dlm_completion is now lkid-aware (function-pointer signature updated).

- The OPT-A content-free completion FIRE (post-op-06) is DISABLED: it destabilized
  the cluster (op-03 with no real op-01 = dangling transaction -> 2/2 reformations,
  lab-proven). Firing nothing keeps the branch safe until Layer 3's registration
  FSM lands. That FSM (next commit): post-op-06 enumerate the standing locks, send
  op-01 per lock to the coordinator, and on the coordinator's cat-82 op-01 grant
  arrival send op-04 -> op-03 with OVMX's real handle.

scsd.c -fsyntax-only clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
… complete

The receive-driven FSM that makes a capless OVMX node register its REAL standing
system locks to the coordinator and complete the rebuild transaction -- the honest
CN=3 path, replacing OPT-A's content-free completion that reformed the cluster.

- scsd_enum_standing_locks(): reads the node's standing cluster-registrable locks
  from the executive over /dev/vms (VMS_IOCTL_DLM_ENUM_STANDING, Layer 2) by direct
  ioctl (scsd is glibc, not the freestanding vms_kif client). Fail-honest: 0 on any
  failure; registers ONLY what the executive genuinely reports it holds (INV-6).
  SCSD_UNIT_TEST stub returns 0 (no /dev/vms in the wire seam).
- cm_dlm_frame_common(): factors the per-send SCS/SYSAP envelope.
- cm_send_dlm_registration(): post-op-06, one cat-02 op-01 ENQ per standing lock
  carrying OVMX's OWN real handle (req_lkid) + real resname; mst_csid=0 (resolve --
  OVMX lacks the coord's full csid, and 0 was granted for db20-b; INV-6 no-invent).
- cm_send_dlm_completion(): rewritten per-lock -- op-04 + op-03 COMMIT carrying
  OVMX's own real handle, fired on the coordinator's cat-82 op-01 GRANT arrival.
- Grant-detect (scsd_sysap_msg_input): mv.is_response && cat DLM && op 0x01 from the
  coordinator, gated on dlm_reg_sent, one-shot -- a PURE trigger (no handle parsed;
  op-04/op-03 carry OVMX's own). The await-grant gate is the OPT-A insurance.
- dlm_reg_sent one-shot + epoch re-arm; SEND SITE census updated.

FSM shape (op-01 -> await grant -> op-04 -> op-03, OVMX's own handles throughout)
grounded via the conductor's handle-chain trace. Both build paths -fsyntax-only
clean; send-site census 123/0; member builder suite green. The lab is the final
validator: fresh vaxlab-2 re-fire grades the 3 signals (real registration fires /
reformation GONE / BRK_NON -> counted + CN 2->3). Known lab-reject suspects (fill
honestly if VAX2 chokes): op-04's 2nd handle word @[24:28] (zeroed) and mst_csid=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…t gate (vms-74f)

The Layer-3 FSM (98562d2) tripped the Rule 9 runtime_target gate (tests/
integration/test_runtime_target.sh check 3): it greps for absence-words within 24
chars of "/dev/vms" as a "silent userspace fallback" tell, EXCLUDING lines that
start with a comment marker. My SCSD_UNIT_TEST stub's TRAILING comment on a code
line -- `return 0;   /* ... no /dev/vms here */` -- is not a comment-leading line,
so the "no /dev/vms" phrase was flagged (a phantom; the code fails honest, it does
not fall back). Reword the trailing comment to drop the /dev/vms-absence phrasing.

No behaviour change -- the stub still returns 0 (executive-resident; scsd registers
only what the executive genuinely reports). Gate grep now CLEAN across src.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
Run 9c: the coordinator DROPS a skeletal op-01 (req_lkid + resname, rest
zero); a granted reference ENQ carries a full per-lock record. Fill it
entirely from OVMX's OWN genuine lock state (INV-6, no fabrication):

  scs_member_build_dlm_reg_enq now takes a scs_dlm_reg_fields struct and
  writes req_lkid@[4:8], dir_csid@[20:24], lock_id@[24:28], flags@[28:30],
  mode@[30], lockmgmt@[32:36]; req_csid@[16:20] stays 0 (846/846 ref).

  cm_send_dlm_registration sources dir_csid + n_granted per lock from the
  executive via a new scsd_res_dir_info() (GET_RESMASTER over /dev/vms);
  req_lkid/lock_id from the DLM_ENUM_STANDING accessor; mode NL.

body[20:24]=dir_csid is OVMX's OWN encoding -- the measured operator-scope
decider on re-fire: grant off it => honest CN=3, no cluster-DLM interop;
drop => interop scope (SCS$DIRECTORY-agreed id). flags/lockmgmt are the
structural lock-mgmt words, flagged secondary iterate-suspects.

Self-test: member suite ALL PASSED, send-site census 123/0, scsd.c
syntax-clean both arch paths, Rule-9 runtime-target gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…mpare (vms-74f)

The cat-0x82 op-01 GRANT trigger that fires cm_send_dlm_completion tested
`mv.is_response && mv.category == SCS_MEMBER_CAT_DLM`. scs_member_parse stores
the RAW category byte (body[8]), so a response carries the 0x80 bit IN
mv.category (0x82) and mv.is_response is derived from it -- making the
condition UNSATISFIABLE (0x82 != 0x02). The grant was never detected, so op-04/
op-03 never fired: a GRANT would dangle indistinguishably from a DROP, making
the milestone re-fire uninterpretable. Mask with & 0x7f, matching the parser's
own convention (scs_member_parse lines 482/490) and every other DLM-response
site.

Regression: test_dlm_grant_response_needs_masking asserts a cat-82 op-01 frame
parses to is_response=1 with raw category 0x82 != CAT_DLM but (category & 0x7f)
== CAT_DLM -- locking the exact trap.

Self-test: member suite ALL PASSED, send-site census 123/0, scsd.c syntax-clean
both arch paths, Rule-9 gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…ted membership (vms-655)

The SCSD-I-XITDONE self-report claimed "cluster membership COMMITTED ... OVMX is
now an admitted cluster member" on receipt of the coordinator's op-06 MEMBERSHIP
burst, asserting a 1:1 relationship with the F$GETSYI(CLUSTER_NODES) 2->3 oracle.
The 2026-09-02 re-fire refutes that: op-06 arrived, OVMX drove its DLM
registration, but VAX2 dropped the op-01 (dir_csid gap, vms-655) and CLUSTER_NODES
stayed 2. The 1:1 analysis predates the DLM-registration gate (vms-74f) that op-06
now triggers -- op-06 is NECESSARY but NOT SUFFICIENT for counting.

Reword the log + correct the comment: op-06 is the admission INVITATION that opens
the transition; counted membership requires the DLM registration to COMMIT
cluster-wide (op-01 GRANT -> op-04 -> op-03). Facility tag SCSD-I-XITDONE and the
membership_committed latch are KEPT (lab grep + oracle compat, tests/lab/tools/
abrun.sh keys the tag not the body); only the false "admitted" claim is removed.
Log/comment only -- no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…time (vms-655)

Root cause of the op-01 DROP (measured 2026-09-02): the executive's DLM directory
(dlm_directory_csid) hashes a resource name over vms_local_csid + dlm_member_csids
to pick the master, but both are insmod module params (0444) defaulting to a
cluster-of-one {1} -- a joining node cannot know its SCSSYSTEMID or the members at
insmod (learned only during the SCS join), and STARTUP.EXE loads vms.ko with an
empty param string. So GET_RESMASTER returned dir_csid=1 (the phantom local id),
which does not match the CSID (1028) the cluster knows OVMX by, and VAX2 dropped
the registration. scsd's op-01 field was faithful -- it reported a mis-configured
executive.

Fix: the live connection-manager feed the static-vector comment in vms_lock.c
already anticipates. New VMS_IOCTL_DLM_DIRECTORY_SET (NR 0x3d, DLM family) pushes
{local_csid, member CSIDs} into the directory; the handler (vms_lock.c) mirrors
DLM_MEMBER_DEPART's locking + directory-cache invalidation and clears the runtime
departed-set (fresh membership). scsd_push_dlm_directory() sources local from
resolve_scssystemid() (=1028) and members from peer_node_number() per live peer
(=each peer's SCSSYSTEMID = its DLM csid, as peer_by_csid reads it), and fires in
the op-06 admission handler BEFORE cm_send_dlm_registration -- so GET_RESMASTER
resolves over the real {1025,1026,1028} set and the op-01 carries the master VAX2
agrees with. Confirmed by wire (conductor): this lab is CSID==SCSSYSTEMID, raw ids,
no 0x2060 form.

INV-6: local is OVMX's resolved SCSSYSTEMID, members are CSIDs the CM actually
sees -- never fabricated; a malformed vector is rejected (SS$_BADPARAM).

Full cascade: vms_ioctl.h (struct + sizeof/encoding asserts, 0xC04C563D),
vms_module.c dispatch, vms_internal.h (Linux+NetBSD prototypes), vms_lock_nb.h
(struct + sizeof assert), vms_netbsd.c (outer group + inner switch), and the
required vms_kif_dlm_directory_set wrapper (OVMX-UNWIRED; kif caller census).

Self-test: member suite ALL PASSED, send-site census 123/0, kif caller census
PASS, scsd.c syntax-clean both arch paths, Rule-9 gate 31/0 + absence scan clean,
NetBSD struct sizeof 76.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…ory hypothesis (vms-655)

Revert 90b3bbb (VMS_IOCTL_DLM_DIRECTORY_SET + scsd_push_dlm_directory + the
GET_RESMASTER->dir_csid wiring) and set the op-01 dir_csid to a hard 0. The lab
disproved "OVMX computes the directory": 90b3bbb armed correctly (op-01 carried
dir_csid=0x00010003=OVMX) but BROKE the cluster (CLUSTER_NODES 2->1, VAX2->BRK_NON
~4s after OVMX's op-01) because OVMX asserted ITSELF as master of F11B$vOVMXSYS.

Root reason it cannot work: the executive's dlm_directory_csid() uses exec_jhash
(vms_lock.c:527), which is explicitly NOT VMS's directory hash (unpublished, Rule
8). Any master OVMX computes is uncorrelated with VMS's choice -> directory
conflict -> reformation. Feeding real cluster CSIDs doesn't help: right values,
wrong SELECTION.

Measured-correct behavior (conductor's ref.pcap + db20-b grant decode):
 - A joiner NEVER self-masters mid-transition; it registers each resource to a
   member, which masters it. The GRANT carries no master field -- the master is
   IMPLICIT (the granting node).
 - db20-b PROVED a dir_csid=0 op-01 is GRANTED 48/48. It was granted-but-
   insufficient only because it carried ZERO handles -- NOT wrong target (the
   reference registers more to the non-coordinator than the coordinator).

So: op-01 carries OVMX's REAL held-lock handles (req_lkid/lock_id from
DLM_ENUM_STANDING, kept from 5772a86) with dir_csid=0 (OVMX asserts no directory
opinion), to the currently-connected member. exec_jhash never runs on this path;
OVMX never self-masters. GET_RESMASTER is read only for the honest n_granted
count. Keeps 4eeddea (grant-detect masking) + 43d33ae (XITDONE honesty).

Self-test: member suite ALL PASSED, send-sites 123/0, kif caller census PASS
(balanced after the DIRECTORY_SET revert), scsd.c both arch paths syntax-clean,
Rule-9 gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…vms-655)

5360671 re-fire: no regression (dir_csid=0 held CN stable at 2) but still
DROPPED. Conductor's byte-diff of the granted db20-b op-01 vs the dropped one
pinned the cause to req_lkid (body[4]): a granted frame encodes OVMX's cluster
node-index in the low 16 bits; 5360671 sent DLM_ENUM_STANDING's raw lkid=1 (low
word 0x0001 -- a wrong node), and a VAX rejects a lock id whose node-index isn't
the sender's.

Fix, honest end-to-end (no hardcode -- a fixed node-index would be a fake CN=3):
 - Learn OVMX's OWN cluster-assigned CSID (0x000X000X) by IDENTITY from the
   cat-01 op-05 per-member membership record {sysid@body[20], csid@body[36]},
   selecting the record whose sysid == our SCSSYSTEMID. Matching on our own
   identity makes it immune to offset drift (a wrong offset never matches -> we
   fail honest, no CSID, rather than fabricate). Stored in ovmx_cluster
   .assigned_csid; low 16 bits = OVMX's node-index. Logged SCSD-I-CSIDLEARN.
   op-05 precedes op-06 in the choreography, so it is known by registration time.
 - req_lkid = (OVMX's real lock handle << 16) | node_index. Real handle, real
   wire-learned node-index -- INV-6 clean.
 - Zero lock_id/flags/lockmgmt to match db20-b's GRANTED baseline exactly (add
   back only if the completion needs them). dir_csid stays 0.
 - Fire the registration ONLY once assigned_csid is learned; otherwise defer
   (SCSD-I-DLMREGDEFER) rather than send a droppable/fabricated op-01.
 - Removed the now-unused scsd_res_dir_info (GET_RESMASTER) helper.

Self-test: member suite ALL PASSED, send-sites 123/0, kif caller census PASS,
scsd.c both arch paths syntax-clean, Rule-9 31/0, absence-word scan clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…ithhold XITGO (vms-655)

DETERMINISTIC finding (2026-09-02, reproduced byte-for-byte across two fresh
clusters): OVMX's unsolicited pre-barrier cat-02 op-01 origination, fired in the
op-06 handler after VAXCLMEMBER but before XITGO, makes the coordinator WITHHOLD
XITGO. Result: 0 XITGO, 0 op-0b/0c barrier frames, the SCS$DIRECTORY selfreg
(gated at barrier step 5) never fires, VAX1 never pushes its directory rebuild,
0 op-0d, 0 grants, CLUSTATE members=1 (unstable). db20-b, which sent NO such
pre-barrier op-01, got XITGO -> 116 barrier frames -> selfreg -> 222 op-0d -> 48
grants.

The honest granted model is the REVERSE of origination: stay quiet after op-06,
let the barrier run, and register REACTIVELY to VAX1's op-0d rebuild requests
(respond-to-rebuild). This removes the perturbing origination fire; the reactive
per-op-0d registration lands next in the CM_RSP_DLM echo path.

This is a single-variable diagnostic: it isolates whether removing the
origination alone restores XITGO -> the barrier -> the selfreg -> op-0d, before
the larger reactive-registration port.

Self-test: scsd.c both arch paths syntax-clean, send-site census 123/0, member
suite ALL PASSED, Rule-9 gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…t drains VAX1 (vms-655)

Step 2 of the port (ff30929 was step 1: remove the XITGO-perturbing origination).
ff30929's re-fire CONFIRMED the chain flips with the origination gone: XITGO
arrives, the op-0c barrier runs (119 frames), the SCS$DIRECTORY selfreg fires
(tag=0x0003), VAX1 pushes 229 op-0d rebuild requests, and VAX1's SDA CSB shows
OVMXJ0 admitted MEMBER (sustained) -- first time ever. But grants=0 because OVMX
echoed the 229 op-0d without registering, so the rebuild never drained.

This ports db20-b's respond-to-rebuild (its line's e08d4f5/5bdbad43, never inherited
by HEAD which forked at 160c5f1): in the CM_RSP_DLM echo path, after echoing a
NON-COORDINATOR member's op-0d record, originate an honest NULL-mode op-01
registration for the resource it SHOWED us:
 - scs_member_build_dlm_nl_enq: the proven granted frame (body[4:6]=txn tag,
   body[6:8]=per-VC counter, mode HARD-PINNED NL, dir_hash honest 0). NOT the
   node-index construction (that was a coincidental misread of 0x0003=DIR_TAG).
 - dlm_op0d_resname reads the resource name from body[48] (SCS_DLM_B_RESNAM);
   dlm_nl_reg_add dedups so each shown resource registers once (cap OVMX_DLM_NL_MAX).
 - cm_send_dlm_nl_register builds via cm_dlm_frame_common + sends CHOKED.
INV-6: OVMX holds NOTHING (NL); it invents nothing -- resource name from the shown
record, member_count is OVMX's own true count, dir_hash omitted (0) not invented.
This is directory-node participation (tracking, not holding) -- the honest role the
rebuild assigns, which VAX1 granted db20-b 48/48 for.

The op-06 origination stays removed; its completion FSM is inert (gated on
dlm_reg_sent, never set now) -- matching db20-b, which fired no completion.

Self-test: scsd.c both arch paths syntax-clean, member suite ALL PASSED, send-site
census 125/0 (cm_send_dlm_nl_register added to the SEND SITE TABLE), Rule-9 gate
31/0, kif caller census PASS.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…est, echoing the grant handle (vms-655)

2f2025a reproduced db20-b's dead-end: 48 reactive registrations, VAX1 granted all
48, clean CSB MEMBER sustained -- but CLUSTER_NODES stayed 2. The conductor's
reference decode showed the counted joiner does what OVMX skipped: after each grant
it drives op-04 completion + op-03 COMMIT. OVMX registered and stopped.

Completing OVMX's OWN granted registration is HONEST and derivable -- distinct from
reciprocal-grant (which the executive-master subagent confirmed is INV-6-forbidden
fabrication: OVMX masters none of these resources). The op-04/op-03 carry
{handle@body[20:28], resname@body[48], constant status 0x00030001@body[12]}
(measured reference layout), and the handle is the one OVMX RECEIVED in the cat-82
op-01 grant (gb[28:36], the master's handle) -- echoed, never synthesized from a
lock DB OVMX lacks. OVMX finishes its own handshake and masters nothing.

 - scs_member_build_dlm_op04_res / _commit_res: the resname-carrying completion
   builders (the existing op04/commit ZERO resname -- wrong for the reactive flow).
 - On inbound cat-82 op-01 from a NON-coordinator member for a resource OVMX
   registered (in dlm_nl_reg), once each (dlm_nl_done dedup): capture the grant's
   handle + resname and send op-04 then op-03 (cm_send_dlm_completion_res).
Honest by construction: if the completion needs a handle NOT in the grant, VAX
won't advance -- OVMX never fabricates one (INV-6). OPT-A's dangling-commit
reformation doesn't apply -- 48 real grants precede these.

Self-test: scsd.c both arch paths syntax-clean, member suite ALL PASSED, send-site
census 127/0 (cm_send_dlm_completion_res added to the SEND SITE TABLE), Rule-9 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…3) — honest, echoing the grant handle (vms-655)"

This reverts commit a554e7c.
…rant inbound op-01 from REAL lock state (vms-16c)

Operator-directed (Julie): stop the wire-imitation (reactive NL-registration +
echoed completion) and build the VMS-faithful DLM. The executive DLM is already
real (vms_lock.c $ENQ/master-on-first-use/grants; VMS_IOCTL_DLM_XNODE real
cross-node grants H4-H11) — the gap was scsd wiring the CM protocol to it.

 - scsd_dlm_master_local: on the op-0d rebuild assignment, OVMX's executive
   genuinely MASTERS the resource (a real vms_lock_resource, master_csid=local via
   master-on-first-use) with a local NL $ENQ — holds nothing, but a later inbound
   ENQ now grants from REAL lock state. Replaces the wire-only "master nothing".
 - cm_dlm_grant_inbound_op01: an inbound cat-02 op-01 lock REQUEST (previously
   SILENCED in cm_response_shape "until OVMX has a real lock manager to answer
   from") is routed to the executive via VMS_IOCTL_DLM_XNODE and GRANTED/QUEUED
   from real state — the same path the OVMX$DLM SYSAP server already uses.

Gated on OVMX_DLM_REAL; flag-off is byte-identical to today (no regression). This
commit lands the real grant PATH + proves it on the wire (SCSD-I-DLMMASTER /
SCSD-I-DLMGRANT). The cat-82 op-01 RESPONSE frame — whose body[20:56] lock-DB
window must be rewritten from real state, NOT echoed — is DEFERRED until the
window is grounded against a reference specimen (Rule 10; a guessed window
regressed the run in a554e7c). Not building imitation, not guessing frame bytes.

vms_lock.c: UNCHANGED — the real DLM engine already exists.

Self-test: scsd.c both arch paths syntax-clean, member suite ALL PASSED, send-site
census 125/0, Rule-9 gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…k state (vms-16c)

Completes the faithful DLM (3e26962 was the foundation): on an inbound cat-02
op-01 that the executive GRANTS from real lock state, OVMX now SENDS the cat-82
op-01 GRANT reply -- the response cm_response_shape had to silence "until OVMX has
a real lock manager to answer from".

scs_member_build_dlm_enq_response builds it from OVMX's REAL master state, measured
against VAX1's OWN accepted grant format (the 2f2025a ENQ->GRANT diff, NOT the
varied reference): body[8]|=0x80 (granted bit), body[12:16]=0x00030001 (granted
status), body[28]=master_lkid for a held mode / 0 for NL (the rebuild grant is NL,
matching VAX1's NL grants), body[32:36]=0x00fe0000 master-state marker; body[0:4]
= OVMX's own SYSAP send/ack counters (scs_member.h: body[0:2]=send-msg#, [2:4]=
ack-msg# -- NOT a lock handle, correcting a recurring misread), req_lkid + resname
echoed. INV-6: every rewritten field is OVMX's real executive lock state, never
fabricated; body[28]=0 for NL carries NO dangling handle (unlike a554e7c's garbage
handles that crumbled because they referenced nothing).

Sent ONLY on a real executive grant (status==1). Gated on OVMX_DLM_REAL; flag-off
byte-identical. vms_lock.c unchanged.

Self-test: scsd.c both arch paths syntax-clean, member suite ALL PASSED, send-site
census 125/0, Rule-9 gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
… default (vms-16c)

Two fixes:

1. ANTI-LARP (operator, Julie): the faithful DLM was gated behind a Linux env var
   (OVMX_DLM_REAL) injected via the kernel cmdline -- so the SHIPPED OVMX ran the
   imitation and only a test-flagged boot did the real thing, and it gated VMS
   behaviour on a Linux env var (itself un-faithful). Gate REMOVED: a normally
   booted SCSD.EXE now masters rebuild-assigned resources for real + grants inbound
   op-01 from real lock state, unconditionally.

2. GROUNDING (the count-gate lead): the flag-on run showed 14,326 SCSD-W-CMUNGROUNDED
   -- OVMX's executive granted the inbound op-01 from real lock state and SENT a
   grant, but the CM layer sent it OUTSIDE the response machinery (a separate
   origination with its own send_seq), so it lacked the request's txn/send_seq
   correlation -> VAX rejected it -> re-requested (a 14K retry storm on 2 real
   system locks LNM$CWLOGICALS + F11B$aSYSDSK1, ~34/s). Now op-01 returns
   CM_RSP_DLM_ENQ from cm_response_shape ("revisit when OVMX has a real lock
   manager" -- it now does), and the build dispatch GRANTS from the executive +
   builds the cat-82 response with the correlated mp (the request's txn echo,
   send_seq, ack), sent through the same grounded machinery as the op-0d echo.
   Only on a real executive grant (status==1); otherwise silent (no fake grant).
   Removed the separate ungrounded send.

vms_lock.c unchanged. Self-test: scsd.c both arch paths syntax-clean, member suite
ALL PASSED, send-site census 125/0, Rule-9 gate 31/0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…ring the mode byte (vms-16c)

The faithful-DLM grant (scs_member_build_dlm_enq_response) wrote the master lock
handle with put_le32(body+28, master_lkid). body[28:30] is the 16-bit handle
field but body[30] is the MODE byte — so for every handle < 0x10000 (all of them;
the storm ran at 0x328) the le32 write pushed the handle's high zero byte into
body[30] and clobbered the granted mode to NL.

VAX asked for PR (0x03) / CR (0x01), read NL (0x00) in the grant, treated the lock
as unsatisfied, and re-requested forever — the measured 34/sec retransmit storm on
LNM$CWLOGICALS + F11B$aSYSDSK1 (SCSD-W-CMUNGROUNDED already 0 after the grounding
fix, but CN still 2). The grant frame the conductor measured (body[28]=0x328,
body[30]=0x00) is exactly what this arithmetic produces.

Write the handle as le16 at body[28:30] and carry the granted mode explicitly at
body[30] (still OVMX's real executive lock state — the mode the master granted;
INV-6 intact). Add test_dlm_enq_grant_honors_mode pinning the regression: a handle
< 0x10000 must not zero the mode byte, and the NL grant carries no dangling handle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…aster handle (vms-16c)

The mode fix (24fbc64) landed on the wire (grant body[30]=0x03 PR confirmed), but
the retransmit storm persisted: OVMX minted a FRESH master lock record for every
re-send of the same op-01, so the handle it returned changed each time
(0x328 -> 0x329 -> 0x32a ...). A cluster member never saw a STABLE granted lock to
correlate, so it re-requested forever (~35/sec on LNM$CWLOGICALS + F11B$aSYSDSK1,
CN stuck at 2).

A real VMS master is idempotent to a retransmit. In vms_lock_dlm_xnode_dispatch's
ENQ case, before running the enqueue core, look up an existing grant keyed by
(req_csid, req_lkid) on the resource; if one is granted at a mode that already
covers the request, return its EXISTING master handle (SS$_NORMAL) instead of
creating a new record. Cross-node only (both ids non-zero); a genuinely new lock
or an up-conversion (existing grant weaker than the request) falls through to the
core unchanged. INV-6: the handle returned names a REAL lock on the resource's
granted queue, never a fabricated one.

Ground-source test (test_syssvc_dlm_xnode 1c, through the real /dev/vms): a
retransmit of the granted ENQ returns the SAME lkid and leaves exactly one grant
on the resource -- no duplicate record. vms.ko builds clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
…cks CLUSTER_NODES 2->3 (vms-16c)

Lab routing (conductor pcap) proved the CN=3 gate is FLOW 1 (OVMX-as-requester),
and it stalls at COMMIT: OVMX sends its 48 own standing-lock op-01 ENQs to VAX1
(1025, the directory node for its file locks), VAX1 grants all 48 back, but OVMX
sends op-04=0 / op-03=0 — cm_send_dlm_completion never fires. The count only
commits once that completion lands (scsd.c XITDONE scope note).

Two-part root cause, both from cm_send_dlm_registration being retired (it perturbed
XITGO) without rewiring the completion:
  1. dlm_reg_sent was armed inside cm_send_dlm_registration; with it retired,
     NOTHING set the flag — yet the completion gate still required it, so it was
     permanently 0 (48 grants, 0 completions).
  2. The gate also hard-required cm_peer_is_coordinator, but measured topology is
     that OVMX registers with the resource's DIRECTORY node VAX1 (the non-coordinator
     member) and the coordinator VAX2 grants OVMX nothing — a coordinator-keyed gate
     could never fire here.

Fix (both halves): arm ps->dlm_reg_sent=1 at the live registration origination
(cm_send_dlm_nl_register site), on the peer we register to; and re-key the completion
gate to fire on that same peer (drop the coordinator requirement — the per-peer
dlm_reg_sent flag IS the "peer we registered to" discriminator, set only on that ps).
Faithful VMS: register with, and complete op-04/op-03 to, the directory node that
granted the registration. Both one-shots already re-arm together at transition-open,
so re-joins work.

Verification is the lab re-fire (ground source): op-04/op-03 from OVMX->VAX1 go 0->48,
flow-1 commits cluster-wide, CLUSTER_NODES 2->3. scsd.c syntax-clean; send-site census
125/0 (no new send site — an existing completion is now correctly gated). Flow-2 storm
(inbound grants, incl. the not-assigned LNM$CWLOGICALS) is separate and non-gating,
left for a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PhM3QcmFEY3p8YNnHGaYwP
… a real lkid, record the grant, complete from GETLKI (vms-16c)

fc8540a proved the architecture (VAX2 completed the state transition, OVMX being
admitted) but crashed VAX1 with a PLACEHOLDER lock id in the completion. The deeper
problem the operator flagged: flow-1 was wire-plumbing with no executive lock state
behind it — a NL "holds nothing" registration, a grant never recorded, a completion
built from a template. This routes the whole chain through OVMX's executive.

Root of the crash (conductor's named VAX<->VAX chain): OVMX's ENQ was DEGENERATE —
body[24:28] (the requester's own lock id) was zeroed, so VAX1 had no id to build the
normal grant pair and returned only a bare handle; OVMX's completion then had no
master id to reference. Fix, all executive-backed:

- ENQ: cm_send_dlm_registration now carries OVMX's REAL requester lkid at body[24:28]
  (from enum_standing, VMS_IOCTL_DLM_ENUM_STANDING — real held locks), and is fired
  ONCE reactively post-barrier (not op-06-gated → no XITGO perturbation). The NL
  respond-to-rebuild drain is kept for the member's directory rebuild (db20-b).
- Grant-back: OVMX feeds VAX1's grant into its executive via VMS_DLM_OP_GRANT
  (grant_recv) — a real vms_dlm_origin record keyed by OVMX's own req_lkid, carrying
  the master's handle + CSID (the same H5 requester-side receive OVMX$DLM uses). OVMX
  now genuinely tracks the cross-node lock (real BLKAST/LVB/remaster), not a dead echo.
- Completion: read master_lkid BACK from the executive (GETLKI, new master_lkid
  field on the origin accessor) and send op-04/op-03 with it at body[20:24] +
  OVMX's req_lkid at body[24:28], PER grant-back. Fire ONLY when the executive holds
  a real master handle — honest omission otherwise (INV-6), so a placeholder can
  never reach VAX1: crash-safe by construction (worst case CN stays 2, no bugcheck).

Every completion field traces to an executive read (enum_standing lkid, GETLKI
master_lkid), never plumbed frame->frame. Rewrote test_dlm_completion to the faithful
semantics (master handle @[20:24], requester lkid @[24:28]); removed the stale
"holds nothing" doc. vms.ko + scsd build clean; member suite ALL PASSED; send-site
census 125/0. The named-resource completion OFFSET is the one open question the
lab re-fire resolves; the gate makes that resolution safe. DO NOT MERGE fc8540a.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…he fragile dlm_reg_sent gate (vms-16c)

340f94e graded: no crash, ENQ fix confirmed (body[24:28]=0x00010003), VAX1 grants
back a real master handle (0x4abc) -- but OVMX's completion never fires and there is
NO log to say where the chain dies (grant_recv? GETLKI? or the handler never runs?).

Two changes, both to pinpoint and un-stick the break:
1. Drop `&& ps->dlm_reg_sent` from the grant-back gate. The real discriminator is the
   non-zero echoed requester lkid (body[24:28]) -- a genuine flow-1 grant-back, vs the
   NL drain which echoes 0. dlm_reg_sent is a per-peer one-shot that a mid-storm
   transition re-open clears (dlm_reg_sent=0 at transition-open), which would silently
   drop the completion after the registration but before the grant-back lands.
2. Instrument every step so the next re-fire shows exactly where it dies:
   - SCSD-I-DLMGRANTBACK: every cat-82 op-01 grant-back, with the extracted reqlkid,
     master handle, and dlm_reg_sent state.
   - SCSD-I-DLMGRANTREC: grant_recv status + the GETLKI master handle read back.
   - SCSD-I-DLMNOCOMMIT: the honest-omission branch (executive holds no master handle).
   With DLMCOMPLETE (on send) that covers the whole chain.

Confirmed not the cause (checked): origin records live on a global list freed only by
vms_lock_cleanup (module init-failure / exit), never on fd close -- so the fresh
open/REGISTER/close in each helper does not tear down the grant_recv origin.

scsd builds clean; send-site census 125/0; member suite ALL PASSED. Still crash-safe
(completion only on a real executive master handle). DO NOT MERGE fc8540a.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant