Skip to content

ssot: restore the [pgvector] keys a lost header stranded under [offline] - #60

Draft
mios-dev wants to merge 4 commits into
mainfrom
claude/fervent-gates-jp5d5z
Draft

mios-dev wants to merge 4 commits into
mainfrom
claude/fervent-gates-jp5d5z

Conversation

@mios-dev

@mios-dev mios-dev commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

6ab11843 opened [lsfs] and [offline] directly after [pgvector].rls_mode in usr/share/mios/mios.toml. Everything below that line parsed into [offline]. That was fifteen keys, not the seven first noticed: rls_enable, pool_enable/pool_min/pool_max, the three hnsw_* scan knobs, emb_model, emb_version, scratch_persist, backfill_batch, backup_enable/backup_dir/backup_keep and listen_loopback.

The resolver emitted MIOS_OFFLINE_* for them, and nothing reads those names. Every consumer reads the [pgvector] names and silently fell back to its inline default:

Consumer Reads Effect before this PR
[containers.mios-pgvector] Exec (pgvector Quadlet) MIOS_PG_HNSW_* The render baked strict_order/20000/1; editing the key did nothing
agent-pipe mios_pipe/memory/pg.py, usr/libexec/mios/mios-pg-query MIOS_DB_RLS_ENABLE The tenant-RLS switch the 2026-09-29 audit cites could not be turned on where the SSOT declared it
agent-pipe pg.py MIOS_PG_POOL_* Pool knobs dead
agent-pipe server.py MIOS_PGVECTOR_EMB_MODEL / _EMB_VERSION Embedding-version hygiene used compiled defaults
userenv.sh, mios-resolver shell emitter MIOS_PG_LISTEN_LOOPBACK / MIOS_PGVECTOR_LISTEN_LOOPBACK MIOS_PG_BIND_ADDR always fell back to 127.0.0.1
mios-pgvector-backup.service MIOS_PG_BACKUP_* Reachable only through an offline.backup_* alias added by 8bb9075f/de73f459

Overrides written by the configurator, which already uses pgvector.* keys, did reach the env-reading consumers. Edits at the declared location did not, and the Quadlet render (vendor tier only) never saw either.

The configurator (pgvector.* data-keys), check-runtime.py, schema-init.sql, edge-node-join.md and the value-aliases.tsv registry all name [pgvector] too. [database] is not the lost header: no consumer reads MIOS_DATABASE_* for these keys.

Changes

  • mios.toml: the fifteen keys move back into [pgvector] verbatim. A parsed-TOML deep compare shows exactly 15 paths moving offline.* → pgvector.* with equal values, and nothing else changing. The orphaned WS-A15 comment goes back above memory_provider, which it describes.
  • Gate (tools/drift-checks.py value-aliases): this gate is why nothing caught the bug. It skipped any registry row whose names were not emitted, and the stranded families were exactly the rows it skipped. A registered name the resolver does not emit is now a violation that names it. Rows whose names end in _ are naming-family declarations and are not checked. [pgvector].rls_enable → MIOS_DB_RLS_ENABLE joins the registry, so the RLS control is covered too.
  • Ledgers:
    • var-closure-baseline.tsv drops the four names it had recorded as referenced-but-unemitted (MIOS_DB_RLS_ENABLE, MIOS_PG_POOL_*); ceiling 410 → 406.
    • value-dup-baseline.tsv is a pure one-for-one rename. The five rows whose members were stranded MIOS_OFFLINE_* names now name the restored canonical keys (MIOS_PGVECTOR_POOL_MAX, _EMB_MODEL, _BACKFILL_BATCH, _BACKUP_DIR, _BACKUP_KEEP). Every count and the 405 ceiling are unchanged, and nothing new is recorded (9bf687c1, after review).
  • Research prompt vector-index-version-assurance.xml.md: its context no longer presents the fault as current. Its af6de6a provenance stays as written.
  • Generated: globals.{sh,ps1}, env-baseline.txt, the man page, manifests and the corpus ledger, all from tools/sync-generated.sh (+ roadmap-index.py).
  • Later commits:
    • 779b0bb6 is wording only. The registry header and the test docstring now say the old skip hid 14 of the 15 stranded keys; the 15th, rls_enable, had no row until this PR. It also carries the manifest and corpus bytes that sync-generated.sh regenerates from those files.
    • 1e19a29b adds this branch's handoff entry to .devloop/LEDGER.md.

