Architecture rework: fix protocol bugs, add origin-side cache, document spec

8-expert review identified 3 bugs in shipped code (Vary header hallucination,
fn/function wire key mismatch, max-age=0 defeating PSR) — all fixed with
tests updated across Python and TypeScript.

Added: manifest version field, affects validation, wire format convention,
origin-side cache module (HMAC key derivation, MemoryCache + RedisCache
backends, reverse index for scoped invalidation, executor integration).

16 known issues documented in cache/KNOWN_ISSUES.md from expert review —
critical items (user_id not passed, purge race condition, no Redis error
handling) to be fixed in follow-up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 22:40:55 -04:00
parent 97237ed1a4
commit b2f990b4e5
20 changed files with 1162 additions and 43 deletions

View File

@@ -55,7 +55,7 @@ describe('Edge Compatibility', () => {
test('context GET is cacheable', async () => {
const r = await handleContextFetch('user', { userId: '5' })
expect(r.headers['Cache-Control']).toContain('public')
expect(r.headers['Cache-Control']).toContain('stale-while-revalidate')
expect(r.headers['Cache-Control']).toContain('s-maxage')
expect(r.headers['Cache-Control']).not.toContain('no-store')
})
@@ -70,14 +70,6 @@ describe('Edge Compatibility', () => {
expect(r.headers['Cache-Control']).toBe('no-store')
})
// ── Vary header ────────────────────────────────────────────────────
test('Vary header present on context GET', async () => {
const r = await handleContextFetch('user', { userId: '5' })
expect(r.headers['Vary']).toContain('Authorization')
expect(r.headers['Vary']).toContain('Cookie')
})
// ── X-Mizan-Invalidate header ──────────────────────────────────────
test('mutation response includes invalidation header', async () => {
@@ -195,6 +187,7 @@ describe('Manifest', () => {
test('manifest matches expected structure', () => {
const m = generateManifest()
expect(m.version).toBe(1)
expect(m.contexts.user).toBeDefined()
expect(m.contexts.user.endpoints).toEqual(['/api/mizan/ctx/user/'])
expect(m.contexts.user.params).toContain('userId')