Files
mizan/ISSUES.md
Ryth Azhur 9d2781b52c Catch missed content edits from tree restructure
The fe39fcb commit captured the file moves (git mv stages those automatically)
but didn't catch the content edits I made afterward — npm package rename
(@mizan/runtime → @mizan/base), path updates in Makefile/Dockerfile/examples,
and doc updates were all left unstaged at commit time.

This commit lands those:
- npm rename: 3 frontend package.jsons (base/vue/svelte) + mizan-base/src/index.ts + 4 codegen templates
- path updates: Makefile, Dockerfile.test, two Gitea workflows, four example/harness configs
- doc updates: CLAUDE.md, ROADMAP.md, ISSUES.md, docs/AFI_ARCHITECTURE.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 01:26:04 -04:00

8.0 KiB

Mizan — Known Issues

Identified by domain expert review (Cloudflare, Serverless, Vercel, React Query, Django, Laravel, Vue/Svelte).

Fixed

  • C1 Scoped cache purge now passes user_id
  • C2 initSession retries 3x, resets on failure
  • C3 SSR backend injects __MIZAN_SSR_DATA__ script tag
  • C4 SSR bridge uses _write_lock for stdin
  • C5 SSR bridge registers atexit handler
  • C7 View-path mutations now purge origin cache
  • H1 pendingScoped is Array, not Map (no overwrite)
  • H2 stableKey() sorts JSON keys (order-independent)
  • H3 mizanFetch retries 2x on 5xx/network errors
  • H4 Named contexts skip refetch if SSR data exists
  • H6 refreshContext uses GET /ctx/ not POST /call/
  • H10 _meta always fresh dict
  • H11 Python normalizes True→"true" for cross-language HMAC
  • H13 isValid checks all required fields are touched
  • M11 execute_function return type includes HttpResponseBase
  • M18 registerContext cleanup uses ?. (no crash)

Remaining Critical

C6. No loading/error/stale states in runtime

File: mizan-base/src/index.ts The kernel stores only {params, refetch}. No data, status, error. Every adapter reinvents loading tracking. Blocks stale-while-revalidate.

Remaining High

H5. Mutation hooks expose no loading/error state

File: mizan-django/generate/generator/lib/adapters/react.mjs Returns bare useCallback. No isPending, error, isSuccess.

H7. Redis SCAN blocks request path at scale

File: mizan-django/src/mizan/cache/backend.py Synchronous SCAN at 1M keys: multi-second blocking.

H8. Svelte codegen uses Svelte 4 stores

File: mizan-django/generate/generator/lib/adapters/svelte.mjs Should use Svelte 5 $state/$derived runes.

H9. Svelte destroy() not auto-called

File: mizan-django/generate/generator/lib/adapters/svelte.mjs Memory leak if user forgets onDestroy.

H12. Forms triggerValidation captures stale data

File: mizan-react/src/forms.ts Debounced validation uses stale closure data.

Remaining Medium

M1. SSR bridge not fork-safe

gunicorn prefork shares file descriptors and Redis connections.

M2. cache_purge_user() not implemented

No way to purge all cache entries for one user.

M3. No garbage collection for context entries

Runtime contexts Map grows monotonically.

M4. No cross-tab invalidation

No BroadcastChannel. Logout in tab 1 doesn't affect tab 2.

M5. React 18 Strict Mode double-fetch

useEffect runs twice in dev mode.

M6. No request deduplication

Two components mounting same context fire parallel fetches.

M7. SSR worker module cache never invalidates

Dynamic imports cached forever.

M8. Vue injection key not exported

Can't inject directly without generated composables.

M9. Vue onMounted won't pre-fetch in Vue SSR

Needs onServerPrefetch for Nuxt.

M10. Svelte should use setContext/getContext

Module-level stores don't scope to component tree.

M12. render_strategy heuristic uses hardcoded param names

Misses member_id, customer_id, non-English names.

M13. initSession called for token-auth requests

Wastes GET /session/ round-trip for JWT/MWT apps.

M14. Vue watch imported but unused

Params not watched — reactive param changes don't trigger refetch.

M15. Vue mutation composables misleading use prefix

export const useXxx = callXxx — not a real composable.

M16. Svelte mutation imports bypass Stage 1 index

Should import from '../index' consistently.

M17. Side effects in React state updater

