Skip to content

Control: SharedState constructor tail duplicated (init/open) — new fields drift between test and prod #400

Description

@EnRaiha

Version / build tested against

origin/main @ e235fe5 (2026-09-29)

Deployment mode

Origin — single node (local)

Engine(s) involved

Not engine-specific / unsure

Summary

SharedState is constructed by two near-identical struct-literal tails (test path init.rs, prod path server/open.rs). Every new field must be added twice; the two already diverge in field order and shuffle staging, so a missed field is a live risk — a test-only field silently changes what the test exercises.

Steps to reproduce

diff the two constructor tails; add a field to one and observe the other drifts. (static verification at the pin.)

Expected behavior

One shared assembler used by both constructors.

Actual behavior

Duplicated struct-literal tails that have already drifted.

What actually happened? (severity facts)

  • Acknowledged/committed data was lost, corrupted, or silently wrong
  • The server crashed, hung, or failed to start
  • A security or isolation boundary was crossed
  • Core functionality is broken with no acceptable workaround
  • A workaround exists

Proposed severity

SEV-4 — Low: maintenance hazard, no current user-visible defect.

Reproducibility

Always — every attempt

Last known-good version / commit (if a regression)

(unknown / not a regression)

Environment & logs

Linux x86_64; Verified by static code reading at the pin above; runtime reproduction pending.
Code references:

  • (see prior-art line below)

Before submitting

  • I searched existing issues and this is not a duplicate. (searched SharedState: none)
  • Reproduced on a released tag or current main build (pending) — code path verified at e235fe55c.
  • This is not a security vulnerability.

Additional evidence (origin/main @ e235fe55c)

  • What: the 21-line SharedState { ... } tail from audit_dml_cache to startup is duplicated in the test constructor and the production constructor.
  • Where: nodedb/src/control/state/init.rs:375-395 (new_inner); nodedb/src/control/state/init_prod/open.rs:376-396 (open).
  • Evidence: diff of the two extracted tails differs only in lsn_ms_map position (init.rs:374 vs open.rs:383) and shuffle_registry staging path (prod: catalog_path.parent(); test: std::env::temp_dir()/nodedb-shuffle-{pid}-{test_id}).
  • Impact: every new SharedState field must be added in two places; the two constructors already diverge in field order and shuffle staging, so a missed field is a live risk. A test-only field added to one path silently changes what the test exercises.
  • Fix: extract a shared assembler (e.g. SharedStateParts::assemble(...) taking the two differing values as parameters) used by both constructors.
  • Prior-art: no open issue matches (searched: SharedState, init.rs duplication).
    Why: every new SharedState field must be added in two places; the two constructors already diverge in field order and shuffle staging, so a missed field is a live risk (and a test-only field silently changes what the test exercises).
    Steps to verify: diff the two constructor tails (.../init.rs visit vs .../server/open.rs), then extract a shared assembler and run cargo test -p nodedb.

Activity

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