policy: reject out-of-range seed boundaries; carry baselines through session-query
Review fixes (ds-review-bot on #623): - overrideOf (both knobs) rejects a seedLength past the log end before slicing: a malformed durable boundary would otherwise empty the own-switch slice until the log outgrew it, letting a wide baseline shadow a REAL later tightening. Malformed durable metadata fails loud, never open. - The session-query derived index carries the two baseline fields end to end: schema columns on both session tables (SESSION_QUERY_SQLITE_SCHEMA _VERSION 6 — derived, rebuilds in place), inserts, header selects, the candidates CTE, rowHeader, sameHeader, and the cross-source assertSessionHeadersCompatible — so a search hit's header keeps the child's inherited confinement and conflicting live/persisted baselines reject. Red-first: out-of-range seedLength tests in both policy suites; baseline round-trip and live/persisted baseline-conflict tests in the session-query sqlite suite.
This commit is contained in:
@@ -162,7 +162,14 @@ export function approvalOverrideOf(session: Session): ApprovalPolicy | undefined
|
||||
if (!APPROVAL_POLICIES.includes(baseline as ApprovalPolicy)) {
|
||||
throw new Error(`session header approvalPolicy "${baseline}" is outside the closed policy vocabulary`)
|
||||
}
|
||||
const own = effectiveApprovalPolicy(session.events.slice(session.header.seedLength ?? 0))
|
||||
// A boundary past the log would make the own-switch slice empty until the
|
||||
// log grows past it — a baseline would then shadow a REAL later switch.
|
||||
// Malformed durable metadata fails loud, never fails open.
|
||||
const seedLength = session.header.seedLength ?? 0
|
||||
if (seedLength > session.events.length) {
|
||||
throw new Error(`session header seedLength ${seedLength} exceeds the log length ${session.events.length}`)
|
||||
}
|
||||
const own = effectiveApprovalPolicy(session.events.slice(seedLength))
|
||||
return own ?? baseline as ApprovalPolicy
|
||||
}
|
||||
|
||||
|
||||
@@ -655,4 +655,12 @@ describe('delegation inheritance (overrideOf over the header baseline)', () => {
|
||||
|
||||
expect(ctx.approval.overrideOf(child)).toBe('never')
|
||||
})
|
||||
|
||||
it('rejects a seed boundary past the log end instead of silently ignoring own switches', async () => {
|
||||
const ctx = await mounted()
|
||||
const child = inheritedSession('sess-appr-oob', { approvalPolicy: 'ask', seedLength: 100 })
|
||||
setApprovalPolicy(child, 'never')
|
||||
|
||||
expect(() => ctx.approval.overrideOf(child)).toThrow(/seedLength/)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user