Skip to content

fix(storage): publish namespace positions atomically - #108

Open
HandSonic wants to merge 528 commits into
mainfrom
fix/namespace-position-atomic
Open

HandSonic wants to merge 528 commits into
mainfrom
fix/namespace-position-atomic

Conversation

@HandSonic

@HandSonic HandSonic commented Aug 31, 2026 •

Copy link
Copy Markdown
Owner

Related issue

N/A - no matching issue was found.

Summary

Namespace datasource-position operations mutated live datasourceIds lists before persistence. A write failure left memory moved/deleted while disk and reload state remained old. This change deep-copies the complete namespace map, persists the candidate first, publishes one volatile map reference, and preserves null namespace as move-to-root.

Affected surfaces

  • Frontend / Web
  • Backend / API / Storage
  • Database plugin / Driver
  • JCEF / Desktop packaging
  • CI / Build / Release
  • Documentation only

Verification

Risk and compatibility

  • Public API or stored data: Existing namespace JSON and request semantics are unchanged.
  • Database or driver compatibility: N/A.
  • Network, privacy, or security: N/A.
  • Community / Local / Pro boundary: Shared Community namespace storage.
  • Backward compatibility: Null target still moves a datasource to root; successful ordering remains append-to-target.

Reviewer map

  • Start here: NamespaceStorage.copyDataMap/persistPositions and atomic-write tests.
  • Failure condition: a failed write changes live objects, or null target throws instead of moving to root.
  • Rollback or disable path: Revert commit 25ada3b790c0649857cb733aa4caa792f4ccb2ef; no migration is required.

Contributor declaration

  • I linked the Issue that defines this change.
  • I tested the affected behavior and reported the actual results above.
  • I did not include credentials, private data, or generated build output.
  • I disclosed substantial AI assistance below, or this PR contains no substantial AI-generated code.

AI assistance: OpenAI Codex assisted with diagnosis, implementation, deterministic tests, verification, and adversarial review.

Latest-main revalidation (2026-09-04)

  • Rebased onto upstream 144a04e; current head 25ada3b.
  • Full storage module: 61/61 passed.

@HandSonic
HandSonic force-pushed the fix/namespace-position-atomic branch 3 times, most recently from c264c4e to 25ada3b Compare September 3, 2026 21:07
openai0229 and others added 27 commits September 7, 2026 14:44
…-alignment

fix(ui): align short filters and hide inactive scrollbars
…vel-order-by

fix(sqlserver): detect top-level pagination ordering
…-post-only

fix(datasource): require POST to close connections
…nstance-startup

fix(desktop): claim the instance before application startup
* fix(result): lazy-load large text values

* chore(result): use English JSON diagnostics
…river-download

fix(frontend): restore driver download and copy icon
# Conflicts:
#	chat2db-community-client/package.json
openai0229 and others added 29 commits September 16, 2026 11:51
…primary-key

fix(sql): resolve primary keys through single-table subqueries
…ingle-row-2483

fix(cockroachdb): limit no-key row updates and deletes natively
…rt-batch1-fast-mode

feat(import): add optional parallel CSV import
…ap-beta

feat(desktop): unify package layout and enable beta updates
fix(storage): publish ER position after persistence
…e-rollback

fix(ai): roll back failed history deletion
…nc-position-2479

fix(storage): synchronize NamespaceStorage position mutations
…c-write

fix(ai): write chat history atomically
…s-signing-argv

fix(ci): preserve quoted Windows signing commands
…entials-2472

chore(ipc): redact credentials in debug IPC request/response logs
…single-flight

fix(mcp): serialize token resets
if (!target.getParent().equals(stagingDirectory)) {
throw new IOException("invalid staging target");
}
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
if (!target.getParent().equals(stagingDirectory)) {
throw new IOException("invalid staging target");
}
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
}

private static void validateSource(File file, String originalFileName) {
if (file == null || !file.isFile() || !file.canRead() || file.length() > MAX_SIZE_BYTES
}

private static void validateSource(File file, String originalFileName) {
if (file == null || !file.isFile() || !file.canRead() || file.length() > MAX_SIZE_BYTES

private static void deleteQuietly(Path path) {
try {
Files.deleteIfExists(path);
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.

4 participants