Skip to content
This repository was archived by the owner on May 13, 2026. It is now read-only.

fix(org): dual-read fallback for pre-tag molecules (alpha BLOCKER 3e063) - #564

Merged
shiba4life merged 3 commits into
mainlinefrom
fix/org-tag-dual-read
Apr 20, 2026
Merged

fix(org): dual-read fallback for pre-tag molecules (alpha BLOCKER 3e063)#564
shiba4life merged 3 commits into
mainlinefrom
fix/org-tag-dual-read

Conversation

@shiba4life

Copy link
Copy Markdown
Collaborator

Summary

Alpha BLOCKER 3e063 (dogfood run 4): tagging a schema with set-org-hash orphaned every molecule that already existed on the schema. Writes went to the new org prefix, reads went to the new org prefix, but the pre-tag atoms + molecule refs lived at the unprefixed (personal) keys. Queries returned InvalidField("Atom … not found for key …") on data the user had just ingested.

Design (docs/designs/org_shared_sync.md) is explicit that tagging does not re-key pre-existing molecules — but the product was silent and returned a cryptic error rather than continuing to serve the data. This PR lands the dual-read path recommended in the bug report: on miss at the org-prefixed key, fall back to the unprefixed base key. Writes are unchanged; a future change can re-key old data and retire the fallback.

  • AtomStore::get_atom_by_uuid — direct atom lookups
  • AtomStore::get_mutation_events — history-prefix scans
  • FieldBase::refresh_from_db — molecule ref loads during query
  • fetch_atoms_with_key_metadata_async_with_org — batch atom fetch used by all field variants' resolve_value

Regression test

test_pre_tag_molecules_remain_queryable_after_set_org_hash in tests/org_key_prefixing_test.rs:

  1. Register personal schema, ingest two molecules (alpha body, beta body).
  2. Sanity-query — both visible.
  3. Mutate the schema in place to set org_hash + trust_domain + propagate to every runtime field (mirroring fold_db_node::OperationProcessor::set_schema_org_hash).
  4. Query post-tag — both pre-tag molecules must still resolve (this is the failing assertion on main).
  5. Write a third molecule post-tag; query again — mixed pre/post-tag results, all three resolve.
  6. Verify at the Sled level that the tree holds BOTH unprefixed atom keys (pre-tag) and {org_hash}:atom:… keys (post-tag), confirming the fix is read-only and no migration happened.

Test plan

  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace --all-targets (full fold_db suite green, incl. all 10 tests in org_key_prefixing_test.rs)
  • merge queue CI
  • follow-up: workspace pointer bump + post-merge verification in /qa-folddb --dogfood (run 5)

Follow-ups (out of scope)

  • 249d8 — extend /qa-folddb --dogfood harness to exercise the set-org-hash path so this class of regression is caught automatically.
  • Migration pass that re-keys pre-tag molecules under the org prefix so the dual-read fallback can eventually be removed.

Refs: gbrain projects/alpha-e2e-dogfood-run-4, design/org_shared_sync, projects/alpha-org-schema-tagging-gap.

🤖 Generated with Claude Code

@github-actions
github-actions Bot enabled auto-merge April 20, 2026 02:21
Comment thread src/schema/types/field/base.rs Fixed
Comment thread src/schema/types/field/base.rs Fixed
shiba4life and others added 2 commits April 19, 2026 19:45
Pre-existing molecules became unqueryable after `POST /api/schema/{name}/
set-org-hash`. Writes new and reads new both went through the org-prefixed
keyspace, but atoms and molecule refs stored before the tag still lived at
the unprefixed (personal) keys, so `refresh_from_db` and
`fetch_atoms_with_key_metadata_async_with_org` came back with
`InvalidField("Atom … not found for key …")` on the same data the user
had just ingested.

Design (`docs/designs/org_shared_sync.md`) is explicit that set-org-hash
does not rewrite pre-existing keys, but the product was silent and
returned a cryptic error rather than continuing to serve the data.

Fix: dual-read at each read site — try the org-prefixed key first, and on
miss fall back to the unprefixed base key. Applied at:

- `AtomStore::get_atom_by_uuid` — the direct atom lookup used by
  mutation-event replay and other singleton reads.
- `AtomStore::get_mutation_events` — scans history prefix; if the org-
  prefixed scan is empty, retries the unprefixed scan.
- `FieldBase::refresh_from_db` — loads the molecule ref during query;
  now falls back to the unprefixed ref key when the field has an
  `org_hash` but the prefixed key is absent.
- `fetch_atoms_with_key_metadata_async_with_org` — batch atom fetch
  used by SingleField/RangeField/HashRangeField `resolve_value`.

Writes are unchanged — new writes continue to land in the org prefix.
Content-addressed atoms with identical content will coexist under both
keys after mix-use (harmless; the read path prefers the org-prefixed
version).

Regression test: `test_pre_tag_molecules_remain_queryable_after_set_
org_hash` in `tests/org_key_prefixing_test.rs` — register personal
schema, ingest two molecules, promote to org schema, assert both
pre-tag molecules resolve AND a post-tag molecule resolves in the same
query, and assert the Sled tree holds both prefixed and unprefixed atom
keys (confirming the fix is read-only, no migration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI Rust Format step flagged the short match arm as wrappable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shiba4life
shiba4life force-pushed the fix/org-tag-dual-read branch from 60d1167 to 4ac5fb4 Compare April 20, 2026 02:45
@shiba4life
shiba4life disabled auto-merge April 20, 2026 03:07
@shiba4life
shiba4life added this pull request to the merge queue Apr 20, 2026
Merged via the queue into mainline with commit c3393c3 Apr 20, 2026
7 checks passed
@shiba4life
shiba4life deleted the fix/org-tag-dual-read branch April 20, 2026 03:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants