feat: harden chat state by tenant
This commit is contained in:
@@ -15,9 +15,11 @@ function withTempChatState(fn: () => void) {
|
||||
CASAN_CHAT_AUDIT_HEAD: process.env.CASAN_CHAT_AUDIT_HEAD,
|
||||
CASAN_CHAT_METRICS_LOG: process.env.CASAN_CHAT_METRICS_LOG,
|
||||
CASAN_APPROVAL_INBOX_FILE: process.env.CASAN_APPROVAL_INBOX_FILE,
|
||||
CASAN_TENANT_STATE_ROOT: process.env.CASAN_TENANT_STATE_ROOT,
|
||||
};
|
||||
const state = mkdtempSync(join(tmpdir(), 'cp-chat-'));
|
||||
process.env.CASAN_STATE_ROOT = state;
|
||||
process.env.CASAN_TENANT_STATE_ROOT = join(state, 'tenants');
|
||||
process.env.CASAN_APPROVAL_INBOX_FILE = join(state, 'approval-inbox.json');
|
||||
delete process.env.CASAN_CHAT_AUDIT_LOG;
|
||||
delete process.env.CASAN_CHAT_AUDIT_HEAD;
|
||||
@@ -135,3 +137,22 @@ test('chat ask escalates delegation approval into approval inbox', () => {
|
||||
assert.equal(inbox.proposals[0].payload.agent_binding.decision, 'REQUIRES_APPROVAL');
|
||||
});
|
||||
});
|
||||
|
||||
test('chat replay is partitioned by non-default tenant', () => {
|
||||
withTempChatState(() => {
|
||||
const svc = new ChatService();
|
||||
const alpha = { ...viewer, actor: 'tenant-alpha', tenant: 'alpha' };
|
||||
const res = svc.ask({ message: 'Summarize Plan 18 MVP-2 status', chatId: 'tenant-chat' }, alpha) as any;
|
||||
assert.equal(res.success, true);
|
||||
assert.equal(res.audit_verify.ok, true);
|
||||
|
||||
const alphaReplay = svc.replay('tenant-chat', '', 'alpha') as any;
|
||||
assert.equal(alphaReplay.ok, true);
|
||||
assert.equal(alphaReplay.decision, 'MATCH');
|
||||
assert.equal(alphaReplay.records, 1);
|
||||
|
||||
const betaReplay = svc.replay('tenant-chat', '', 'beta') as any;
|
||||
assert.equal(betaReplay.ok, true);
|
||||
assert.equal(betaReplay.records, 0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user