Merge remote-tracking branch 'origin/master' into feature/subagent-policy-inheritance

# Conflicts:
#	.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/persistence.i18n.yaml
#	docs/persistence-catalog.md
#	packages/core/session/README.i18n.yaml
#	packages/sandbox/sandbox-policy/README.i18n.yaml
#	packages/subagent/subagent-inprocess/README.i18n.yaml
This commit is contained in:
kingwl
2026-07-28 18:19:30 +08:00
396 changed files with 7854 additions and 2571 deletions
@@ -263,10 +263,10 @@ export function scanLog(buffer: Buffer): { meta: SessionHeader; events: SessionE
const headerLine = parsedHeader
// Parse and decode every complete line first so the last valid `turn/end`
// determines whether an earlier hole is committed corruption or an
// uncommitted tail. One line yields one event, or a whole run for a packed
// chunk row; a row-tagged line that fails row validation is a hole, exactly
// like unparsable JSON.
// determines whether an earlier hole interrupts an otherwise closed
// execution or belongs to a tolerable final suffix. One line yields one
// event, or a whole run for a packed chunk row; a row-tagged line that fails
// row validation is a hole, exactly like unparsable JSON.
interface Parsed { ok: boolean; events?: SessionEvent[]; endByte: number }
const parsed: Parsed[] = eventEntries.map((entry) => {
try {
@@ -276,9 +276,11 @@ export function scanLog(buffer: Buffer): { meta: SessionHeader; events: SessionE
}
})
// The last index (into eventEntries) that ends in a valid `turn/end` — the
// last fully-committed boundary (the loop flushes only at turn/end). A packed
// row never stores a turn/end, so only single-event lines can match.
// The last index (into eventEntries) that ends in a valid `turn/end`. A hole
// before this boundary cannot be a torn final suffix because later execution
// already closed. Standalone events after it remain part of the preserved
// contiguous prefix. A packed row never stores a turn/end, so only
// single-event lines can match.
let lastTurnEnd = -1
for (let i = parsed.length - 1; i >= 0; i--) {
const p = parsed[i]