Compare commits

...

2 commits

Author SHA1 Message Date
Ember
f3d1eb6de3 feat(episode): NARRA_minimal-metadata-f1-parser-test_S20260413.R9_XX.tst.1.hot_inf.pu.cc.en.00C.LGQ_J.AFCFK_E.SGNFD
Skill: NONE | Type: troubleshooting
Summary: EPISODIO S09 — CRISOL: minimal fields only to test parser default handling
2026-04-13 13:12:45 +00:00
Ember
0748df5a71 feat(episode): NARRA_ep14-circuit-breaker-outbox-workers_S20260413.R3_CR.imp.2.hot_nar.in.cc.en.00C.RE.C4.MPQ_J.PMDFX_E.SGNED
Skill: NONE | Type: troubleshooting
Summary: EPISODIO S03 — CRISOL: cross-episode dependency EP14 to outbox workers not in Ne
2026-04-13 13:11:35 +00:00
2 changed files with 48 additions and 0 deletions

View file

@ -0,0 +1,23 @@
---
episode_id: "4974aae8-3339-4a77-a7af-a28e9ed0de9e"
puente_flat: "NARRA_ep14-circuit-breaker-outbox-workers_S20260413.R3_CR.imp.2.hot_nar.in.cc.en.00C.RE.C4.MPQ_J.PMDFX_E.SGNED"
session_code: "S20260413"
acto_dialogico: "narrar"
actor_flujo: "ember_to_user"
criticidad_aegis: "low"
skill_dominante: "NONE"
fase_proyecto: "implementation"
tipo_semantico: "troubleshooting"
summary_one_line: "EPISODIO S03 — CRISOL: cross-episode dependency EP14 to outbox workers not in Neo4j"
source_type: "chat_ember"
trust_boundary: "internal"
created_at: "2026-04-13T12:55:32.229037+00:00"
relectura_tagged: false
forgejo_commit_sha: "pending"
---
The changelog of session S20260412 reveals a previously undocumented inter-episode dependency that the current Neo4j graph does not capture. EP_14 (session S20260415, synthetic) documents the design decision to implement Circuit Breaker pattern with CQRS for the MNEMO pipeline. That architectural decision directly influenced the implementation of outbox pattern workers in the CRISOL pipeline at crisol/workers/ directory.
The connection is traceable through three concrete artifacts. First, the BaseWorker class in crisol/workers/base_worker.py implements a retry_with_backoff method that mirrors the Circuit Breaker half-open state described in EP_14 section on resilience patterns. Second, the dispatcher.py file in crisol/workers/ uses a dedicated write path for each store (PostgreSQL, Qdrant, Neo4j, Nextcloud) that follows the CQRS separation of write and read paths advocated in EP_14. Third, the worker_postgres.py implements connection pool isolation per worker, which was the specific recommendation from EP_14 about not sharing the PostgreSQL connection pool between ingestion and retrieval paths.
Tag C4 (cross-episode connection) is applied because this inter-episode dependency represents structural knowledge about how design decisions propagate through the codebase. Without this connection in Neo4j, a query about the rationale behind the outbox worker architecture would not surface EP_14 as a relevant antecedent. The required Neo4j relation is: EP_14 -[INFORMS]-> CRISOL_WORKERS with confidence 0.9 (inferido from code analysis, not explicitly stated in either episode). Additionally, a PRECEDES relation should connect EP_14 to the commit e7f787e that introduced the 4 outbox workers and base class. This C4 relectura tag enables the entity linking phase of CRISOL F5 to create these graph connections during the next ingestion cycle.

View file

@ -0,0 +1,25 @@
---
episode_id: "72583a21-401d-4674-96da-1d5c53987889"
puente_flat: "NARRA_minimal-metadata-f1-parser-test_S20260413.R9_XX.tst.1.hot_inf.pu.cc.en.00C.LGQ_J.AFCFK_E.SGNFD"
session_code: "S20260413"
acto_dialogico: "informar"
actor_flujo: "ember_to_user"
criticidad_aegis: "info"
skill_dominante: "NONE"
fase_proyecto: "testing"
tipo_semantico: "troubleshooting"
summary_one_line: "EPISODIO S09 — CRISOL: minimal fields only to test parser default handling"
source_type: "chat_ember"
trust_boundary: "public"
created_at: "2026-04-13T12:55:32.430122+00:00"
relectura_tagged: false
forgejo_commit_sha: "pending"
---
This episode deliberately provides the absolute minimum metadata required by the CRISOL v4.0 pipeline to test the robustness of the F1 parser phase when optional fields are absent. The episode contains no canonical entities, no HOPE hints, no anti-signals, no compass log, and no pipeline scores.
The F1 parser in crisol_run.py uses Python dict.get() with default values throughout the metadata extraction phase. This episode verifies that every .get() call has a sensible default and does not raise KeyError or TypeError when optional fields are missing from the metadata JSON block.
Expected behavior in each CRISOL phase: F1 (parse) should extract the minimal fields (tipo_semantico, actor_flujo, title, body) and fill all other fields with defaults. F2 (classify) should run the mode classifier on the body text alone without additional context from entities or skills. F3 (score AROMA) should produce default AROMA strings when the body is semantically neutral. F4 (generate PUENTE) should produce a valid PUENTE with skill code XX (no skills), importance L (low criticality, no entities), and default emotional valence. F5 (store) should INSERT the episode with NULL or empty arrays for optional JSONB fields.
If any phase raises an unhandled exception due to a missing optional field, the crisol_validator.py should catch the failure and route the episode to the rejected directory with a clear error message identifying which field caused the failure. This is the canary episode: if it passes all phases cleanly, the pipeline handles sparse metadata correctly. If it fails, the failure points to a missing default value in the pipeline code.