Context listeners called inside setContextStore() updater.

Architectural / Cleanup Debt

A1. Legacy MizanProvider not yet removed

File: mizan-react/src/context.tsx (~750 lines) Superseded by the kernel (mizan-base) + generated React adapter (useSyncExternalStore). Still exported as MizanProvider, useMizan, useMizanContext, etc. Must be deleted or replaced with thin shims that call configure() + delegate to the new generated hooks.

A2. Allauth pending extraction

File: legacy/allauth/ (44 files) Sitting in legacy/ since the cleanup pass. Should become its own mizan-django-allauth package consuming Mizan's public API. Unblocks v1 mizan-react publishing.

A3. Forms codegen not adapted to kernel

File: mizan-react/src/forms.ts (~1163 lines) Still uses useMizan().call() from the legacy MizanProvider. Needs rewrite to use mizanCall from the kernel. Currently the only consumer of MizanProvider — blocks A1.

A4. Codegen for Vue/Svelte not validated end-to-end

The Stage 2 templates produce code that compiles, but no example app exercises Vue or Svelte rendering against a live backend. React is the only adapter with full integration verification.

A5. ROADMAP.md is stale

File: ROADMAP.md Lists SSR Bridge, Edge Manifest, Codegen Rewrite, etc. as "Next" — all are done. Doesn't reflect:

  • Two-stage codegen with Vue/Svelte adapters
  • C6 kernel-owned state (ContextState<T>)
  • mizan-ts cross-language adapter
  • Cleanup of djarea/Django-specific naming

A6. CLAUDE.md may also be stale

File: CLAUDE.md Written before the kernel rewrite. References to MizanProvider responsibilities and the old codegen pattern are likely outdated. Needs audit.

Test Coverage Gaps

T1. No tests for C6 kernel state machine

File: mizan-base/ has no tests/ directory at all The state-owning kernel has zero unit tests. No coverage of:

  • registerContext returning getState/subscribe/refetch/unregister
  • Status transitions: idle → loading → success/error
  • Subscriber notifications on state change
  • Refetch reusing the same entry on Strict Mode re-mount
  • unregister clearing listeners

T2. No tests for generated Vue adapter output

The vue.mjs template produces code, but no test verifies it generates valid Vue 3 composables, that onServerPrefetch is wired correctly, or that the kernel subscription bridges to Vue reactivity.

T3. No tests for generated Svelte adapter output

Same as T2. Readable store factory pattern is unverified against actual Svelte components.

T4. No tests for view-path cache purge (C7 fix unverified)

The fix added _purge_cache_for_invalidation() to the view-path branch, but no test asserts that an HttpResponse-returning mutation actually purges the origin cache.

T5. No tests for SSR thread safety (C4 fix unverified)

The _write_lock was added but no concurrent-render test exists to prove it prevents JSON interleaving.

T6. No tests for SSR atexit cleanup (C5 fix unverified)

atexit.register(self.shutdown) was added but not exercised — no test that asserts the Bun process is reaped on Python exit.

T7. No tests for SSR hydration injection (C3 fix unverified)

The <script>window.__MIZAN_SSR_DATA__=...</script> was added to template output but no test asserts it appears in rendered HTML or that the JSON is valid/safe.

T8. No cross-language HMAC pin test for booleans/None (H11 fix unverified)

Python now normalizes True→"true", but there's no test comparing Python's derive_cache_key(secret, ctx, {flag: True}) against TypeScript's equivalent to prove they produce identical hex output.

T9. No tests for retry logic (H3)

fetchWithRetry retries 5xx/network errors with backoff. No test for: 5xx triggers retry, 4xx does not, mutation calls bypass retry, max retries respected.

T10. No end-to-end integration test

Nothing exercises the full pipeline: Django function defined → schema exported → codegen runs → generated React mounts → mutation fires → server response includes invalidate → kernel refetches → DOM updates. Each layer is tested in isolation.

T11. No tests for isValid requiring all required fields touched (H13 fix unverified)

The forms fix checks field.required && !touched but no test exercises a form with untouched required fields to confirm isValid === false.

T12. No tests for _meta fresh-dict isolation (H10 fix unverified)

The shared-dict fix replaced {**FunctionWrapper._meta, **meta} with {**meta}. No test confirms that mutating one function's _meta doesn't leak into others.