Merge remote-tracking branch 'origin/master' into worktree/pr2177-export-fixes-20260811

# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/subsystems/persistence.i18n.yaml
#	packages/session/session-persistence-jsonl/README.i18n.yaml
#	packages/session/session-persistence/README.i18n.yaml
This commit is contained in:
Tianyi Cui
2026-08-11 16:18:28 +08:00
642 changed files with 1814 additions and 1429 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/session/session-persistence-jsonl/README.md
README.md: 540ddb6db67adb1a36c8feea946b6843e614e035
README.md: 4cff3215cdb083d2fdb7c4a8f1b60e8c4028ba84
README.zh.md: 7e3ba5be4f2707ff6408d296ece1f43550d76286

View File

@@ -72,6 +72,6 @@ JSONL storage does not mutate live request prefixes. A resumed loop can reuse pr
- **Only the configured encoding and current `SESSION_FORMAT_VERSION` (v0) load** — changing compression requires a separate/fresh root or selecting the legacy raw mode; the pre-release format has no migration.
- **The flat-file storage layout does not load** — use a separate root or move pre-release artifacts into the project/session directory layout before loading.
- **Compressed files are not directly line-readable** — use the backend to load them, or select `compression: 'none'` before writing a fresh root when external line readers are required.
- **Nothing deletes session files** — logs accumulate under `root` until removed externally (the seam has no deletion surface).
- **Nothing deletes session files** — logs accumulate under `root` until removed externally (the seam has no deletion API).
- **One live writer per session** — append and repair are coordinated only inside the owning backend instance. Another backend instance or process must not write the same session until that owner reaches quiescent disposal; initial same-id publication remains collision-safe through the POSIX no-overwrite hard link or Windows write-through rename without replacement.
- **POSIX materialization requires hard-link support** — first append uses `link()` so same-id races fail instead of overwriting a committed log; Windows uses write-through rename without replacement.

View File

@@ -163,10 +163,10 @@ export class SessionPersistenceJsonl extends SessionPersistence implements Persi
})
}
// Each backend keeps the typed service surface beside its storage hooks;
// Each backend keeps the typed service API beside its storage hooks;
// extracting these trivial forwards would add an inheritance layer.
/* jscpd:ignore-start */
// --- SessionPersistence service surface (delegated to the coordinator) ---
// --- SessionPersistence service API (delegated to the coordinator) ---
/** Resolve the absolute target path without touching the filesystem. */
locate(meta: SessionHeader): SessionLocation {

View File

@@ -38,7 +38,7 @@ const ERROR_ALREADY_EXISTS = 183
let bindings: Win32Bindings | undefined
/** Load the small Win32 surface lazily so non-Windows processes never load Koffi. */
/** Load the small Win32 API lazily so non-Windows processes never load Koffi. */
async function win32(): Promise<Win32Bindings> {
if (bindings !== undefined) return bindings
const koffi = (await import('koffi')).default

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/session/session-persistence-sqlite/README.md
README.md: 4ba675447393ffb359ec6983585167b692e84a7d
README.md: ec42419a132a26c1f23ab99ab3da1db97a5483b0
README.zh.md: c2578215613ea42fb34e3092f51ec47cbb2fc128

View File

@@ -58,5 +58,5 @@ SQLite storage does not mutate live request prefixes. A resumed loop can reuse p
- **`DatabaseSync` is synchronous** — every append transaction blocks the event loop for its duration; acceptable for local stores, a throughput ceiling for busy multi-session servers.
- **Write contention has no wait or retry policy** — the backend sets no busy timeout and retries no locked-database error, so another connection holding a write transaction makes the operation reject immediately.
- **Only a pristine new database or the current owned `SCHEMA_VERSION` opens** — unversioned schema objects, foreign application identities, and every other schema version are rejected rather than migrated (unreleased software; no persisted user data to preserve).
- **Nothing deletes stored sessions** — rows accumulate until removed externally (the seam has no deletion surface; `ON DELETE CASCADE` is wired for such out-of-band cleanup).
- **Nothing deletes stored sessions** — rows accumulate until removed externally (the seam has no deletion API; `ON DELETE CASCADE` is wired for such out-of-band cleanup).
- **TODO:** this backend talks to `node:sqlite` directly. If a cordis database service (`cordis/db` / a `@cordisjs` SQL driver plugin) is adopted, route through that instead of holding a raw `DatabaseSync` here — the contract surface (`SessionPersistence`) would not change, only the storage driver.

View File

@@ -167,7 +167,7 @@ export class SessionPersistenceSqlite extends SessionPersistence implements Pers
}
}
// --- SessionPersistence service surface (delegated to the coordinator) ---
// --- SessionPersistence service API (delegated to the coordinator) ---
/** SQLite has one database, not an independent local artifact per session. */
locate(_meta: SessionHeader): SessionLocation | undefined {

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/session/session-persistence/README.md
README.md: 09aa7ad8263454d6c5edbb2358033370504c0cb9
README.md: 6e1898f8a49e54f8fe90ff27cf8571c5959f27e9
README.zh.md: 901c41b6894d86bdc4ffb345314a3dd506e4a770

View File

@@ -80,6 +80,6 @@ Persistence does not mutate live request prefixes. A resumed loop can reuse prov
## Known Limitations and Deferred Work
- **No deletion or retention surface** — pruning stored sessions is out-of-band backend maintenance.
- **No deletion or retention API** — pruning stored sessions is out-of-band backend maintenance.
- **`list()` is unpaginated and unfiltered** — it returns every stored session's header; fine for local stores, unindexed at scale.
- **Repair-time synthetic closers are the only crash story** — a backend must synthesize `tool/result`/`step/end`/`turn/end` closers on load; there is no partial-turn resume that continues an interrupted turn instead of closing it.

View File

@@ -624,7 +624,7 @@ export class PersistenceCoordinator<TornMarker = unknown> {
this.installWritePath()
}
// --- public surface (the backend's service methods delegate here) ---
// --- Public API (the backend's service methods delegate here) ---
/**
* Register detached session metadata for lazy creation on the first append.

View File

@@ -87,7 +87,7 @@ class MemoryPersistence extends SessionPersistence implements PersistenceBackend
this.coordinator = new PersistenceCoordinator<never>(this.ctx, this)
}
// --- service surface (delegated to the coordinator) ---
// --- Service API (delegated to the coordinator) ---
locate(_meta: SessionHeader): undefined {
return undefined