Expose private operational evolution timeline

This commit is contained in:
wuyang
2026-11-03 17:29:10 +08:00
parent 20aea13054
commit 84fc19c965
6 changed files with 67 additions and 4 deletions
+16 -1
View File
@@ -43,7 +43,7 @@ test('password hashing uses random salts and checks a supplied password', () =>
test('anonymous users can see health/login shell but cannot read private reports or ledger', async t => {
const { request } = await fixture(t);
for (const endpoint of ['/api/dashboard', '/api/reports/2026-W45', '/api/reports/2026-W45/download', '/api/ledger']) {
for (const endpoint of ['/api/dashboard', '/api/evolution', '/api/reports/2026-W45', '/api/reports/2026-W45/download', '/api/ledger']) {
const r = await request(endpoint); assert.equal(r.status, 401); assert.equal(r.headers.get('cache-control'), 'no-store');
assert.doesNotMatch(await r.text(), /PRIVATE|entries|cash_usd/);
}
@@ -110,3 +110,18 @@ test('invalid JSON values and oversized bodies are rejected', async t => {
assert.equal((await request('/api/login', { method: 'POST', headers, body: 'null' })).status, 400);
assert.equal((await request('/api/login', { method: 'POST', headers, body: JSON.stringify({ password: 'a'.repeat(9000) }) })).status, 413);
});
test('evolution is private, readable after login, and empty when absent', async t => {
const { request, login, directory } = await fixture(t);
const example = { schema_version: 1, events: [{ id: 'fictional-1', recorded_at: '2026-11-03', retrospective: true, trigger: '虚构起因', hypothesis: '虚构假设', change: '虚构改变', evidence: ['虚构证据'], cost: { known: '未知', unknown: '待确认' }, decision: '虚构决策', next_step: '虚构下一步', artifact_refs: ['虚构版本'] }] };
await writeFile(path.join(directory, 'evolution.json'), JSON.stringify(example));
const anonymous = await request('/api/evolution'); assert.equal(anonymous.status, 401); assert.doesNotMatch(await anonymous.text(), /虚构/);
const shell = await request('/'); assert.doesNotMatch(await shell.text(), /虚构/);
const cookie = (await login()).headers.get('set-cookie').split(';')[0];
const authenticated = await request('/api/evolution', { headers: { Cookie: cookie } });
assert.equal(authenticated.status, 200); assert.deepEqual(await authenticated.json(), example);
await rm(path.join(directory, 'evolution.json'));
const empty = await request('/api/evolution', { headers: { Cookie: cookie } });
assert.equal(empty.status, 200); assert.deepEqual(await empty.json(), { schema_version: 1, events: [] });
});