Spaces:
Runtime error
# Animetix - History of Refactorings & Achievements
This document archives the major milestones of the project's technical evolution.
[2026-07-11] Session: Coverage blind spots closed — the modules the 76% global was hiding, gate ratcheted to 76
Closure of the 🟠 audit item "métier critique quasi non testé sous un gate à 1,45 pt de marge". The item's headline recommendation ("tester Stripe billing en priorité") was stale — stripe_billing.py no longer exists (Stripe was removed from the project; the Pro tier is free/manual). The other five blind spots were real and are now covered with behavior tests (52 new tests, no filler):
| Module | Before | After |
|---|---|---|
| alert_service.py (live: the hourly-health-monitoring Cloud Run job calls it) | 0 % | 100 % |
| validation_gate.py (the HITL gate staging every synthetic gold entry) | 0 % | 100 % |
| semantic_cache_service.py | 31 % | 100 % |
| games/quiz_who.py | 23 % | 98 % |
| games/animinator.py | 26 % | 97 % |
The tests pin real behavior, not lines: drift/latency alert thresholds are strict (> 5.0s, not >=), the HITL gate caps an unsafe entry's score at 0.2 and prefixes its critique, the semantic cache short-circuits the embedding call on an exact hit, and Animinator's PaymentRequired is raised outside the view's try/except so an empty wallet returns 402, not a swallowed 500.
Gate ratcheted 75 → 76 (ci.yml + pyproject.toml, kept in lockstep): only tests were added (no source touched), so the global could only rise — the ratchet locks the gain in rather than leaving the margin to be eroded silently. Residual (tracked in TODO): the stateful undercover WebSocket consumer (38 %).
[2026-07-11] Session: CI topology untangled — unit feedback no longer waits on the Docker build, real-API perf-test off the push path
Closure of the 🟠 audit item "topologie fragile". Four targeted changes to ci.yml, no job removed:
testno longer needsdocker-build(a slow or broken image build starved all unit feedback); docker-build stays a hard deploy gate viadeploy-to-prod's ownneeds.frontend-testdecoupled from docker-build after verifying the claim: Playwright'swebServerspawnsnpm run devitself — the e2e job never touches the image.perf-testgated onworkflow_dispatchonly: it hits real Gemini/OpenAI APIs, so it no longer costs money (or flakes) on every push/PR. The prod deploy is dispatch-only, so its perf-test gate is preserved unchanged — on push the skip cascades into deploy-to-prod, which was already skipped there.- Ollama model cache:
ollama serveruns as the runner user, so~/.ollamais cacheable — the qwen2.5:0.5b blob (~400 MB) was re-downloaded from the ollama registry on every integration run; with a warm cache the pull is a manifest check (static cache key: blobs are content-addressed).
Push/PR runs now fan out test/integration-test straight after lint and start both frontend jobs immediately. Effects measurable on the next push.
[2026-07-11] Session: Guardrail fail-open made explicit and switchable — the "swallowed exceptions" half of the audit item was wrong
Closure of the 🟠 audit item "exceptions avalées dans les adapters d'inférence, dont le guardrail (fail-open)" — by correcting the audit on its first half and fixing the real risk in its second:
- The "~14 + ~4×5 + 6 silent
except: pass" count is false: an AST sweep of the 7 named files found zero silent handlers — every one of the 63 handlers logs (google_genai 20/20, brain_api 34/34, guardrail 6/6, …). The 2026-07-10 observability pass had already covered them; the audit likely countedexceptblocks, not silent ones. - The fail-open concern was real though: on a moderation-engine outage, guardrail_service.py
validate_input/validate_outputreturnedis_safe: Truewith only a soft log — indistinguishable, for callers, from a genuine pass. The deterministic layers (jailbreak regex, base64 probing, system-leak fingerprinting) run before the engine call and stay active, so full fail-open never applied to known attack patterns — a defensible availability tradeoff, now made explicit: the failure response carriesdegraded: Trueand logs at ERROR ("FAIL-OPEN — only the deterministic checks covered this request"), and a newGUARDRAIL_FAIL_CLOSEDflag (settings.py, env-gated, default off) flips the posture to blocking without a code change (string-parsed defensively since EnvConfig returns raw env strings —"false"stays falsy, locked by test). TDD: 4 locks watched fail (missingdegradedkey,is_safenot flipping) before the shared_engine_failure_responseexisted. Full suite green.
[2026-07-11] Session: Prod deploy gets a smoke test — and a design where rollback is never needed
Closure of the 🟠 audit item "aucun smoke-test ni rollback". Rather than the audit's suggested deploy→check→rollback (which leaves a bad-revision window), the deploy job now uses Cloud Run's no-traffic pattern — traffic never moves to an unverified revision, so there is nothing to roll back:
gcloud run deploy --no-traffic --tag candidate: the new revision boots without serving, reachable only via the tagged URL (which also bypasses the Cloudflare custom-domain worker).- Smoke test: up to 30×10s retries on
<candidate-url>/healthz/(first hit cold-starts the container, which runs migrate + collectstatic before gunicorn — a broken migration or missing secret fails right here). On failure the job dumps the revision logs and exits; the previous revision keeps serving. - Only on green:
update-traffic --to-latest.
New endpoint healthz (/healthz/): a plain Django view — deliberately not DRF (the anon throttle must never 429 the deploy gate, locked by a 30-hits test), registered outside i18n_patterns (an unknown path 302s to /fr/... via the locale catch-all — caught by the RED test). TDD: both tests watched fail (302) before the route existed. The flow itself gets its first real exercise at the next manual prod deploy (gh workflow run ci.yml -f deploy_to_prod=true).
[2026-07-11] Session: Monolithic lockfile split — one lock per Docker image, CUDA out of the web image
Closure of the 🟠 audit item "splitter le lockfile monolithique (image web obèse)". Investigation corrected two audit assumptions before designing the split: the 8 Cloud Run jobs all run the web image and genuinely import torch/transformers/sentence-transformers/peft/trl in-process (train_vibe_*, continuous_pretraining, train_expert_model) and shell out to the dbt CLI (rlhf_pipeline) — so the training stack must stay on web; and five pinned packages are imported nowhere repo-wide (ultralytics, manga-ocr, onnxruntime, opencv-python-headless, torchvision — cv2 has zero imports), whose removal also retired the GUI-vs-headless opencv uninstall dance in all three Dockerfiles.
- Layered locks (canonical pip-tools pattern): requirements.in stays the single place versions are pinned → union
requirements.txt(dev/CI, unchanged workflow); requirements-web.in / requirements-brain.in / requirements-dataflow.in list unpinned names constrained by-c requirements.txt, so image locks can never drift from the tested union. Compiled: web 206 pins (Django + jobs stack, no beam/diffusers/coqui/fastapi), brain 128 pins (FastAPI GPU serving, no Django — verified against the brain_service import closure), dataflow 224 pins (-r web+ apache-beam pinned in lockstep with the Beam SDK base image). - CUDA out of web and dataflow: both Dockerfiles now pre-install
torch==<lock pin>from the PyTorch CPU index before the lock install (the+cpuwheel satisfies the==pin, so pip never pulls the multi-GB nvidia-* wheels) — the same trick CI has used all along. The brain image keeps CUDA torch on purpose (it is the only image running models on GPU). - Union slimmed: dropping the 5 dead top-levels removed 18 pins (incl. the GUI opencv-python that ultralytics forced in) via a no-churn recompile (existing pins preserved). CI/security-audit pre-install lines lose the dead torchvision.
- Validated: old-union-vs-web set difference reviewed name by name (the 69 absentees are all transitives of dropped packages — librosa/matplotlib/einops/tensorboard have zero backend imports), and each lock dry-run-resolved on the actual image Python (web/dataflow on 3.12, brain on 3.11) in Docker.
- The two never-locked lazy imports resolved differently:
colpali_enginematches the real colpali-engine API (ColPali/ColPaliProcessor, verified by import) and is now shipped (union + brain locks) — this forcedpeft0.13.2 → 0.17.1 (no colpali release satisfies both peft 0.13.2 and transformers 4.57.6; bump validated by the full suite).moshi, however, turned out to be aspirational code:from moshi.models import Moshinames a class that does not exist in the real package (API:loaders/LMGenstreaming) — the local S2S path never worked, adding the package cannot fix it, so it is deliberately not added; rewrite-or-delete tracked in TODO.
[2026-07-11] Session: Agentic RAG pipeline goes async-only — sync twin path deleted
Closure of the last residual of "exposer le streaming async aux endpoints HTTP" and of the 2026-07-11 audit item "duplication sync/async dans agentic_rag_service" (the same root cause seen from two angles). The pipeline maintained two full orchestration paths: plan_and_solve_stream (144 l.) / 162 l.) twins in the service, aplan_and_solve_stream (run_workflow/arun_workflow twins in the orchestrator, and sync+async twins inside FallbackRagProcessor and SynthesizeProcessor — a fix in one could silently miss the other. The async path is now the single implementation:
- The 8 one-shot processors (Plan/Research/Judge/Acquire/Speculate/VlmRerank/GraphExplore/SagaLookup) are native
aprocessasync generators — each blocking collaborator call goes throughawait asyncio.to_thread(...), and the elaborate per-processor queue/producer thread bridge in base.py is gone (aprocessis the abstract contract; next state travels viactx.next_state). - Deleted:
StateProcessor.process,RAGOrchestrator.run_workflow,AgenticRAGService.plan_and_solve_stream(sync), and the sync halves of fallback/synthesize (~350 lines of duplicated orchestration). arun_workflow also resetsctx.next_statebetween hops so a forgetful processor falls back to FINALIZE instead of replaying the previous transition (locked by test). - Sync consumers kept working through one facade: every sync caller was one-shot (collects the whole stream, never streams incrementally) —
plan_and_solveremains sync but now drives the async stream viaasync_to_sync(new publicaplan_and_solvealongside); the B2B DeveloperRAGView andbenchmark_quality_v2.pydrainaplan_and_solve_streamdirectly. The SSE views were already on the async path — WSGI and ASGI consumers now share one code path. - Test migration (~20 files, ~100 call sites): new helpers tests/helpers/async_stream.py (
collect_async,as_async_iter,consume_aprocess) and an automatic factory shim (agentic_rag_factory.py) that gives MagicMock engines/llm a realastream_generatebridging their test-configured syncstream_generateat call time — most existing mocks kept working unchanged. TDD: the two new behaviors (sync facade drives async; developer view consumes the async stream) were locked RED-first with mocks that raise AttributeError on the retired sync attributes.
Full suite green.
[2026-07-11] Session: Inference-adapter dedup residual closed — RerankMixin retired, load semantics unified
Closure of the last open sub-item of "duplication entre adapters d'inférence" (2026-06-22 architecture review). Investigation showed the residual had shrunk since the item was written: the June composition pilot had left two verbatim copies of the rerank logic (RerankComponent used by UnifiedInferenceAdapter, plus the original rerank_mixin.py kept alive by a single consumer). Fixed by finishing the migration instead of patching the duplicate:
RerankMixindeleted —RerankComponentis now the single rerank implementation; LocalRerankAdapter composes it like Unified does. Bonus correctness: this adapter has no LLM, so the component getsgenerate=Noneand the prompt-based fallback is disabled cleanly instead of being discovered through a raisinggenerate(). A tombstone test asserts the module stays gone.- CrossEncoder load unified on
LazyLoadMixinand its revision pinned viaget_verified_revision(the SHA was already in the model registry but the loader ignored it — the last unpinned hub download in the adapters).on_error="raise"feeds the existing prompt/zeros fallback chain unchanged. LocalTextAdapter.get_text_embeddingmoved to the same_lazy_load(on_error="raise")motif: a broken SentenceTransformer load now surfaces asInferenceErrorlike every other local model load, instead of leaking a raw RuntimeError.- Model names centralized:
RERANKER_MODELandLOCAL_EMBEDDING_MODELjoin local_models.py (env-overridable), removing the last duplicated literals. LocalGuardrailAdapter(no model, as the item noted): health payload aligned on the shared_health_statusbuilder — cosmetic.
TDD: 4 regression locks written first and watched fail (component composition, pinned revision, InferenceError semantics, module tombstone). Full suite green.
[2026-07-11] Session: Settings hardening — Cloud Run tripwire, TLS-by-default Redis, consolidated GCP defaults
Closure of the 🟢 item "défauts d'infra codés en dur" (2026-07-05 audit), with each concern addressed at its root:
- "Toute la sécurité repose sur
DJANGO_ENV=production" → a fail-fast tripwire: Cloud Run always setsK_SERVICE/CLOUD_RUN_JOB, so booting there withoutDJANGO_ENV=productionnow raises instead of silently running withDEBUG=Trueand the dev SECRET_KEY (verified live that the web service and jobs all carry the variable — the guard only fires on real misconfiguration). DevDEBUGalso became env-overridable (DJANGO_DEBUG). ssl_cert_reqs: Noneonrediss://→ investigated live first: the prodREDIS_URLis plainredis://(in-VPC), so the insecure branch was dormant. Flipped to secure-by-default:REDIS_SSL_CERT_REQS=requiredunless explicitly set tonone(legacy escape hatch), mirrored in channels_config.py via a new parameter (TDD: the channel-layer tests were rewritten to the new contract first and watched fail).- Duplicated hf.space/service-account literals → the audit overstated this (all were already env-overridable); the real issue was repetition: a single
SERVICE_PUBLIC_BASE_URLnow derives the 4 GCP callback-URL defaults, and the tasks-invoker SA email is defined once (it was read twice with duplicated literals, including as the Cloud SQL IAM user). - Startup
print()s →logger.info(Redis-fallback and Sentry-init messages).
[2026-07-10] Session: Model registry Phase 2b — local logical ids centralized, models_registry.py residual merged
Closure of the last 🟡 item ("noms de modèles hardcodés", 2026-06-22 architecture review — Phases 1/2a shipped earlier). core/utils/local_models.py (which already held the 5 divergence-prone roles) gained three more env-overridable logical roles — LOCAL_VLM_MODEL, LOCAL_VIDEO_VLM_MODEL, SMALL_TRAINABLE_MODEL — and the 14 remaining hardcoded local-model literals were replaced by registry constants: the 7 repeated FLUX fallbacks in image_gen_mixin, the Qwen3-VL defaults (adapter + video analysis), the Qwen3-0.6B student defaults (distillation + akinetix RL DPO ×2), the image-worker id reported by the health dashboard, and the bare "qwen3.5" tag the synthetic gold generator sent to Ollama (now the canonical qwen3.5:9b). Residual merge: ModelIntegrityVerifier (safetensors anti-pickle/RCE guard + trusted-author list) moved from pipeline/models_registry.py into core/utils/model_registry.py so every model-loading security policy lives in one module; the pipeline file is now a thin lazy loader importing it. New anti-literal tripwire tests/security/test_no_hardcoded_local_model.py (mirroring the Gemini guard, written first and watched fail with the 13-offender list) allowlists only the registries/catalogs whose purpose is to enumerate ids. Full suite green.
[2026-07-10] Session: Migration squash finalized — 48 original files purged
Closure of the 🟡 item "squash des migrations : purge des originales". The gating condition was verified live first: showmigrations against prod Neon shows 0001_squashed_0049 recorded as applied. Adjacent find fixed along the way: 0050_siteconfiguration (the maintenance-mode table) was NOT applied on Neon — applied during the session (additive CREATE TABLE), so the next prod deploy of the maintenance feature won't 500 on a missing table. Then the standard Django finalization: the 48 original migration files deleted (numbering skipped 0017), the replaces list and the stale copy-these-functions header removed from the squash (all its RunPython functions were already local). Validated: makemigrations --check reports no drift, and a test database built from scratch via pytest --create-db runs green on the squash alone — the fresh-DB setup speed win the squash was made for. Full suite green.
[2026-07-10] Session: User→Profile signals consolidated — write amplification and legacy-user crash gone
Closure of the 🟡 debt item "signaux dispersés + write amplification". The two models.py receivers were replaced by a single ensure_user_profile in signals.py (now the one home for every receiver, wired by AnimetixConfig.ready()): the profile is created with the user, lazily recreated on the next save for legacy/bulk-created users (bulk_create skips signals — the old save_user_profile raised RelatedObjectDoesNotExist there), and never rewritten otherwise — the old pair emitted one full-profile UPDATE on every User.save(), i.e. one wasted write per login (last_login). Verified first that no call site relied on the hidden "user.save() persists profile mutations" contract (all 7 user.save() sites touch User fields only). TDD: 3 regression locks written first and watched fail (test_user_profile_signal.py — creation, no-profile-write via query capture, lazy healing).
[2026-07-10] Session: brain_api.py was never dead — renamed to brain_service.py to kill the trap
Closure of the 🟡 debt item "module mort brain_api.py (539 lignes)" — by correcting the audit, not by deleting. The file is the FastAPI entrypoint of the standalone GPU "brain" Cloud Run service, launched by deploy/Dockerfile.brain (uvicorn adapters.inference.brain_service:app); it is "imported nowhere" in Django precisely because it belongs to another service — deleting it would have killed the brain on the next image build. The item's underlying concern was real though: the near-identical name with the consuming adapter (brain_api_adapter.py) was confusing enough to fool the audit itself. Fixed at the source: module renamed to brain_service.py (Dockerfile CMD, the two dedicated test suites and the B104 security test updated in the same commit, so the next brain image stays coherent; the currently deployed image is untouched), plus an explicit module docstring stating its role and the historical misflag. 124 brain-related tests green.
[2026-07-10] Session: Silent exception swallowing eliminated from the runtime paths
Closure of the 🟡 debt item "exceptions avalées à grande échelle" (2026-07-05 audit). The inventory corrected the audit twice over: the ~168 except Exception log-and-continue handlers had already been AST-audited in June (legitimate defensive code — they log), and of the "77 silent pass" only 11 real silent handlers remained in the backend runtime (the rest sat in tests/scripts or had been fixed since). All 11 made observable, zero behavior change:
- Flagship fixes (both named in the audit): the Undercover consumer's public-lobby index registration now logs a
warningwith the room code and traceback when the state store fails (a room silently missing from the lobby was invisible); ReachabilityHealthCheckMixin's best-effort health enrichment now logs adebugwith the engine name (200 still never downgraded). Both files gained module loggers; both behaviors locked by logger-mock regression tests (test_undercover_index_logging.py, mixin suite) — caplog can't be used since the project logging config doesn't propagate to root. - Narrowed: the Vertex pipeline timestamp fallback (
except Exception→(TypeError, ValueError, OSError, OverflowError)+ debug). - Made observable (debug): temp-YAML cleanup failure, optional-telemetry ImportError, AniList-id metadata fallback, and the 6 user-input coercions (daily-date params in classic/dashboards,
intensity_multiplier/tau_plus/tau_minusin the Singularity lab) — all deliberate fallbacks, now visible.
Sweep verified: 0 silent except: pass left in backend runtime code; 170 tests green across the touched suites; ruff clean.
[2026-07-10] Session: Service locator eradicated from the view layer — constructor injection everywhere
Closure of the 🟡 debt item "service locator au lieu d'injection" (2026-07-05 audit). The view layer resolved services through 49 get_container() call sites (~158 container.x.y() expressions across 20 files); all converted to dependency_injector constructor injection (@inject __init__ with Provide[Container.<sub>.<service>] defaults, the house pattern already used by MediaSearchView/Suwayomi/ToT), including the 5 native-async SSE views in streams.py and the function view run_vs_battle (@inject on the function). apps.py wiring extended with the 5 modules that were missing (cognition, developer, monitoring, streams, games.vs_battle).
ProviderDelegatemonkey-patch deleted (containers/__init__.py): its 8 flat root-container shortcuts had 10 real consumers (scripts benchmark/curation/verify,run_red_teaming, codemanga consumer, 3 evaluation pipelines,regression_benchmark) — all migrated to the explicit sub-container paths (container.core.x(),container.agentic.y(), …).- Latent prod breakage found and fixed: creative_tasks.py called five flat services (
studio_transform_service,manga_flow_service,soundscape_service,spatial_computing_service,fusion_service) that never existed on the root container nor among the delegate shortcuts — every one of those task paths raised AttributeError in production and only passed in tests because the whole container was mocked. Now routed throughcontainer.core.*. Similarly,pre_flight_check'sif not container.neo4j_manager:guard could never trigger (a delegate instance is always truthy) — it now checks the resolved port. - Dead code removed:
views/common.pyshrunk to its logger — theLazyServiceProxyshim and its 9 service proxies resolved flat attribute names that don't exist on the root container (broken since the sub-container split) and had zero consumers. - Canonical test pattern switched: mocking
module.get_containerreplaced by real-container provider overrides (container.core.x.override(mock)+ provider-levelreset_override()infinally) or, for directly-instantiated views, passing mocks as constructor kwargs — ~20 test files migrated. The genericmock_containerfixture no longer pre-seeds misleading flat attributes. - Accepted residual: the 4 WebSocket consumers (undercover, codemanga, duel, speech_to_speech_live) keep a
get_container()call each — long-lived stateful objects where per-connection constructor injection buys little; their accesses now use the explicit sub-container paths.
[2026-07-10] Session: Profile.rank defined — authenticated /config/ no longer 500s
Closure of the 🟡 item "Profile.rank n'existe pas". Empirical reproduction confirmed both halves of the finding: ProfileSerializer.rank (a ReadOnlyField with no matching model attribute) silently serialized to nothing — which is why the leaderboard and /auth/me never crashed and the frontend showed its 'Explorateur' fallback — while the authenticated GET /api/v1/config/ genuinely crashed with AttributeError: 'Profile' object has no attribute 'rank' (500 on every authenticated call, critical now that the maintenance-mode frontend polls this endpoint). Root cause: the ranked ladder existed only on the domain entity (UserProfile.rank_label — zero consumers, dead code) and was never bridged to the Django model. Fix at the source: the ladder extracted into rank_label_for(ranked_points) in entities/user.py (single source of truth, the entity property delegates), and Profile.rank added as a property using it. TDD: 10 regression locks written first and watched fail with the AttributeError (test_profile_rank.py — ladder thresholds, serializer exposure, endpoint 200), the artificial patch(..., create=True) in the config coverage test removed in favor of asserting the real value ("Bronze 🥉"). 152 tests green across the impacted suites.
[2026-07-10] Session: API god-files decomposed — api/labs.py and api/core.py split into domain packages
Closure of the 🟡 debt item "fichiers-dieux dans la couche API" (2026-07-05 audit). Both worst runtime offenders are now domain packages whose __init__ star-re-exports keep the public surface intact (the api_views.py aggregator and every URL keep working unchanged):
api/labs.py(1262 lines, 25 views) →api/labs/:dashboards(daily challenge, latent space),singularity(evolving-AI actions, LNN, ToT, command center, neural diagnostics),manga(clean/translate/voice),video(FateZero, Video-RAG),audio(seiyuu, voice ingest/clone, soundscape, S2S),spatial(image/video→3D).api/core.py(1234 lines, 25 views) →api/core/:accounts(login/logout/register/me + game session),media(search, detail, signed image proxy),config(app config incl. maintenance mode, transparency report),manga(chapters, favorites, tracker sync),suwayomi(proxy + sources/search/import/extensions).- DI wiring (apps.py) now lists the 11 domain submodules; ~15 test files'
@patchtargets repointed to the submodule that defines each view (shared helpers like_container_patch/GET_CONTAINERparametrized per domain). - Latent bug fixed by the move:
DailyChallengeDataView's authenticated branch didfrom ...models import DailyResult— from the old monolith (packageanimetix.api) that 3-dot relative import climbed beyond the top-level package and raised ImportError (→ 500) on every authenticated daily-challenge request. Inside the newanimetix.api.labspackage it resolves correctly toanimetix.models; a regression test creating a realDailyResultlocks the path. - Also fixed 4 pre-existing test failures along the way (3 diagnostics tests + the anonymous config test lacked
django_dbwhile the views traverse middleware/SiteConfigurationDB reads). The impacted suites went from 166 passed / 3 failed to 170 passed / 0 failed; ruff clean. The API layer no longer has any file > 500 lines except the flat URL table (urls/api.py); the remaining big files are offline pipeline/mlops scripts, outside this item's runtime scope. Side-finding tracked in TODO:Profile.rankis consumed by ConfigView/ProfileSerializer but not defined on the model.
[2026-07-10] Session: List-endpoint N+1s fixed (TDD) + broken public-profile endpoint repaired
Closure of the 🟠 debt item "N+1 quasi garantis sur les endpoints listes" (2026-07-05 audit). The inventory corrected the audit: most list endpoints were already optimized (club list/feed/friends/leaderboard/user-search in social.py, manga favorites via a correlated-subquery annotation in core.py, explore, world_boss) — notably members.count() on a prefetched M2M uses the prefetch cache on this Django version, so the club list was sound. Three real N+1s remained, each fixed test-first with a scaling assertion (query count captured on 2 rows, dataset grown, count must be identical — tests/api/test_query_counts.py, 5 locks):
ProfileDetailViewtop/recent fusions (19 → 34 queries observed):CreativeFusionSerializerreadscreator.username+likesper fusion →select_related("creator")+prefetch_related("likes")(the serializer was already prefetch-aware).- VS Battle arena list (7 → 31 queries):
VsBattleSerializerreadscreator.username, thelikesM2M field,likes.countandis_likedper battle →select_related("creator")+prefetch_related("likes")on the view, andget_is_likedmade prefetch-aware (user in obj.likes.all()), matching theCreativeFusionSerializerhouse pattern. - AI feedback history (mlops.py, 3 → 11 queries, up to 100 rows):
usernameper row →select_related("user").
Bonus real bug surfaced by the RED phase: ProfileDetailView crashed with a 500 on every request — user.user_achievements is not a valid reverse accessor (UserAchievement has no related_name; it's userachievement_set). A coverage test even asserted the 500 as "known bug". Fixed the accessor and rewrote the test to lock the correct behavior (200 + achievements/fusions payload). 113 tests green across the impacted suites (social, mlops, vs_battle, query-count locks).
[2026-07-09] Session: Post-leak hygiene closed — secrets mounted on animetix-web + pre-exclusion registry purge
Closure of the 🔴 item "secrets manquants sur animetix-web + hygiène post-fuite" (follow-up of the 2026-07-05 .env remediation), except the two dead-key revocations which stay tracked in TODO.
- Secrets on the web service: verified already mounted (fixed by a later deploy since the 07-05 finding) — the live revision
animetix-web-00043-t7vreadsHF_SPACES,HUGGINGFACE_API_KEY(→HF_TOKEN),NEO4J_URI,NEO4J_USERandNEO4J_PASSWORDfrom Secret ManagersecretKeyRefs; no literal env values remain besides non-sensitive config. - Artifact Registry purge: deleted the 33
animetix-repo/webimages predating the 2026-07-05.envexclusion (26 untagged localgcloud builds submitbuilds — the actual at-risk set, one of which had even served revision00036— plus 7 clean-but-obsolete CI builds tagged by commit SHA). Only the 5 post-exclusion July images remain, including the servinglatest. Prod verified healthy after the purge. Side effect (accepted): Cloud Run revisions older than 2026-07-04 can no longer cold-start — they were inert at 0 % traffic.
[2026-07-09] Session: Playwright e2e suite consolidated and actually running
Closure of the 🟡 debt item "les e2e Playwright ne tournent nulle part" (2026-07-05 audit): npm run test:e2e filtered on --grep @e2e but no spec carried that tag (0 tests selected), and CI only ran a11y.spec.ts. The suite was consolidated onto the Playwright TS specs, dropping the redundant Python e2e harness (7dde6d05); stale routes and bad mocks in the a11y/vrt specs were fixed (9724600d). Actually running the flows surfaced real bugs: an apiClient crash on null Firebase auth hit by the akinetix e2e (1c93b6f3) and 3 WCAG AA contrast violations on LabHubPage (92fb6a81), both fixed.
[2026-07-08] Session: Dev dependencies out of the prod lock, migrations squashed, HF deploy workflow repaired
- Dev dependencies embedded in the prod image (🟠 closed): requirements.in mixed pytest/pytest-playwright/playwright/watchdog/coloredlogs into the prod lock (playwright pulls a whole browser stack). 9 dev packages moved out to
requirements-dev.{in,txt}(layered via-c requirements.txt); the 3 Docker images slim down with no behavior change; the 3 pytest CI jobs install the dev lock. Commits22a12a30/6d045714/8294c9c8. - Migrations squash landed:
0001_squashed_0049_…created, with the redundantRenameIndexoperations collapsed so fresh DBs build (68fec496). Deleting the 49 original migration files once the squash is applied everywhere stays tracked in TODO. - HF deploy workflow repaired (🟠 closed): deploy_to_hf.yml now calls the real script path
scripts/deploy/huggingface/hf_deploy.py(it pointed at a non-existentscripts/deploy/hf_deploy.py, failing every trigger);hf_deploy.pyalso fixed to resolveproject_rootat the right depth so it findsdeploy/Dockerfile(ed30faca) and to skipcreate_repowhen the Space already exists, avoiding a 402 (ecbb9e3a).
[2026-07-07] Session: Debt-audit batch closure — frontend refactors, test hygiene, CI parity, infra-as-data, scripts & repo cleanup
Batch closure of 13 items from the 2026-07-05 debt audit, each verified.
Frontend
- God components (14 pages of 400-560 lines): refactored the three worst pages —
ForgePage.tsx,SynapticLabPage.tsx,UndercoverRoom.tsx. State and network/socket logic extracted into reusable hooks (useForge.ts,useSynapticLab.ts,useUndercoverRoom.ts); complex UIs split into modular presentational sub-components undercomponents/forge/,components/labs/andcomponents/games/. All unit tests and TypeScript typing green. - Two divergent WebSocket implementations (+2 bugs): fixed the assignment-order bug in
useSocket.ts(the « Connexion rétablie ! » toast now fires on successful reconnect) and alignednotificationStore.tsreconnection onuseSocket: 5-attempt cap, exponential backoff, no reconnect on voluntary close (code1000logout), info toasts, and timeout cleanup ondisconnect().
Tests
- Coverage asymmetry + blind spots: 25 targeted unit tests on the blind spots (
pipeline/movies,pipeline/games,pipeline/actors,adapters/infrastructure) → 78.83 % targeted coverage (above the 75 % gate); Ollama configured and the integration tests made blocking in CI. - 77 raw
sys.modulesmutations across 16 files: inter-test cleanup secured via a full snapshot/restore ofsys.modulesinconftest.py; module-levelos.environassignments in thebrain_apitest files replaced withsetdefault(no more temporal coupling); real 50 msasyncio.sleepreplaced withasyncio.sleep(0)intest_cove_parallel.py; shared global mock objects intest_s2s_inference.pymade per-test.
CI / DX
- pre-commit ↔ CI drift + fake frontend security audit:
.pre-commit-config.yamlnow runs mypy (--no-site-packages, matching CI) and pytest with the 75 % coverage bar, through cross-platformrun_in_venv.py/run_cmd.pyrunners; unified frontend hooks (lint-stagedon commit,viteston push); mypy brought to 0 errors on 515 files; thefrontend-securityjob now runs a realnpm audit --audit-level=high, and 12 vulnerabilities were fixed vianpm audit fix.
Infra
animetix.xyzmissing fromALLOWED_HOSTS/CORS defaults: the custom domain and its subdomains (.animetix.xyz) added to the production defaults ofALLOWED_HOSTSandCSRF_TRUSTED_ORIGINS;CORS_ALLOWED_ORIGINSmade env-driven with these domains as defaults.- Duplicated deploy logic, no IaC: single declarative source deployments.yaml centralizing all deployment parameters (GCP services, Cloud Run GPU, the 8 scheduled jobs, Load Balancer/CDN, Cloud Armor, the Cloudflare Worker and the HF Space); the 3 build files merged into a root cloudbuild.yaml supporting selective or global builds via
_BUILD_TARGET; the Python deploy scripts (deploy_brain.py,deploy_jobs.py,deploy_budget.py,deploy_cdn.py,deploy_security.py) now read fromdeployments.yamlinstead of hardcoded params;.gcloudignorealigned on.dockerignorevia#!include:.dockerignore(one canonical build context). - Scripts sprawl (~55 scripts): deleted
scripts/test/(7 non-pytest exploratory scripts); the DB utility scripts (Qdrant vector counts, migration checks, SQLite catalog checks, Neo4j reconciliation) promoted to Django management commands (check_db_status,reconcile_db,generate_offline_db);reconcile_dbbulk-loads (values_list+item_id__in, no N+1) and validates Neo4j connectivity once; non-ASCII console output stripped (WindowsUnicodeEncodeError).
Git / docs / hygiene
dev/null/versioned: removed the literal path and the 4 Git-LFS hooks accidentally committed via a Windows redirect (3df26086).- ~30 MB of raw PNG blobs (64 files):
*.pngnow auto-tracked by Git LFS in .gitattributes; the 64 existing PNGs converted in place to LFS pointers viagit add --renormalize .(history untouched). - Two contradictory TODOs + stale docs: deleted the duplicate
docs/TODO.md(the rootTODO.mdis the single source of truth); fixed thesetup_e2e.pypath in the README; replaced the Celery reference indocs/ARCHITECTURE.mdwith the active Cloud Run Jobs; updateddocs/FULL_GUIDE.mdanddocs/ROADMAP.mdfor the July 2026 features (drift detection, XAI transparency diagnostics, billing-budget safety). - Working-tree residues:
/src/added to.gitignore; verifiederror_latent.html/brainstorming_status.txtwere already ignored. - Misc cosmetic/hygiene: compiled
.motranslation binaries de-indexed and gitignored; the NOTICE file rebranded from « Double Scenario Project » to Animetix; Windows-onlysync-api.batreplaced by the cross-platformscripts/sync_api.py; redundantWSGI_APPLICATIONsetting removed (server is ASGI-only);frontend/.env.productionde-indexed and gitignored;downloadDatasetmigrated from raw XHR ontoapiClient(which gainedresponseType: 'blob'support);@extend_schemabound to the right serializers on the XAI audit endpoints (fixing schema-generation TypeScript errors).
[2026-07-07] Session: Removed all Stripe payment features
Purchasing Berrix (or a Pro subscription) via Stripe is no longer offered, so the payment code was removed end to end: the CreateBxCheckoutView / CreateProSubscriptionCheckoutView / StripeWebhookView endpoints, the StripeBillingService, the metered usage reporting in django_usage_adapter, the purchasable PACKS, the six STRIPE_* settings, the stripe dependency, and the three Profile Stripe columns (dropped via migration — to be applied to the Neon prod DB manually). The front had no live purchase path: NexusGatewayModal (the only priced component) was dead (test-only) and was deleted; PowerStation/Pricing already run on earned Berrix (rewarded ads + mining) and sponsor/donation. The tier (free/pro) concept stays: DeveloperSubscriptionMockView now simply sets tier="pro" for free. The Stripe-key log-scrubbing regex was intentionally kept.
[2026-07-06] Session: i18n externalization completed + dependency_injector wiring bug fixed at the root
- i18n (~500 hardcoded FR strings) (🟡 closed): the ~150 remaining files (labs, social, admin, media, search, dev) externalized with
t('key', 'FR default'); translation fragments generated and merged viamerge_translation_fragments.py; pre-existing key inconsistencies (games.akinetixvslabs.akinetix,labs.ai_debate_arena.protocol_text) resolved and verified bycompare_translations.py(100 % key parity). 611 vitest unit tests + type checking green. - Games conftest landmine (
dependency_injectorbug) (🟡 closed): fixed at the root independency_injector.wiring—_is_markerand theProvide/Provider/Closingtype checks switched to duck-typing and class-name comparison, resolving the multiple-import collision under test coverage. The skipped test intest_archetypist_coverage.pyrestored and fixed; full suite green.
[2026-07-05] Session: Prod WebSockets repaired (missing channels_redis) + CSS design tokens fixed
- Prod — WS 500 on every handshake (🔴 closed): root cause confirmed via Cloud Run logs (live repro, trace
b03e26f1…) —ModuleNotFoundError: No module named 'channels_redis'. The Redis channel-layer backend was selected wheneverREDIS_URLexists (prod), but the package was never in requirements; locally there is noREDIS_URL→ InMemory fallback → invisible. Fix:channels-redis==4.3.0added (lock regenerated without drift); channels_config.py extracted with a fail-fastImproperlyConfiguredifREDIS_URLis missing in prod (per-process InMemory breaks fan-out with 2 workers) and thessl_cert_reqs=Nonemirror forrediss://; regression tests in test_channel_layers.py (including theimport_stringtest that would have caught the bug). Deployed and verified live: the handshake returns101 Switching Protocols(re-checked 2026-07-09). Gotcha: WS routes need a trailing slash, else channels 500s with "No route found". - Frontend — broken CSS design tokens (comma-separated RGB triplets) (🟠 closed): the 23 tokens of index.css converted to space-separated triplets (
37 99 235) so Tailwind<alpha-value>consumption works. Verified in-browser:bg-brand-primary→rgb(37, 99, 235),bg-anime-accent/20→rgba(253, 185, 19, 0.2); the only other consumers (rgb(var(--color-bg))on body) accept both formats.
[2026-07-05] Session: Secured the anonymous AI/GPU endpoints + rationalized throttling
Closure of the 🟠 debt item on AllowAny AI endpoints. A precise inventory corrected the audit: 3 of the 4 named labs views (MangaLabDataView, AudioLabDataView, SeiyuuDiscoveryView) are CPU/DB and stayed public; the real anonymous GPU holes were the Speech-to-Speech Live WebSocket (a full Gemini Live session — now auth-gated with a flat 12-Bx per-session charge, a 10-minute cap, and the Firebase token passed via the Sec-WebSocket-Protocol subprotocol rather than the URL query string so it never lands in access logs), GraphWorldMapView (per-hit LLM community summaries, now a 24 h shared cache with an anti-stampede lock — the map is identical for everyone, so it stays public and bills no one), VideoRAGSearchView (now IsAuthenticated + 6-Bx via the canonical deduct_berrix pattern), and the guardrail's _llm_moderate fallback on MediaSearchView (now authenticated-only via an allow_llm flag; anonymous search keeps the heuristic layer). Throttling went from "daily cap or nothing" to two-speed: per-minute burst throttles (anon 30/min, user 120/min) added globally, the long-dead gpu scope wired to a real 30/hour rate, and a CpuGameThrottle (60/min) applied to every AllowAny CPU-game view (emoji/undercover/covertest + blindtest/classic/akinetix/quiz_who/animinator/archetypist/vision/world_boss), replacing the throttle_classes = [] overrides that had removed all protection. Two bugs caught in review: CpuGameThrottle initially inherited ScopedRateThrottle (whose allow_request reset the scope to None → a silent no-op) and was reparented to SimpleRateThrottle; and the WS token was first put in the URL (flagged HIGH by commit review) before moving to the subprotocol. Frontend login-gates added to VideoLab/VisualNexus/S2S pages.
[2026-07-05] Session: Unified the import namespace on the bare root
Closure of the 🟠 debt item "triple espace de noms d'import" (2026-07-05 audit). The same packages were importable as animetix / backend.api.animetix / backend.animetix (and core / backend.core, etc., plus a legacy src.pipeline alias in tests), because three sys.path roots (., backend, backend/api) coexist — Django genuinely loaded both identities in prod (settings mixed them inside MIDDLEWARE/AUTHENTICATION_BACKENDS) and middleware.py carried a runtime contextvars-sync hack between the module copies. Unified everything on the bare root (INSTALLED_APPS' identity, ~95% of the code already): ~31 files rewritten (imports, @patch targets, sys.modules keys, settings dotted strings), both compat hacks deleted (middleware sync, SrcPipelineMapper/AliasLoader in tests/conftest.py), standalone pipeline script headers cleaned of dead src/ path entries, and a 3-layer tripwire installed: backend/__init__.py now raises ImportError on any backend.* import (implicit-namespace-package-proof), ruff TID251 bans backend/src imports, and tests/test_import_hygiene.py scans for textual regressions.
[2026-07-05] Session: Removed the dead LLM text-to-SQL surface
Closure of the 🔴 debt item "SQL généré par LLM exécuté en base" (2026-07-05 audit). Exploration showed the whole chain was dead code: zero production callers (only the port, adapters and tests referenced it), ALLOYDB_NL_QUERY_ACTIVE=False by default, and prod runs on Neon where the native alloydb_ai_nl.get_sql path cannot execute — while the LLM fallback would have run with neondb_owner privileges gated only by a READ ONLY transaction. Decision (user-validated): delete rather than harden — removed query_data_natural_language from RepositoryPort and its three adapters, is_alloydb_nl_query_supported(), sql_guard.py (sqlglot AST validator), its fuzzing tests and scripts/verify/audit_sql_guard.py, the ALLOYDB_NL_* settings, and the sqlglot dependency. Everything is recoverable from git if the feature ever ships for real (spec: docs/plans/2026-07-05-remove-text-to-sql-design.md).
[2026-07-05] Session: Secret hygiene — .env can no longer reach the prod image or the HF Space
Closure of the 🔴 debt item "Prod — secrets réels embarqués dans l'image Docker" (2026-07-05 debt audit). Both leak channels are shut and verified:
- Cloud Build / Docker channel:
.envadded to .gcloudignore (verified withgcloud meta list-files-for-upload— only the placeholder.env.exampleremains in the upload context) and a root .dockerignore created (.env+**/.env, mirroring.gcloudignoreso local, CI and Cloud Build contexts match). The olddeploy/.dockerignorewas dead config — Docker only reads the.dockerignoreat the build-context root (the build isdocker build -f deploy/Dockerfile .) — and has been deleted. - HF Space channel: hf_deploy.py now enforces an unconditional
always_ignore = [".env", "**/.env", …]insidedeploy_space(), independent of the caller-supplied ignore list. - Actual exposure was narrower than feared: the current prod image (
web:5f8a0886…) was built by CI from a git checkout, which has no.env(untracked) → clean; the HF Space never received a.env(verified via the Hub API — the callers' ignore lists had worked). The residual risk was old Artifact-Registry tags built locally viagcloud builds submitbefore the exclusion, plus two dead-but-real keys in the local.env(TRIPO_API_KEY,MAPBOX_TOKEN— consumed nowhere in the code) → follow-ups tracked in TODO (purge old tags, revoke dead keys). Stripe/Cohere/Tavily/OpenAI values in.envwere already empty; the 8 Cloud Run jobs already mount all their secrets via Secret Manager andci.ymldeploys with--update-env-vars(merge), so nothing depended on the baked file anymore — except the web service's missingNEO4J_*/HUGGINGFACE_API_KEY, split out as its own open TODO item.
[2026-06-22 → 2026-07-08] Architecture-review follow-ups: model registry, adapter dedup, config validation, native async streaming
Progressive closure of 2026-06-22 AI-architecture-review items shipped across late June / early July (the residual sub-items stay tracked in TODO).
- Hardcoded model names — Phases 1 & 2a: security registry model_registry.py (model_id → pinned SHA + trust policy); Gemini unified on 3 canonical roles via gemini_models.py (
gemini-3.5-flash/live-2.5-native-audio/embedding-2) with an anti-literal guard; embedding revisions resolved from the centralEMBEDDING_VERSIONSregistry (manifest approach abandoned). Phase 2b (registry of local logical IDs +pipeline/models_registry.pymerge) stays open. - Inference-adapter duplication: API-adapter reachability
health_checkfactored into ReachabilityHealthCheckMixin; local-model readinesshealth_checkinto LazyLocalModelAdapter (all local-model adapters migrated); the multi-submodel_load_model()motif into LazyLoadMixin (ImageGenMixin/AudioMixin). Residual (RerankMixin,LocalTextAdapter.get_text_embedding,LocalGuardrailAdapter) accepted as out of scope, tracked in TODO. - Inference env-var validation (closed):
BrainAPIAdapterfails early (ConfigurationErrorifBRAIN_API_URLis missing, unified message, malformed-URL check); coherence guards forunified(LLM_API_BASEmalformed) andgoogle_genai(blankGEMINI_API_KEY) in their__init__; aggregated startup validation viavalidate_inference_config()(inference_config.py), wired into the container (inference.py). - Sync adapters → native async streaming (closed): native
astream_generate(non-blocking I/O) onUnifiedInferenceAdapter(httpx.AsyncClient/SSE),GoogleGenAIAdapter(client.aio) and async orchestration inFallbackInferenceAdapter; local models stay onInferencePort's default thread bridge. Multiple streams can now be parallelized viaasyncio.gather. (Documented caveat:UnifiedInferenceAdapter's_last_completiondiagnostics cache is best-effort under concurrent streams on the Singleton.) - Async streaming exposed to the HTTP endpoints (all shipped except the 8 one-shot processors, tracked in TODO): the 5 SSE views are now native async Django views (Animinator, Emoji, Paradox, ToT, AgenticRAG) sharing the
api/sse.pyhelper (check_rate_limit+sse_stream_response), freeing worker threads for the whole stream duration; ToT'sasolve_with_tree_of_thoughts_streamparallelizes each level viaasyncio.gather(first real gather win on remote engines); AgenticRAG got an end-to-end async pipeline (StateProcessor.aprocess,RAGOrchestrator.arun_workflow,aplan_and_solve_stream) with native-streamingFallbackRagProcessor/SynthesizeProcessor(asynthesize_stream);Cache-Control: no-cacheharmonized across the 5 views; 4 dead non-routed sync stream views removed with their tests; and the latent.textbug (stream chunks areInferenceResponseobjects) eradicated in every streaming consumer (emoji_service,paradox_service,fallback_rag_processor,synthesize_processor,AniminatorStreamView) with regression tests feedingInferenceResponse— the Oracle SSE endpoint works again.
[2026-06-25] Session: Architecture & Financial Review — Backlog Closure
Closure of the high/medium items raised by the 2026-06-22 AI-architecture and financial review (each shipped on its own branch; TODO trimmed back to open work only).
Resilience & security
- Neo4j single-point-of-failure (silent degradation): user-preference context (agentic_rag_service.py) and CoVe fact-checking (cove_oracle_service.py) silently fell back to empty when the graph was unavailable — aggravated by CoVe's bias of marking a real-but-absent fact as "unverified". Added an explicit fallback (ChromaDB/web) plus a degraded-state signal.
- Prompt-injection sanitisation (tag-breaking): the companion wrapped input in
<user_input>…</user_input>but didn't catch payloads that close then re-open the tag (</user_input>ignore previous<user_input>) (companion.py). Delimiters are now escaped/neutralised and validated beyond a pure regex. trust_remote_code=Trueon HF models: central allowlist (model_registry.py) maps model_id → pinned SHA +trust_remote_codepolicy; defaultFalse, only allowlisted models (jina, LightonOCR…) get it, pinned to SHA. All adapters (vlm/image_gen/…) + pipeline/scripts gate viaresolve_trust_remote_code(); a test guard forbids raw literals.
AI architecture
- Cognitive boosters in the prod RAG path:
advanced_rag_servicewiredquantum_cognitive_service+neuromorphic_lnn_serviceinto real reranking without proof of gain. Instrumented the path viaragas_eval_service(faithfulness/relevance) and ran ablations — kept what measurably helped, demoted the rest toward the Ghost Labs demos (reducing the maintenance + billed-GPU surface of a solo project). UnifiedInferenceAdaptergod object: 8 mixins / ~476 l. with a fragile MRO (unified_inference_adapter.py) refactored toward composition over multiple inheritance.FallbackInferenceAdaptergod object + central coupling: 30+ methods across 7 mixins mixing orchestration + fallback + health-check + capability-detection + reporting (fallback_adapter.py), with ~60 dependent services. Selection/health-check extracted from orchestration.- Companion long-term memory:
memory_servicewired via DI into companion.py — long-term memory retrieval + backgroundremember()+ persistence of evicted turns ({memories}slot in the personality prompts). - CoVe parallelised: claim verification now runs via
asyncio.gatherin cove_oracle_service.py. - Health-checks re-run on every orchestration → short-TTL cache: the fallback re-probed every adapter on each call. Added a TTL-throttled health refresh (fallback_adapter.py) — adapters are re-probed at most once per
FALLBACK_HEALTH_TTL_SECONDS(default 30 s) window, shared by routing (_online_adapters) and the publichealth_check(_cached_statuses). - API-adapter reachability
health_checkfactored into a mixin: the per-adapter HTTP-ping / client-init reachability probe (Brain HTTP/health, Google client-init, Unified Ollama/OpenAI) extracted into ReachabilityHealthCheckMixin — a standardized status builder + a generic probe driven by a caller-suppliedrequester(so each adapter keeps its own HTTP client and test patch targets).
Cost & viability (financial review)
- 24/7 fixed GPU → spot/serverless on-demand: the always-on L4/A100 cost 450–1 200 $/month regardless of traffic (docs/COST_AUDIT.md) — the dominant fixed cost, forcing ~30 000–80 000 ad-clips/month to break even. Migrated to on-demand spot/serverless GPU per §5.1‑5.2 of the cost audit, cutting the break-even threshold 3–5× (the n°1 viability lever).
- Brain GPU scaling bounds made explicit: deploy_brain.py left
--min/--max-instancesat Cloud Run defaults (implicit min=0, uncapped max=100). Pinned--min-instances=0(auditable scale-to-zero) and--max-instances=3(cost ceiling, aligned withrestore_brain_service); COST_AUDIT corrected — the "fixed GPU 24/7" premise was inaccurate. - Zero-margin "social equilibrium" model → minimum margin: the Berrix model recalibrated to zero margin (13/06) left no cushion for a GPU spike, an eCPM drop or churn. Restored a minimum 5–15 % margin to build a treasury cushion; the budget-alert webhook that scales the brain service to 0 on overrun stays as an anti-bankruptcy guard.
Frontend coverage
- Frontend test coverage broadened to 551 unit tests with ratchet floors at statements 29 / branches 22 / functions 28 / lines 29. Remaining (decreasing ROI, left open): complex 3D/canvas/WebSocket flows (
useTachideskExplorer,useSocket,useMultiverseCatalog).
[2026-06-22] Session: Typed inference-failure sentinel (drop the "Erreur" string heuristic)
Fix: brittle string-based fallback routing
FallbackInferenceAdapter decided an engine had failed by testing result.text.strip().startswith("Erreur") in both generate() and stream_generate(). Fragile and French-locale-specific: a genuine model answer that merely began with « Erreur… » (e.g. "Erreur 404 est un thème de Serial Experiments Lain") was misrouted to the next engine. Audit confirmed no production text adapter actually returned such a response — they all signal failure by raising (InferenceError / raise), which the orchestrator already catches — so the string branch was dead-but-harmful legacy.
- Added a typed sentinel
InferenceResponse.is_error: bool = False+ anInferenceResponse.failure(message)factory (ai_schemas.py). Adapters that prefer to soft-fail (without raising) now set the flag instead of relying on a magic prefix. FallbackInferenceAdapternow falls through onresult.is_error(not on the text prefix); the terminal "Échec critique" response is built via.failure(...)so total-failure is detectable downstream (fallback_adapter.py).- TDD: updated the two
*_erreur_*fall-through tests to drive the sentinel, added a regression test asserting an answer starting with "Erreur" is now returned as success, plus factory/default tests. Full related-suite run green (528 passed).
[2026-06-22] Session: API Hardening, RCE Guard & Constants/Broad-Except Cleanup
Cleanup: duplicated constants + bug-masking catch-alls
- Constants:
MAX_IMAGE_SIZEand the image/video/audio MIME allow-lists were duplicated (and drifting) betweenapi/core.pyandapi/labs.py. Centralized incore.constants; both import from there (image list unified to include gif; labs' dead duplicate constants dropped). - Broad
except Exception: AST audit of all 638 handlers showed almost all already log or return a deliberate fallback (legitimate defensive code). Only 3 silently swallowed; narrowed the 2 obvious ones (django_repository_adapter.get_creative_fusion→CreativeFusion.DoesNotExistso a repo no longer masks DB errors as "not found";regression_benchmark--thresholdparse →(ValueError, IndexError)). The ASGI event-loop-policy startup shim is an intentional best-effort guard, left as-is. No blind 638-site sweep (no value, risky).
Security: API stacktrace-leak + secure-by-default permissions
- Stacktrace leak: 27 endpoints returned the raw exception to the client on HTTP 500 (
Response({"error": str(e)}, status=500)), exposing internals (paths, SQL, …). Replaced the client body with a generic"Internal server error"and log the detail server-side vialogger.exception(...)— across 11api/*modules plustasks_viewsandviews/billing. 4xx validation responses (intentional user feedback) were left intact. - Permissions secure-by-default: DRF
DEFAULT_PERMISSION_CLASSESwasIsAuthenticatedOrReadOnly, making every endpoint world-readable unless overridden. Flipped toIsAuthenticated. An AST audit of all 142 views found only 8 relying on the default; the genuinely public ones now declareIsAuthenticatedOrReadOnly(Multiverse gallery/catalog/export-PDF, AchievementViewSet) while internal/control views (monitoring, observability) tighten. The 3@api_viewfunctions andAIFeedbackAPIView(usesget_permissions) already scoped permissions explicitly.
Security: RCE guard on exec() of LLM-generated kernels
SelfEvolvingCompiler.compile_dynamic_kernelexec'd dynamic Python source, including code produced by an LLM (evolve_with_llm) — a prompt injection upstream could smuggle arbitrary code into the host (RCE). Addedassert_safe_kernel_source(): an AST gate rejecting imports, dunder attribute access (blocks().__class__.__subclasses__()escapes) and a blocklist of dangerous names (os/sys/subprocess/eval/exec/open/getattr…).execnow also runs with a restricted__builtins__(_SAFE_BUILTINS— only numeric helpers like range/len/abs/float) as defense-in-depth. Malicious kernels raiseUnsafeKernelError;evolve_with_llmswallows it and returns the null fallback (no execution). Legitimate numeric kernels unchanged; 13 new security tests.
[2026-06-22] Session: Frontend & Infra Sweep (data/LFS, fetch→apiClient, CI, deps, DX, a11y, coverage)
A batch of TODO items closed across data hygiene, CI, deps, DX and the frontend, each merged via its own PR.
- Repo data → Git LFS: the large tracked
data/processed/data/artifactsJSON (filtered/refined characters 40/30 MB, …) moved to Git LFS (consistent with the existing*.npyrule); the orphanclean_characters.json(24 MB, zero references) dropped. A history-rewrite purge of old blobs was left as a separate coordinated op. - Frontend
fetch()→apiClient: ~15 raw same-originfetch()calls migrated toapiClient(CSRF + Firebase auth + error toasts) — SearchBar image search (searchMediaByImage), billing ad-events (billingService.logAdEvent),useCustomConfig→utilsService.updateConfig, Monitoring/Financial pages, ExplorePage,useTachideskExplorer(9 calls, control-flow preserved), MangaLibrary. Binary/cross-origin asset fetches (AudioLabPage, MangaVoicePage, offlineLibrary, the image proxy) left as rawfetchon purpose; AudioLabPage got a failure toast. - AudioLabPage state: Quick Ingest form (5
useState+ validation + submit) extracted to a dedicateduseQuickIngestFormhook (14→9useState). SynapticLabJSON.stringify-in-render confirmed a deliberate React "adjust-state-during-render" pattern (left as-is). - CI:
concurrency.cancel-in-progress; pip wheel cache on the test/integration/perf jobs (no more ~800 MB torch re-download);timeout-minutes(45/30/30); corrected the stale coverage-gate comment (coverage is 75.33 %, gate live). - Deps:
requirements.infully pinned to the resolved versions (transformers, google-cloud-*, apache-beam, dbt-*) — lockfile byte-identical. Duplicateopencv-python(forced by ultralytics, needs libGL) dropped in all 3 Dockerfiles: uninstall both then reinstall headless from the lockfile. - DX: Prettier +
eslint-config-prettier(config + scripts + lint-staged, no repo-wide reformat), root.editorconfig, README Python3.11+→3.12+. - A11y & logs: 12 WebSocket
console.logrouted through a dev-onlylogger(no-op in prod) + ano-consoleESLint rule (warn/error allowed).<img>alt and admin accessible-names were already enforced. - Frontend coverage: covered the untested game/media services + react-query hooks (+28 tests, 492→520); ratcheted the v8 floors to statements 29 / branches 22 / functions 28 / lines 29.
[2026-06-22] Session: Hexagonal Boundary Repair (domain → infra) & Test-Home Consolidation
Hexagonal boundary violations fixed (domain no longer imports Django/animetix)
Three core-domain services reached across the hexagonal boundary into infrastructure. Each now depends on an injected port; the Django/ORM/middleware code lives in an adapter wired through the DI container.
manga_serviceimportedanimetix.models(MangaChapter/MangaPage/MediaItem) and ran ORM queries +get_or_createdirectly → newMangaRepositoryPort+DjangoMangaRepositoryAdapter. The port returns records as opaque objects (still real models, so DRF serialization is untouched) and mapsDoesNotExist→None; sync decisions / Suwayomi+mock flow stay in the service.voice_ingestion_serviceimportedanimetix.models.VoiceProfile+ContentFile/slugifyto persist the ingested sample → newVoiceProfileRepositoryPort+DjangoVoiceProfileAdapter; the service is now wired ascontainer.core.voice_ingestion_serviceand the labs view resolves it from the container instead of instantiating it directly.llm_servicereached intoanimetix.middlewareto resolve the ambient request user for the quota check → newUserContextPort+MiddlewareUserContextAdapter. Explicituser_id/tierargs keep priority; quota enforcement is preserved with no direct middleware import (avoids threading user_id through ~35 internal callers).- Verified: container wiring tests green,
llm_service/labs/manga-endpoint tests green, and none of the three core files import Django/animetix anymore.
Test scaffolding removed from production
AgenticRAGService.__init__shipped ~130 lines of test-onlyisinstance(..., Mock)scaffolding: it gave a mockllm_servicedefaultgenerateside-effects and rebuilt a realRAGOrchestrator(with all real agents) whenever a Mock orchestrator was passed. Extracted to a test factory (tests/helpers/agentic_rag_factory.py:build_test_agentic_rag_service) and migrated the 14 unit tests that relied on the implicit behavior. The production__init__no longer importsunittest.mockor branches onMock; behavior preserved (51 passed / 16 deselected unchanged, container wiring green).
Test-home consolidation
- Merged the historically-duplicated test homes (
tests/backend/core→tests/core,tests/backend/api→tests/api,tests/pipeline_logic→tests/pipeline) viagit mv— pytest collection unchanged at 2313 tests, history preserved. Purely organizational (discovery istestpaths=tests).
[2026-06-21] Session: mypy Type-Debt Elimination, Frontend Coverage Campaign & CI Hardening
Typing (Élevés)
- mypy type-debt baseline 105 → 0 modules: the
[[tool.mypy.overrides]] ignore_errorsblock was removed entirely —cd backend && mypy .is fully green on ~474 files with no per-module ignores. Done in a clean CI-equivalent venv (pip install mypy→ 2.1.0); the project venv can't run mypy/black locally due to a dbtpathspec<0.13pin. ML lazy-Noneinference adapters typed (self._model: Any = None), Djangoadminmodernized (@admin.display/@admin.action),lazy_import(ModuleType proxy) + a Django logging filter carry targeted# type: ignore[...],emoji_servicetyped honestlyList[str] | str. - Streaming contract harmonized on
dict:StateProcessor.process→Generator[dict, None, RAGState], orchestrator simplified (all processors are generators). These 11 errors were breaking CI mypy. - 8 runtime bugs surfaced by strict typing: missing
SimilarityService.find_similar_items(AttributeError) + undercover None-guard;fallback_adapterraise eafter the exception var was deleted (NameError);trl_opscalling a non-existentexport_preference_dataset(a mock hid it);advanced_vision.vlm_reranktreating dicts as int indices (TypeError);tree_of_thoughtsmissing.text;validation_gate-> (str, float)(tuple-value, not a type); deadSampleViewref;django_repository.get_nearest_neighborsreturning[]against anOptional[Dict]port. Several latent None-derefs guarded along the way.
Frontend test coverage (18% → 29%, 188 → 492 unit tests)
- Added
vitest --coveragetooling:test:coveragescript, v8 config (text/html/lcov, include/exclude), anti-regression ratchet thresholds (now 28/22/27/28),coverage/gitignored. - 3 high-ROI campaigns (all behavior-only, no source changes): services/utils/hooks (+112), presentational components (+95), route-level pages (+97).
- Wired frontend unit tests + coverage gate into CI (
frontend-checksjob) — previouslyvitestnever ran in CI — plus a non-blocking Codecov upload (flagfrontend).
Other hardening
- Frontend state convention documented in
frontend/README.md(React Query = server state, Zustand = global/UI, useState = local); dead React Query game hooks purged; the "personalization duplication" was a false positive (/custom-config/vs/profiles/me/— distinct concerns). - Frontend perf:
loading="lazy"+decoding="async"on 54 content<img>(36 files); heroes/logos kept eager for LCP. Memo deliberately not broadened (no expensive in-render compute; already memoized where it matters). - Accessibility: the real scope was 115
control-has-associated-labelacross 68 files (not "a few") — all given meaningful FRaria-labels (+role/keyboard for non-native interactives,htmlFor/idfor labels); rule hardenedwarn→error. Also fixed the 23 pre-existing eslint errors →eslint .fully green. - MLOps logging centralized via
backend/pipeline/logging_setup.py(setup_logging(), single format); 11 inlinelogging.basicConfigcalls + 2 comment-only files migrated. - Playwright e2e: on-failure screenshot/video/trace, CI
Upload Playwright artifactsstep, GitHub reporter (Chromium-only kept by design for the single a11y spec). - k6 load test: replaced the unrealistic global
p(95)<500with tagged per-endpoint thresholds (search/game/rag/ws); added a manualworkflow_dispatchload-test.yml(the test needs a deployed target + incurs LLM costs, so not a PR gate). Dockerfile.dataflow: removed a redundant, UNPINNEDpip install beautifulsoup4(already==4.12.3in requirements); documented why a HEALTHCHECK is inappropriate (Dataflow-managed) and how to digest-pin the:latestlauncher base.- Backend test organization: corrected the premise (no duplication —
tests/corevstests/backendare different layers); documented the "one home per layer" convention intests/README.md; physical consolidation deferred until thecoverage-consolidationbranch merges. - Security — leaked HF token: removed the hardcoded Hugging Face token from
scripts/deploy/deploy_jobs.py(moved to Secret ManagerHF_SPACES:latest); old token revoked. The Snyk Python scan was stale (9/10 packages already fixed); the only residual,jsonpickle, is transitive (capped<4by apache-beam) and never imported by our code → documented as accepted. - Base-image OS CVEs: the prod build used
--cache-fromWITHOUT--pull, so Debian security patches (zlib/openssl/sqlite3/krb5/…) were never re-pulled. Added--pulltocloudbuild.yaml(web),cloudbuild.brain.yaml, and the CI image build → each deploy picks up the patched base. - Optional integration CI:
conftestnow TCP-pings the LLM backend (LLM_API_BASE, default ollama) and skips@pytest.mark.integrationtests gracefully when it's unreachable; added a non-blockingintegration-testjob (skipped on PRs; runs on push to main + dispatch) — never gates the pipeline.
[2026-06-21] Session: Hexagonal Core, CI Guardrails, Test-Coverage Campaign & Hardening
Architecture & security (Critiques)
- Hexagonal core isolation: the
coreno longer imports Django (settings/cache), the MLOpspipeline, or the DI container (get_container()). IntroducedCache/Config/VectorStoreports with Django/Chroma adapters; movedguardrail_serviceinto theagenticcontainer, resolving thecore↔agenticcircular dependency (back-compat alias kept). backend.core.*→core.*: removed the dual-namespace that produced duplicate modules and brokenisinstance/mocks (15 source + 19 test files).- SSRF in
sample_url(Animetix Voice): user-controlled URL fetch hardened viasafe_http_request(rejects private/loopback/link-local IPs at every redirect hop), both at ingestion and fetch. - Backend ↔ frontend schema desync: exposed
wallet_balance(serializer + mapping); added DRF serializers +@extend_schemaforvs_battleand thexai_reportSSE event; regeneratedapi.d.ts.
Frontend health gate
- New CI job
frontend-checks(check-types+lint) gatingdeploy-to-prod— previously nothing rantscbefore prod (Vite doesn't type-check). tsc131 → 0: fixed runtimeReferenceErrors (brokencatchvars, missing importsGlobe/motion/Button/useCallback…), Plotly namespace, app types, deduplicated XAI cluster,Buttonvariants, force-graph refs; removed dead/brokenuseAniminator.ts.- ESLint 132 → 0:
no-explicit-any,no-unused-vars,react-hooks/*,jsx-a11y. - Fixed 6 broken/flaky frontend tests (incl. a
SynapticLabPageinfinite-render regression and an orphanedMultiverseLabPagetest →MultiverseStudioPage).
Monolith decomposition
pipeline/mlops/finetuning_dataset.py4650 → 1316 l. (−72%) via a façade re-export pattern (9 modules underft_dataset/, zero caller changes).- DI container: shared
LazyClassextracted tocontainers/lazy.py;core_services.py524 → 440 l. - Frontend:
MultiverseCatalogPage740→161,TachideskExplorerPage724→157,Layout475→118 — memoized sub-components + custom hooks, strictly behavior-preserving.
RAG services / dead-code audit
- Corrected the audit premise: the 3 RAG services don't overlap, they compose (merge abandoned on purpose). Removed real dead code: 2 orphan modules, 3 test-only modules, 2 registered-but-never-resolved modules+providers, 2 duplicate dead providers, 1 dead injected wire.
test_container_wiring3/3.
Test-coverage campaign (≈443 new tests; 17 backend modules 0% → 92-100%)
- Established a hard
--cov-fail-under=75gate + non-blocking Codecov upload;pytest-covconfirmed inrequirements.txt. - P1 — MLOps & Ingestion (8 modules):
jikan_enrichment,expert_enrichment,manga/{fetch_covers,ingest_manga,vectorize_manga},mlops/{merge_lora_weights,train_preference,rlhf_pipeline}(HTTP/sleeps/embeddings/vector-store/Neo4j/torch all mocked). - P2 — Async consumers (3 modules):
consumers/{duel,codemanga,speech_to_speech_live}; also fixed a flaky Channels e2e (1s → 5sreceive_json_fromtimeouts). - P3 — Adapters (6 modules):
inference/{moondream,qwen3_vl,brain_api},persistence/{django_safety,django_semantic_cache,colbert}. - P4 — Frontend (vitest 69 → 191): Zustand stores,
ErrorBoundary, offlineidb-keyval/persister. - 🐛 Production bug found via tests:
DjangoSafetyAdapterused fieldaction_taken(create()/filter()/read) while theAISafetyEventmodel field isaction→TypeError/FieldErroron every safety-event write. Fixed + added a@pytest.mark.django_dbround-trip regression lock.
Coverage consolidation → 75 % gate cleared (branch worktree-coverage-consolidation)
- Global line coverage 55,05 % → 75,33 % (
--cov=backend, the exact CI-gate flag; 19 831 / 26 325 lines, 2 285 tests green). The hard--cov-fail-under=75gate now passes. - Measurement-methodology fix: targeted runs must scope coverage by path (
--cov=backend), not by package name (--cov=pipeline). The name-based form attributesbackend.pipeline.*-imported modules to a separate module object and reports them at 0 % (dual-namespace) — e.g.dpo_dataset_compiler/semantic_drift_analyzer/run_provenancelooked uncovered but were already 81–92 %. CI already uses--cov=backend, so the gate itself was never mis-measured. - DI game-view wiring: a shared
tests/api/games/conftest.pyre-wires the@injectview modules and resets cached service Singletons before each test; the harmfulcontainer.reset_override()autouse fixtures were removed (that call detaches thecore→persistencesub-container on thisdependency_injectorversion and broke the views in isolation). All 8 game modes green alone and combined. - Modules raised to 100 %/near this push:
animetix.auth(0→100, IAP/Google/API-key auth), game modesvision/akinetix/blindtest(100),librarianRAG agent +akinetix_rl_service(100),tasks_views+creative_tasks(100),dpo_dataset_compiler(81→95),api/core(79→100),video_analysisadapter (44→100),index_otaku_knowledge(51→96). All model/HTTP/DB/torch I/O mocked; real-behavior assertions, no false-green. - Confirmed
pgvector_repository_adapteris already at 99 % (combinedtests/adapters/+tests/core/) — the earlier 31 % was a single-file stale reading. - Deflaked
test_speech_to_speech_live_consumer(the suite's last intermittent red): root cause was the consumer's ASGI/auth-middleware + background gemini task accessing the DB across the channels thread executor without adjango_dbmark — in isolation the task was cancelled before reaching it, so it only failed under full-suite ordering. Fixed with@pytest.mark.django_db(transaction=True), plus mocking the heavyvoice_cloning_serviceSingleton (it eagerly built the realinference_engine+LNN beforesession_ready) andprocess_client_audio(drops the ffmpeg/pydub dependency). Green across 3 fulltests/backend/runs.
Robustness & process hardening
- Test pollution: Proactor event-loop policy made fail-fast; added an autouse fixture clearing
Mockleaks fromsys.modules+ thelazy_importcache; fixed a realimageiosys.modulesleak. The 2 baselinetest_prompt_loadingfailures disappeared. - Error handling:
ErrorBoundary+ React-Query cache now report to Sentry with smart retry (no retry on 4xx); 5 genuine silentexcept Exception: passmade observable (0 remaining). - Pre-commit: ruff+black on
pre-commit, mypy+pytest (-m "not integration") onpre-push— the pytest hook caught a realtest_deploy_jobsregression. - MLOps provenance:
run_provenance.pywrites git-commit + UTC timestamp + manifest revisions next to each checkpoint (wired into the training scripts). - dbt: added telemetry source freshness + a 2nd singular drift-affinity test.
requirements.txt: confirmed it's a clean canonicalpip-compileoutput (audit was misleading); removed stalerequirements.txt.bak.- Async strategy: audited (only 5 async core files, no boundary violations) and documented the canonical sync-core / async-edges model in
ARCHITECTURE.md. features/vspages/: confirmed no duplication (healthy layering); convention documented infrontend/README.md.- Frontend performance: PWA precache trimmed 7.5 MB → ~3.0 MB (−60%) by excluding the lazy-loaded Plotly chunk and adding runtime caching.
- Accessibility: hardened
jsx-a11yinteraction rules toerror(0 violations) + fixed cleararia-labelcases.
Repository metadata
- GitHub
MissawB/Animetix: refreshed description, set homepage (Cloud Run), added 18 topics; repointedoriginto the current repo name.
Product features delivered (also detailed in earlier sessions below)
Vocal Library & Seiyuu integration, Graph Repair Console (Graph Healer), Plasticity Dashboard & Semantic Profile, Berrix Economy Hub, Tachidesk/Suwayomi integration, Manga Reader UX optimization, Manga Extension Manager, background Manga Chapter Tracking & notifications (periodic trigger wired via Cloud Run job + Scheduler), Offline Manga Library (PWA), Real-time Club Chat, Self-Hosted AI Image Worker, LLM speed optimizations.
[2026-06-20] Session: Offline Manga Reader (PWA)
- Mode Hors-ligne du Lecteur Manga (PWA):
- Added an
offlineLibraryIndexedDB layer (idb-keyval) that stores downloaded chapter page images as blobs with per-chapter metadata, plus auseChapterDownloadhook exposing download status/progress. - Added a chapter list with a per-chapter download button on the manga detail page, and a
useChapterPageshook that serves the reader from the local cache (object URLs) when a chapter is downloaded, falling back to the network and showing an "indisponible hors-ligne" state when offline. - Configured the service worker SPA
navigateFallbackso reader routes load offline.
- Added an
[2026-06-20] Session: Mihon/Suwayomi Integration, React Reader UX, Real-Time Chat, and ML Image Worker
- Manga Reader UX & Suwayomi (Mihon) Integration:
- Implemented the Suwayomi explorer integration, image proxy, and extension manager. Added GraphQL queries/mutations to list, install, update, and uninstall manga source extensions, along with Django REST views/routes and explorer dual tabs.
- Optimized the Manga Reader React UX with background image preloading (next 3/prev 1 pages), double-page side-by-side view (RTL/LTR), wide-page auto-splitting, and infinite scroll Webtoon mode with synchronized scroll-position states.
- Real-Time Club Chat:
- Integrated dynamic chat channels (WebSockets / Django Channels) inside discovery clubs for community interaction.
- Self-Hosted AI Image Worker (MLOps):
- Added a self-hosted fallback worker for Stable Diffusion and ComfyUI using our task queue (
enqueue_task) monitored via the Cluster Health dashboard.
- Added a self-hosted fallback worker for Stable Diffusion and ComfyUI using our task queue (
- LLM Speed Optimizations:
- Implemented speculative decoding (EAGLE, Medusa) and KV cache optimization (semantic cache and RadixAttention) to accelerate response times.
[2026-06-20] Session: Multiverse Lore Exporter (PDF Wiki) & LLM Acceleration Research
- Exportateur de Lore Multivers :
- Backend PDF Generation : Added
reportlabdependency to support native high-quality PDF generation. ImplementedMultiverseExportPDFViewinsidemultiverse.pyutilizing the customNumberedCanvasclass for dynamic page numbering ("Page X sur Y") and header formatting. The API queries Neo4j for the target synthetic universe, its characters, and its neighborhood graph connections (concepts and relations). - URL Registration : Added
/api/v1/multiverse/<str:universe_name>/export-pdf/tourls/api.py. - React UI Button : Integrated an "Exporter PDF" button next to the Nexus explorer within the
UniverseDetailPanelon theMultiverseCatalogPage.tsx. - Testing & Verification : Added a comprehensive test suite in
test_multiverse_export.pyensuring successful streaming of%PDFcontent and correct attachment headers. Verified the output using a standalone scratch generation pipeline.
- Backend PDF Generation : Added
- LLM Acceleration Research : Evaluated recent research (2025-2026) on speculative decoding (EAGLE, Medusa, SSD) and KV Cache optimization techniques, documented in the artifacts index.
[2026-06-19] Session: Digital Assets Shop, HTTP Centralisation, Pydantic V2 Migration, and UI Navigation Convergence
- Boutique d'Actifs Digitaux (Marketplace): Fully implemented the digital assets trading platform. Added the
MarketListingmodel with choice-based wallet transaction types (market_purchase,market_sale), Django migrations, and DRF serializers/viewsets. Integrated atomic transactions for safe balances debit/credit and creator transfer. DevelopedShopPage.tsxusing a premium cyber-emerald styling, and linked it via routing and Sidebar. Wrote comprehensive pytest coverage intest_market_api.py. - Centralisation HTTP (Frontend): Refactored game files (
AkinetixRLPage.tsx,DuelLobbyPage.tsx, andparadoxStore.ts) to use the centralizedapiClientwrapper. This eliminates rawfetchcalls, ensures automatic Firebase and CSRF token transmission, and standardizes error toast feedback. - Dépréciations Pydantic V2: Migrated the
PersonalizationSchemamodel insocial.pyfrom Pydantic V1 class Config format to Pydantic V2ConfigDictstandard, successfully resolving deprecation warnings. - Correction de
sync-api.bat: Aligned the OpenAPI TypeScript code generation target tosrc/types/api.d.tsand removed the unrecognized--quietargument from spectacular schema export. - Navigation, Ghost Labs & UI Convergence:
- Exposed sidebar shortcuts for Nexus Pro and Transparence Système, and created the Outils Admin & Monitoring section for staff.
- Linked previously orphan "Ghost Labs" interfaces: Seiyuu Discovery, Numba Compiler, Video RAG, and Cove Oracle.
- Deployed dedicated pages for Données Hors-ligne sync status, AI Feedback History, and Open Data datasets portal.
- Built the Tableau de Bord État du Cluster displaying real-time metrics for H100 GPUs, Ollama engines, and Neo4j nodes.
- Implemented the Catalogue de la Galerie Multivers enabling grid-view filtering and searching of communities' generated multiverses.
[2026-06-10] Session: SOTA Google Cloud Integrations (GCIP, Vertex AI Vector Search 2.0, Gemini Agent Platform, AlloyDB AI Text-to-SQL, and Cloud KMS CMEK)
- Google Identity Platform (GCIP) & Firebase Auth: Migrated local session and allauth authentication to a managed identity platform. Integrated the Firebase JS Client SDK on the frontend and implemented a custom Django REST Framework
GoogleIdentityAuthenticationbackend to verify JWT ID Tokens using cached Google certificates (with local Firebase Emulator support). Added OAuth social sign-in support for Google, Discord, X (Twitter), and MyAnimeList. - Vertex AI Vector Search 2.0 (Collections): Integrated the managed GCP vector search index wrapper (
VertexAICollectionWrapper) insidechroma_client.py. Implemented auto-embeddings (text-embedding-005) and hybrid search leveraging Reciprocal Rank Fusion (RRF). Maintained a dynamic runtime fallback toPGVectorCollectionWrapperfor local SQLite development. - Gemini Enterprise Agent Platform & Agentic RAG:
- Agent Gateway: Integrated proactive safety gates to validate prompt inputs and LLM outputs against Google Cloud safety policies.
- Agent Observability: Enriched OpenTelemetry spans with detailed GCP-specific agentic semantic attributes within
AgenticRAGServiceto trace the agent's decision tree.
- AlloyDB AI - Tools for Data Agents (Text-to-SQL): Implemented natural language catalog queries utilizing AlloyDB's native
alloydb_ai_nl.get_sqlfunction, with a fallback to local LLM prompt generation. Secured database execution with a custom two-layer validation parser (sql_guard.py) restricting queries toanimetix_mediaitem, blocking mutations, comments, and query chaining. - Customer-Managed Encryption Keys (Cloud KMS CMEK): Integrated CMEK protection for generated assets uploaded to GCS buckets via the
GS_DEFAULT_KMS_KEY_NAMEsetting. - Documentation Sync: Fully updated
README.mdandTODO.mdto reflect the completed cloud integration milestones and their local fallback behaviors.
[2026-06-09] Session: XAI Convergence, Validation Unification, InferencePort Completion, and Model Collapse Protection (HITL)
- XAI Convergence: Merged
UncertaintyServiceintoXaiDiagnosticService. Eliminated duplicated logprob-based entropy and perplexity calculations, simplifying the dependency graph inAgenticRAGService. - Validation Unification: Migrated all critical views (
Login,Register,Akinetix,Archetypist,Cognition) from directrequest.datadictionary parsing to Django REST Framework Serializers, stabilizing input validation and error responses. - InferencePort Completion: Implemented all stubbed methods in production adapters.
BrainAPIAdapternow supports 100% of the interface (video VLM, 3D depth, reranking), andGoogleGenAIAdapterintegrates Gemini's native temporal video analysis. - Model Collapse Protection (HITL): Implemented an "Universal HITL Gate" using the
GoldDatasetEntrymodel. All synthetic data (Multiverses, Distillation datasets, and QA pairs) are put in a validation queue awaiting human verification before ingestion. - Frontend Build Stabilization: Fixed remaining TypeScript and ESLint build failures following the modularization process.
- Dependency Cleanup: Purged duplicate entries for
threeandplotlyinpackage.json. - Ghost Labs Reactivation: Re-connected all previously comment-stubbed experimental interfaces (Soundscape, Speech-to-Speech, Voice, Visual Nexus) inside
LabHubPage. - Admin Tools & Cognitive Pages: Hooked up the MLOps Dashboard, DSPy Optimizer, CoVe Oracle (hallucination reduction), Hierarchical Graph RAG visualizer, Strategy CFR Solver, and the Manga Voice Lab pipeline.
[2026-06-08] Session: Major Refactoring, Frontend Modularization, and Lab Reactivations
- Django Forms API Validation: Refactored view methods in
backend/api/animetix/views/api.pyto systematically use Django Forms, eliminating raw request parsing. - InferencePort Stubs: Removed remaining stubs from
backend/core/ports/inference_port.py. - App.tsx Refactoring & Modularization: Decoupled the monolithic 21 KB
App.tsxfile into atomic components, moving views tosrc/pages/and utilities tofeatures/. - SelfEvolvingCompiler Integration: Replaced compiler stubs with an active proxy compiler dynamically rewriting and optimizing performance critical backend paths.
- Neural Diagnostics Improvement: Migrated uncertainty analysis from simulated
gpt2metrics inUnifiedInferenceAdapterto production-grade model logprobs. - Lazy Load Optimizations: Configured
FallbackInferenceAdapterandGoogleGenAIAdapterto load heavy client dependencies only on their first runtime invocation. - Social Route Cleanup: Shifted non-social pages (Pricing, Support, Explore) to their respective feature directories.
- New Feature Dashboards: Created the
/pricing/comparison page, Tree of Thoughts MCTS visualizer, Thought Budget (TTC) monitoring dashboard, Multiverse Gallery catalog, and the零-shot Voice Cloning (RVC) lab.
[2026-06-04] Session: Advanced Explainability (XAI), Direct VPC Egress, GCP Validation, Vertex Context Caching, and Live API
- XaiReportViewer Component: Built the React component displaying prompt intent, confidence metrics, agent traces, source attributions, and token logprobs, supported by Vitest suites.
- Direct VPC Egress Integration: Replaced serverless VPC connectors with Direct VPC Egress configurations in
deploy_brain.pyanddeploy_jobs.py. - GCP Validation Suite: Created
test_gcp_deployment_validation.pyto verify Cloud SQL sockets, GCS read/write lifecycles, Secret Manager values, and Cloud Run Job error pathways. - Vertex AI Context Caching: Implemented automatic context caching in
GoogleGenAIAdapterfor prompts exceedingGEMINI_CACHE_THRESHOLD. - Cloud Armor WAF Protection: Added
deploy_security.pyconfiguring CEL expressions to block SQLi, XSS, RCE, Token DoS, and prompt injections. - Gemini Multimodal Live API: Implemented the
speech_to_speech_live.pyDjango Channels consumer for PCM WebSocket streaming and updated the frontend client page.
[2026-06-03] Session: Vector Database Migration (ChromaDB to pgvector)
- PostgreSQL pgvector Migration: Replaced standalone ChromaDB containers with the PostgreSQL native
pgvectorextension for production RAG pipelines. - Hybrid SQLite Fallback: Developed a local fallback adapter storing vectors in standard tables and calculating cosine similarity using NumPy.
- ChromaDB Client Emulation: Rewrote
pipeline/chroma_client.pyto maintain client compatibility, avoiding rewrite requirements in data scrapers.
[2026-06-03] Session: Serverless Tasks (Cloud Run Jobs & Cloud Scheduler)
- Secret Manager Hardening: Configured Django settings to pull all external credentials directly from GCP Secret Manager in production.
- ETL Catalog Sync Automation: Created the nightly
sync_catalogCloud Run Job and triggered it via Cloud Scheduler HTTP POST calls. - Database Transaction Optimization: Wrapped the sync command in atomic transactions, reducing execution time from timeouts to 7 minutes.
[2026-06-03] Session: Google Cloud Storage & Creative Forge
- GCS Storage Integration: Configured
django-storageswith Google Cloud Storage backend for production media. - Creative Forge Persistence: Fixed a bug where creative fusions (Base64 URIs) were not saved, implementing default storage decode and write pipelines.
[2026-06-02] Session: SOTA Inference, Content Moderation, and Gaming UI
- Google GenAI Adapter: Built
GoogleGenAIAdapterusing Pydantic structural generation and real logprobs parsing. - Homogeneous Content Moderation: Integrated a standard sémantique safety filter across all adapters with keyword-based fallbacks.
- DRF Serializer Audits: Audited and fixed mass assignment vulnerability vectors in
CreativeFusionSerializerand IDOR vulnerabilities. - Gaming & Profile UI: Deployed ClubEvent countdown participation, realtime notification badges, VsBattle lobby matchmaking, and latent space user auras.
[2026-06-16] Session: Universal HITL Gate, SQL Guard Hardening, MLOps Privacy, and Frontend Stabilization
- Universal HITL Gate (Model Collapse Protection): Implemented a centralized
SyntheticValidationServicethat executes systematic cross-validation (self-critique, XAI scoring, and guardrails) on all synthetic data before human moderation. - SQL Guard Formal Audit & Hardening: Performed a security audit and fuzzing of the Text-to-SQL validator. Implemented mandatory
LIMITclauses, restrictedJOINcounts (max 5), and strictly enforced AST-level table whitelisting foranimetix_mediaitem. Verified against 34 attack scenarios. - MLOps Privacy & Secret Isolation: Created a recursive data scrubbing utility to strip API keys, JWTs, and PII from logs and fine-tuning datasets (
DPOFeedbackLoop). - Frontend Core Stabilization:
- Resolved UI flicker and unpredictability by replacing
Math.random()in render cycles with stable deterministic values oruseMemo. - Fixed critical performance regressions by eliminating synchronous
setStatecalls within effects in core components (ClubChat,VNPlayer). - Fixed "used before defined" reference errors in
AkinetixRLPageandExpertNexusPage. - TypeScript Type Hardening: Massive refactoring to eliminate
anyin core API clients and pages (Explore,Admin,Health), replaced with strict interfaces.
- Resolved UI flicker and unpredictability by replacing
- InferencePort & Adapters Completion: Finalized the
InferencePortimplementation across all production adapters. Added real sprite generation for the Game Engine and replaced similarity placeholders with real embeddings in the Google GenAI adapter. - Manga & Video Labs Promotion: Completed the backend flow for the Manga Reader (OCR & Inpainting) and stabilized the temporal indexing service for Video-RAG.
- Reasoning & Budget Optimizations: Integrated local 3B reasoning models for low-latency tasks and implemented a dynamic "Reasoning Budget" based on query complexity.
- Research Lab Expo: Deployed a dedicated frontend page to showcase and search through the project's 29 fundamental AI research papers.
[2026-06-14] Session: Backend Robustness, Frontend Type Hardening, Semantic RAG Caching, and UI Convergence
- Backend Robustness & Observability: Eliminated the "silent failure" anti-pattern by replacing all identified
except: passblocks with explicit logging (debug,warning, orerror) across all adapters (Google GenAI, ImageGen, Rerank, Safety), API views, and MLOps loops. This ensures full traceability of system failures in production. - Frontend Type Hardening: Performed a massive cleanup of the TypeScript codebase, replacing generic
anytypes with precise interfaces generated from the OpenAPI schema (api.d.ts). Secured game stores (akinetix,blindtest,vision,paradox), services (animinator,codemanga,audioLab), and XAI components. - Semantic RAG Caching: Implemented a vector-based caching layer in
DjangoSemanticCacheAdapterusing the project's unified vector store (PGVector/ChromaDB). Cached LLM responses are now reused for semantically similar queries (0.92 similarity threshold), significantly reducing costs and latency. - Natural Language SQL Security: Hardened the Text-to-SQL pipeline by enforcing a strictly Read-Only transaction in
DjangoRepositoryAdapterfor all AI-generated queries, providing a final line of defense against injection even if guardrails are bypassed. - React Performance Optimization: Migrated
SocialHubPageandClubDashboardto TanStack Query (hooksuseSocialDashboard,useClub), resolving technical debt regarding synchronous state updates in effects and improving data fetching reliability. - UI Routing & Page Convergence: Finalized the integration of several "Ghost" pages into the main router, including the Developer Portal, Transparency Hub, Manga Reader, and specialized profiles for Characters and Staff.
- Stripe Metered Billing for Expert API: Fully implemented usage-based monetization for the B2B API. Developers can now subscribe to the Pro tier via Stripe Checkout. Consumption (RAG requests) is automatically reported to Stripe Billing Meters through the
DjangoUsageAdapter, enabling precise pay-as-you-go invoicing. - Documentation Refactoring: Purged and archived all completed tasks from
docs/TODO.mdinto this log to maintain a focused and actionable project backlog.
End of History Log