Evidence

  • Fixed tree: Python and Rust resolvers emit identical maps (2840 names). Against origin/main, the 15 MIOS_OFFLINE_* names go, 27 consumer names arrive, and no value changes. Every consumer's name now resolves to the value of its own inline default, so default runtime behaviour is unchanged.
  • Planted regression (the exact af6de6a layout; [pgvector]/[offline] parse equal to af6de6a's):
    • check_value_aliases fails naming 27 variables, e.g. MIOS_PG_HNSW_ITERATIVE_SCAN is registered (MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN -> MIOS_PG_HNSW_ITERATIVE_SCAN, derive) but the resolver does not emit it.
    • It still fails after tools/sync-generated.sh, the "regen derived → GREEN" step that let 6ab11843 land.
    • check_var_closure names MIOS_DB_RLS_ENABLE and MIOS_PG_POOL_ENABLE/MIN/MAX.
    • check_pod_quadlets cannot see it either way: the rendered unit is byte-identical at default values.
  • Old gate: on the same plant it reports value-alias consistency verified. tools/test_drift-checks.py TestValueAliasRegistry fails 3/7 on the old gate and passes 7/7 here. One of the tests replays the plant hermetically against the real snapshot tool and registry, with the shipped SSOT as its control.
  • Render: with the fix, a vendor hnsw_iterative_scan = "relaxed_order" renders hnsw.iterative_scan=relaxed_order. Under the bug the same edit rendered strict_order.
  • Full 98-drift-checks.sh vs origin/main (same container, MIOS_RATCHET_BASE = origin/main): 57 violations on each, and no check newly fails. The only differing lines:
    • check_var_closure 440/410 → 436/406 (the same pre-existing excess of 30).
    • tooling_python_lines 80510 → 80513, the gate change, on a legibility ratchet already over its floor.
    • Two resolver-equivalence failures first seen on main were an artefact of a shared binary; they pass with main's own build.
  • check_no_duplicate_value_key (already red on main): findings are identical to main's plus exactly six lines, each a MIOS_PG_* second spelling of a restored key (see below). That is three new two-spelling groups ('strict_order', '20000', 'nomic-768-v1') and three grown members (MIOS_PG_POOL_MAX → '8', MIOS_PG_BACKFILL_BATCH → '50', MIOS_PG_EMB_MODEL → 'nomic-embed-text'). The count goes 416 → 419 with the ceiling at 405 on both, and the rename leaves no shrank or stale row.
  • just drift-gate legs:
    • Golden-master unit snapshots: 25/25.
    • tools/test_*.py: 21/24. The three failures (test_check-ssot.py, test_ci-suites.py, test_sync-dotfiles.py) fail identically on untouched main.
    • Agent-pipe and libexec unit-test pass/fail sets equal main's.
    • lint-python, lint-shell, lint-json and 97-ssot-lint.sh pass; pyflakes reports nothing new.
  • CI on 1e19a29b:
    • "Generated artifacts match the SSOT" and the static-analysis tier (including the PowerShell lints) pass.
    • The behavioural tier fails the same five suites as main, with identical output (comment). tools/test_drift-checks.py passes there.
    • smoke-test fails at the in-image 98-drift-checks with 108 violations, as on main. The sorted violation lines match main's except for the two count changes listed under the full 98-drift-checks.sh run above: check_var_closure 436/406 and tooling_python_lines 80513.
    • sync-generated.sh is a fixed point. mios-task migrate no longer exists (T-1169); mios-task check passes.

Not in this PR

  • Second spellings of the restored keys. [pgvector] is an aliased table, so each restored key is also emitted as MIOS_PG_<KEY>. The value-dup ratchet now reports those six spellings rather than the ledger silencing them, which is Law 9 debt for the alias collapse. Collapsing them needs a change to the resolver's [pgvector] alias family in both twins. Making the gate fold registered derive aliases into one declaration would also remove them, but it drops 65 groups from main's ledger (416 → 351), and that ledger is T-1159's to re-key. The resolver lane plans to fold the [pgvector] alias family after T-1192 lands.
  • The offline.backup_* alias and the inert [offline] table go together.
    • The alias stays in both resolver twins. It is dead for the shipped SSOT, tools/native/mios-resolver is owned by a running lane, and deleting it from one twin alone would break Law 13.
    • [offline]'s remaining enable/rpm_mirror_dir/fallback_to_online have no reader: 04-local-rpm-mirror.sh reads MIOS_RPM_MIRROR_DIR/MIOS_OFFLINE_BUILD.
    • check_no_inert_ssot_tables stays quiet about it only because the dead alias branch in mios_toml.py counts as consumer evidence; deleting that branch makes the gate name [offline] (verified).
    • One follow-up for both.
  • Quadlet placeholder closure. 17 other Quadlet-source placeholders still resolve to names the SSOT never emits, including MIOS_PG_BIND_ADDR, so listen_loopback = false never reaches the rendered unit. Follow-up.
  • Already red on main, unchanged here apart from the six spellings above:
    • check_var_closure: 30 un-ledgered names (T-1159 is draining these).
    • check_no_duplicate_value_key: 11 over its ceiling.
    • check_docs_ratchet (91/6), check_legibility_ratchet, and the behavioural-tier failures the Monitor session is fixing.

🤖 Generated with Claude Code

https://claude.ai/code/session_014Ko3T9bSv6UHkq8ALgVp8b

claude added 4 commits October 3, 2026 18:59
6ab1184 opened [lsfs] and [offline] directly after [pgvector].rls_mode,
so the fifteen keys below it parsed into [offline]: rls_enable,
pool_enable/min/max, hnsw_iterative_scan, hnsw_max_scan_tuples,
hnsw_scan_mem_multiplier, emb_model, emb_version, scratch_persist,
backfill_batch, backup_enable/dir/keep and listen_loopback. The resolver
emitted MIOS_OFFLINE_*, which nothing reads, and every consumer of the
[pgvector] names silently took its inline default:

  MIOS_PG_HNSW_*           [containers.mios-pgvector] Exec; the render baked
                           the Quadlet defaults, so editing the key did nothing
  MIOS_DB_RLS_ENABLE       agent-pipe pg.py and mios-pg-query (tenant RLS)
  MIOS_PG_POOL_*           agent-pipe pg.py
  MIOS_PGVECTOR_EMB_*      agent-pipe server.py
  MIOS_PG_LISTEN_LOOPBACK  userenv.sh -> MIOS_PG_BIND_ADDR
  MIOS_PG_BACKUP_*         mios-pgvector-backup.service, reached only through
                           an offline.backup_* resolver alias (8bb9075)

The keys move back into [pgvector] verbatim. A parsed-TOML deep compare
shows exactly 15 paths moving offline.* -> pgvector.* with equal values and
nothing else changing. Every consumer name is now emitted, each with its
consumer's inline default as the value, so default behaviour is unchanged
and the keys are live again. The orphaned WS-A15 comment goes back above
memory_provider, which it describes.

Why no gate saw it: check_value_aliases skipped every registry row whose
names were not emitted, and the stranded families were exactly the rows it
skipped. A registered name the resolver does not emit is now a violation
that names it; [pgvector].rls_enable -> MIOS_DB_RLS_ENABLE joins the
registry so the RLS control is covered as well.

Ledgers: var-closure stops recording the four names it had as
referenced-but-unemitted (ceiling 410 -> 406). value-dup-baseline was
seeded (710886c) from the stranded layout; it now records the three
restored MIOS_PGVECTOR_X/MIOS_PG_X pairs and the five renamed members
(ceiling 405 -> 408), and that gate's other findings on this tree are
identical to origin/main's.

The offline.backup_* alias stays in both resolver twins for now: it is
dead for the shipped SSOT, tools/native/mios-resolver belongs to a running
lane, and deleting it from one twin only would break Law 13. The shipped
pgvector research prompt no longer describes the fault as current.

Controls:
- planted: the af6de6a layout (tables equal to af6de6a's) fails
  check_value_aliases naming 27 variables, e.g.
  "MIOS_PG_HNSW_ITERATIVE_SCAN is registered (MIOS_PGVECTOR_HNSW_ITERATIVE_SCAN
  -> MIOS_PG_HNSW_ITERATIVE_SCAN, derive) but the resolver does not emit it",
  and still fails after tools/sync-generated.sh, the "regen derived -> GREEN"
  step that let 6ab1184 land. var-closure names MIOS_DB_RLS_ENABLE and
  MIOS_PG_POOL_ENABLE/MIN/MAX. check_pod_quadlets cannot see it: the
  rendered unit is byte-identical either way at default values.
- old gate: that plant reads "value-alias consistency verified";
  tools/test_drift-checks.py TestValueAliasRegistry fails 3/7 there and
  passes 7/7 here. One test replays the plant hermetically against the
  real snapshot tool and registry, with the shipped SSOT as its control.
- render: with the fix, a vendor hnsw_iterative_scan = "relaxed_order"
  renders hnsw.iterative_scan=relaxed_order; under the bug it rendered
  strict_order.
- resolvers: Python and Rust emit identical maps (2840 names). Against
  origin/main, 15 MIOS_OFFLINE_* names go, 27 consumer names arrive and no
  value changes.
- tools/sync-generated.sh (+ roadmap-index.py) is a fixed point. mios-task
  migrate no longer exists (T-1169); mios-task check passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ko3T9bSv6UHkq8ALgVp8b
Review (operator, via the Monitor session): MiOS never raises a ratchet
ceiling, and 52e4ba1 took value-dup-baseline.tsv from 405 to 408 to record
three new groups.

The ledger change is now a pure rename. The five rows whose members were
stranded MIOS_OFFLINE_* names now name the restored canonical keys
(MIOS_PGVECTOR_POOL_MAX, _EMB_MODEL, _BACKFILL_BATCH, _BACKUP_DIR,
_BACKUP_KEEP) one for one, with every count and the 405 ceiling unchanged.
Nothing new is recorded.

What the restoration adds beyond that stays visible to the ratchet rather
than silenced. [pgvector] is an aliased table, so each restored key is also
emitted as MIOS_PG_<KEY>. Where that value is unique it forms a new
two-spelling group ('strict_order', '20000', 'nomic-768-v1'); elsewhere the
second spelling joins a recorded group ('8', '50', 'nomic-embed-text').
That is Law 9 debt for the alias collapse. It cannot be collapsed here
without changing the resolver's [pgvector] alias family in both twins.
Folding registered aliases inside the gate would drop 65 groups from main's
ledger (416 -> 351), and that ledger is T-1159's to re-key.

check_no_duplicate_value_key on this tree versus origin/main: identical
findings plus exactly those three NEW groups and three grown members
(count 416 -> 419, ceiling 405 on both); no SHRANK or stale row from the
rename. tools/sync-generated.sh remains a fixed point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ko3T9bSv6UHkq8ALgVp8b
The registry header and the test docstring said fourteen [pgvector] keys
were stranded under [offline]. Fifteen were. Fourteen of them had registry
rows, which the old gate skipped; the fifteenth, rls_enable, had no row
until this branch added one. Both now say so.

tools/manifest.json and the corpus ledger embed the test file and are
regenerated by tools/sync-generated.sh, which is a fixed point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ko3T9bSv6UHkq8ALgVp8b
Replaces the automatic pre-compact placeholder with what the branch did,
how both controls ran, what CI shows against main 26edb17, and what is
still unverified: the PR-head smoke test, the CI tiers that never run
while the behavioural tier is red, and a booted host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014Ko3T9bSv6UHkq8ALgVp8b

mios-dev commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner Author

drift-gate and smoke-test fail on main too, not because of this PR.

drift-gate. On head 1e19a29b (run 37149445063), the behavioural suite tier reports 403 passed and 5 failed:

  • tests/powershell/run-pester.sh
  • tests/test-bootstrap-sync-parity.py
  • tests/test-video-encoder-probe.sh
  • tools/test_check-ssot.py
  • tools/test_sync-dotfiles.py

Main at 26edb17f, this PR's base, fails the same five suites (run 37134321259). I diffed each suite's output between the two runs after normalising timings and temp paths, and they are identical. On main, as here, the Rust and drift-gate tiers are skipped once this tier fails.

What this PR changes passes:

  • "Generated artifacts match the SSOT" and the static-analysis tier pass on this head.
  • tools/test_drift-checks.py passes in CI, including the new TestValueAliasRegistry tests.

smoke-test. Both runs fail at the same point: the in-image 98-drift-checks in the smoke build, with 108 violations on each. I sorted each run's VIOLATION lines and compared them; 105 are byte-identical. The other three are existing violations whose numbers changed exactly as the PR description says:

  • check_var_closure reports 436/406 here against 440/410 on main. The four names this PR emits come off the ledger, and the excess of 30 is the same.
  • check_legibility_ratchet has tooling_python_lines at 80513 here against 80510 on main. That is the 3-line gate change in tools/drift-checks.py, on a ratchet main already exceeds (floor 77671).

No check fails here that passes on main.

Fix. No fix PR for the base failures is open yet. The main-CI fix lane is fixing them on main ahead of this PR in the merge order, and this PR will be re-gated on top of that fix. Nothing is ported here.


Generated by Claude Code

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.

2 participants