Skip to content

Dossiers de decisión v11 — transiciones de Agent

Estado verificable

Este documento conserva propuestas de CORE-13 y registros aprobados individuales; su existencia no aprueba las filas pendientes. Se deriva de docs/concepts/feature-preservation-inventory.json, del contrato FP-5 y de las pruebas y símbolos que se nombran abajo.

Estado del contrato de este cambio: 33 aprobaciones y 1 blocker (hydration_min_relevance sigue sin firma). CORE-140 firmó el cambio nativo aprobado de domain_description_max_chars con prueba de composición y turnos. La dirección de policy nativa para hydration_min_relevance fue aprobada, pero su firma espera calibración por app y auditoría de composition roots. La exclusión de speakers recibió APPROVE CHANGE en CORE-133, el path SQLite en CORE-137 y fabricación en CORE-136; enabled_layers en CORE-26, domain.core_preferences en CORE-139 y working_memory_recent_turns en CORE-135 (PRs #435, #441 y #442 ya integrados). migration_closure sigue blocked. El merge y su CI son pasos separados.

Medición histórica en origin/main (0f06678a) con _blocking_rows(_contract()): 14 blockers, todos behavior-changed pendientes de veredicto del owner. approved_changes contiene 20 registros. El contrato mantiene migration_closure.state = blocked; estas cifras no prueban paridad ni cutover.

Para APPROVE CHANGE/REMOVAL, CORE-1 debe añadir una entrada individual con row, owner, decision y transition_nodes. Para RESTORE se requiere restaurar el observable, probarlo y cambiar la disposición de la fila a equivalent-proven; una propuesta con decision: null no hace ninguna de esas cosas. El gate exige que los nodos aprobados pertenezcan al outcome de esa misma fila, estén ejecutados y cubran la prueba declarada por el inventario. Una evidencia prestada está rechazada por scripts/feature_preservation_gate.py::_contract.

Convenciones. RESTORE = recuperar el observable legacy y probarlo; APPROVE CHANGE = aceptar el observable nativo explícito distinto; APPROVE REMOVAL = aceptar que no hay equivalente y registrar la mitigación. Las disposiciones son recomendaciones, no aprobaciones.

Las tablas A–E conservan las propuestas históricas del primer paquete de 28 filas. Su columna «Recomendación» no es el veredicto vigente: varias filas ya recibieron una decisión distinta, registrada en approved_changes del contrato FP-5. Para la única fila pendiente manda el dossier con encabezado pendiente; el checklist final de 14 filas es histórico. No se debe reabrir una decisión aprobada por leer una recomendación antigua aquí.

A. Gobernanza: policy explícita sustituye flags legacy

Propuesta histórica: aprobar la composición explícita sólo si conserva los límites de seguridad indicados por cada prueba de aceptación.

Fila Legacy / observable Evidencia Agent/Kernel Recomendación Riesgo Prueba de aceptación
metacognition_confidence_threshold Umbral selective gate / invocación de crítico. SelectiveMetacognitionPolicy; governance(... confidence_floor), capabilities/governance/stages/metacognition_policy.py. APPROVE CHANGE Complementa hard floors. test_subject_confidence_precedes_reporter_and_an_invalid_subject_stays_loud; comparar debajo/en/el umbral.
metacognition_gate Predicado CriticGateContext / decisión de review. trigger_policy, governance(trigger_policy=...), capabilities/governance/stages/metacognition.py. APPROVE CHANGE Firma/contexto cambian. test_public_custom_policy_is_the_explicit_opt_out_seam; predicado y negación.
metacognition_selective_gate Flag selective / review u omisión. Default SelectiveMetacognitionPolicy. APPROVE CHANGE Spelling antiguo rechazado. test_public_selective_policy_preserves_the_three_regression_probes; tres probes.
metacognition_sensitive_tags Tag recuperado fuerza review / crítico invocado. Proyección MemoryRecord.metadata['tags'], capabilities/memory/recall_evidence.py. APPROVE CHANGE Sólo clasificación cruza; payload sigue privado. test_public_agent_distinguishes_native_recalled_tags_from_draft_terms; tag recuperado vs término draft.
metacognition_trivial_ack_patterns Un acuse custom puede omitir review. SelectiveMetacognitionPolicy.trivial_ack_patterns. APPROVE CHANGE Reemplazan los defaults y deben coincidir con la respuesta completa, cruda o sin espacios ni .!? finales. test_public_custom_ack_patterns_replace_the_default_set; reemplazo y no-unión.
credential_patterns Regex custom/disable / argumentos scrubbed. CredentialHygieneStage, governance(patterns=...), capabilities/governance/stages/credentials.py. APPROVE CHANGE Custom reemplaza built-ins; disable separado. test_custom_credential_pattern_scrubs_its_configured_key_only; custom, builtin y disable.
fabrication_refuse_min_confidence Un umbral refuse/allow. FabricationStage, governance(min_confidence=..., refuse_min_confidence=...). APPROVE CHANGE Dos umbrales. TestFabrication::test_refusal_floor_includes_its_exact_boundary; matriz de límites.
read_only_tools Exclusión de herramientas read-only / decisión crítica. governance(read_only_tools=...), metacognition_policy.py. APPROVE CHANGE Nombres deben coincidir con registry. test_public_tool_evidence_distinguishes_mutating_and_read_only; nombre existente y desconocido.

Todos los selectores abreviados de esta sección están en tests/platform/test_metacognition_preservation.py, salvo tests/platform/test_governance_amends.py::test_custom_credential_pattern_scrubs_its_configured_key_only y tests/capabilities/governance/test_egress_stages.py::TestFabrication::test_refusal_floor_includes_its_exact_boundary.

B. Prompt y caché: bytes equivalentes o cambio aprobado

Propuesta histórica: una ruta nueva no prueba equivalencia de prompt. Las filas RESTORE exigen fixture legacy representativa y comparación de bytes/selección antes de cambiar la disposición.

Fila Legacy / observable Evidencia Agent/Kernel Recomendación Riesgo Prueba de aceptación
extraction_template_path Path HMS; directiva MEMORY_EXTRACT/GRAPH_OPERATIONS, persistencia sin reply leak. ExtractionDirectiveSource + LegacyGraphOperationsAdapter, capabilities/memory/legacy_extraction.py. APPROVE CHANGE Retracciones/ops no documentadas caen a fallback. tests/capabilities/memory/test_extraction_in_the_turn.py::test_bundled_legacy_directive_persists_through_the_explicit_adapter; bundled y operación no soportada.
hms_budget_mode warn/strict; continuar/fallar y bytes. PromptBudget, agent/cutover/prompt_assembly_policy.py; prueba nativa test_core15_measurable_native_evidence.py::test_hms_budget_mode_changes_a_direct_agents_overflow_outcome. RESTORE Orden de descarte difiere. tests/agent/cutover/test_prompt_assembly_lane.py; replay over-budget, excepción/continuación y regiones.
hms_system_prompt_token_budget Cap HMS-string / prompt al modelo. RegionalPromptPolicy.hms_system_prompt_token_budget, capabilities/prompting/regional.py. APPROVE CHANGE FrameworkConfig legacy rechazado por cutover. test_issue187_regional_prompt_policy.py::test_hms_region_is_pinned_against_the_total_prompt_budget; bytes para configuración adoptada.
jit_manifest_token_budget Cap JIT manifest / asignación manifest-prompt. RegionalPromptPolicy.jit_manifest_token_budget. APPROVE CHANGE Template JIT y keyword filtering no adaptados. test_issue187_regional_prompt_policy.py::test_public_agent_sends_bounded_domain_and_independent_manifest_bytes; replay de adaptadores o exclusión explícita.
manifest_cache_position Marker de caché fijo / marker proveedor. Regiones L1/L2; NativeCacheComposition no acepta setting, prompt_assembly_policy.py. RESTORE Selección legacy/tool binding difieren. test_public_manifest_regions_keep_volatile_tail_outside_cached_marker; misma entrada, selección y marker.
memory_extract_cadence Directiva N-turn / visibilidad por scope/sesión. ExtractionDirectiveSource(cadence, scope_path), capabilities/prompting/extraction.py. APPROVE CHANGE N>1 anónimo se omite sin frontera segura. test_extraction_directive_source.py::test_public_agent_renders_only_the_due_session_turn_to_the_model; sesión estable y anónima.
messages_cache_policy Rolling history cache / provider cache multi-turn. Opt-in nativo #221; adapter default sin historia anotada, prompt_assembly_policy.py. APPROVE REMOVAL Regresión coste/latencia; system cache no es history cache. test_public_two_turn_cache_reaches_anthropic_wire_with_ttl_marker; medir dos turnos y declarar mitigación/opt-in.
domain Template nested completo / bytes system prompt. hms_source_for_domain(...) proyecta descripción, regional.py. APPROVE CHANGE Tools/governance cambian de owner. test_public_agent_sends_bounded_domain_and_independent_manifest_bytes; separar prompt, tools y governance.
domain_description_max_chars Límites JIT/no-JIT / truncación y aviso. RegionalPromptPolicy.domain_description_max_chars, bounded_domain_description(...). APPROVE CHANGE (CORE-1 50509c6e) La ruta nativa usa aviso RegionalPromptPolicy una vez por composición; legacy usa FrameworkConfig una vez por SymfonicAgent. Agent rechaza dos etapas prompting, así que la duración de dos composiciones en el mismo Agent queda UNKNOWN en la API pública. No prueba reachability de toda instalación ni paridad de template. test_core1_full_hms_domain_cap_restore.py; test_core140_domain_cap_transition.py; run/stream, fallback vacío, aviso en construcción de dos Agents sin repetición en dos turnos y primer read de dos composiciones directas.

Los selectores sin ruta completa en esta tabla son: tests/capabilities/prompting/test_issue187_regional_prompt_policy.py::<selector>, tests/platform/test_fp3_public_preservation_journeys.py::<selector> y tests/capabilities/prompting/test_extraction_directive_source.py::<selector>.

CORE-138 — colocación JIT aprobada, fila jit_manifest_token_budget. El owner aprobó en Plane CORE-138 f66c7da8-6d65-498f-bf6e-a52151ecaeed (2026-10-02T21:22:49.473924Z) y CORE-1 d3b3f3c9-6394-477b-8979-766426755aa8 (2026-10-02T21:22:50.123459Z) el cambio exacto medido por tests/agent/cutover/test_core138_jit_body_differential.py: con tenant, namespace, nombre del dominio, SOUL, checklist y una herramienta alineados, los requests run/stream y las descripciones vacía, breve y truncada difieren sólo en el manifest. Legacy inserta la línea de herramienta en el slot TOOL MANIFEST; Agent deja allí un marcador y emite la contribución L1 después de TOOL DISCIPLINE. La mutación del SOUL añade otro diff y rompe la comparación. La autorización amplía la entrada APPROVE CHANGE existente de jit_manifest_token_budget; no crea una segunda aprobación ni modifica el veredicto posterior de CORE-140 sobre domain_description_max_chars. El facade legacy público rechaza el budget retirado antes del despacho (tests/agent/cutover/test_retired_configuration.py::test_the_refusal_names_the_field_and_cites_the_line), por lo que la comparación ejercita directamente sus cuerpos conservados; no prueba reachability pública para esa configuración.

C. Recuperación y memoria: policy explícita no implica el mismo resultado

Propuesta histórica: la aceptación requiere una ruta pública Agent con corpus equivalente; una unidad de policy no prueba preservación de composición.

Fila Legacy / observable Evidencia Agent/Kernel Recomendación Riesgo Prueba de aceptación
scorer_on_hot_path Switch ranking / orden recall compilado. RetrievalCoordinator, memory_capabilities(retrieval=...), capabilities/memory/factory.py. APPROVE CHANGE Boolean no existe; fuente declara pre_ranked. test_issue188_public_retrieval_contracts.py::test_public_agent_same_scenario_uses_scorer_or_pre_ranked_order; mismo corpus, dos fuentes.
hydration_min_relevance Floor similitud / record pasa gate. RetrievalCoordinator._gate, factory.py. APPROVE CHANGE Score compuesto. test_issue188_public_retrieval_contracts.py; weak/high-salience con pesos explícitos.
working_layer_exclude_speakers Filtro en todo recall / assistant ausente. Sólo WorkingWindow.read, memory_capabilities(... exclude_speakers=...). APPROVE CHANGE Recalled records no tienen speaker schema. test_issue188_public_retrieval_contracts.py; fuente working y recalled.
scope_blend_mode Peso ancestros / ranking jerárquico. RetrievalCoordinator + ScopeBlend. APPROVE CHANGE off/blend/backfill sustituyen policy. test_issue188_public_retrieval_contracts.py; local+ancestor para cada modo.
enabled_layers Layers hydration / layers consultadas. Orchestrator inyectado retiene layers, memory_orchestrator_rows.py; evidencia test_core15_measurable_native_evidence.py::test_enabled_layers_changes_the_native_retrieval_query. APPROVE CHANGE Precedencia de construcción cambia. tests/agent/cutover/test_continuation_cutover.py; top-level y injected orchestrator.
phase1_spreading_weight Peso BFS/direct / importancia persistida post-nap. LearningPolicy.phase1_spreading_weight, capabilities/memory/phases/quick.py. APPROVE CHANGE Nap nativo no importa FrameworkConfig. test_issue188_public_retrieval_contracts.py::test_public_quick_nap_persists_phase1_spreading_weight_effect; coordinator/schedule/lease.
working_memory_recent_turns Conteo; 0 deshabilita / tamaño ventana. WorkingWindow.read, memory_retrieval_rows.py; evidencia test_core15_measurable_native_evidence.py::test_working_memory_recent_turns_changes_a_direct_agents_stage_observable. APPROVE CHANGE Cero rechazado. tests/agent/cutover/test_memory_retrieval_lane.py; contrato disabled y 0/1/N.

Los selectores abreviados test_issue188... pertenecen a tests/capabilities/memory/test_issue188_public_retrieval_contracts.py.

D. Continuidad y estado: el host es el owner nuevo

Fila Legacy / observable Evidencia Agent/Kernel Recomendación Riesgo Prueba de aceptación
dev_sqlite_checkpoint_path SQLite path / payload restart-resume. human_interaction + AgentHost, puertos durables de payload/checkpoint/consumo y resolver de scope aportados por adoptante. APPROVE CHANGE firmado No import de archivos LangGraph SQLite, pausas, transcript ni working deque legacy; at-most-once host-level. Pin 9.12 si se necesitan esos archivos. tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process; tests/retirement/test_core137_sqlite_transition.py; aislamiento, scope, single-use y rechazo del path legacy.
state_class Reemplazo LangGraph / shape estado. Agent.run(state=...) -> TurnRequest.properties, agent/facade_turn.py. APPROVE CHANGE Sin conversión ni persistencia automática. tests/platform/test_issue190_migration_contracts.py::test_public_custom_turn_state_reaches_a_capability_and_stays_per_turn[run]; stream y no-reinyección recovery.
ask_user_pause_ttl_seconds Pause TTL / expiry y resume host fresco. TTLPolicy -> human_interaction -> AgentHost, capabilities/human/values.py. APPROVE CHANGE Máximo rechaza en vez de clamp. test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[resume-below], [resume-equal], [expired]; tests/capabilities/human/test_the_door.py::test_public_pause_refuses_an_above_maximum_lifetime_before_minting.

E. Eliminación sin consumer nativo

Fila Legacy / observable Evidencia Agent/Kernel Recomendación Riesgo Prueba de aceptación
activation_log_mode Footer activation-log / bytes prompt. Sin consumer; src/symfonic/agent/cutover/retired_settings.py. APPROVE REMOVAL Pérdida de footer de procedencia. Crear y ejecutar comparación de prompt compilado: el inventario declara MISSING: compiled-prompt comparison; registrar pérdida y mitigación.

Decisiones del owner — 2026-09-26

La instrucción explícita del owner en la conversación acepta APPROVE CHANGE para ask_user_pause_ttl_seconds, state_class, phase1_spreading_weight, scope_blend_mode, scorer_on_hot_path, phase_12_action_type_from_tool_calls y fabrication_refuse_min_confidence. El registro automatizado en CORE-1, comentario 5596490f-891d-4dec-a42a-4bd1eac1bf70, documenta esa instrucción; el autor API del comentario no se presenta como el owner que aprueba. El contrato ejecutable contiene las siete firmas y sus nodos propios. La descripción inicial de fabricación confundía revisión con entrega permitida; el dossier corregido mide el bloqueo público en run/stream y registra la decisión informada del owner. El estado vigente está en approved_changes.

El owner autoriza implementar RESTORE para working_layer_exclude_speakers, domain_description_max_chars y working_memory_recent_turns. Esto no firma paridad anticipada: CORE-61, CORE-62 y CORE-29 deben aportar implementación, evidencia y revisión antes de reconciliar sus filas. CORE-133 (2026-10-02) sustituye esa dirección para working_layer_exclude_speakers con APPROVE CHANGE; CORE-135 (2026-10-02) hace lo mismo para working_memory_recent_turns con APPROVE CHANGE; CORE-140 firma el cambio de domain_description_max_chars aprobado en CORE-1 comentario 50509c6e.

CORE-26, CORE-139 y CORE-135 (2026-10-02) firman APPROVE CHANGE para enabled_layers, domain.core_preferences y working_memory_recent_turns; hydration_min_relevance sigue sin firma. Los encabezados y propuestas históricos que siguen describen la deliberación previa; el contrato es la fuente del estado de aprobación vigente. No se autoriza retirar engine ni publicar PyPI. La validación temprana de TTL y la evaluación de calidad del ranking son seguimientos, no evidencia ya implementada.

F. Dossiers añadidos para las dos filas sin entrada anterior

domain.core_preferences — veredicto del owner: APPROVE CHANGE

Observable y evidencia. En legacy, la declaración de CorePreference llega al request del modelo crítico cuando se invoca la revisión; lo comprueba tests/platform/test_core_preferences_migration.py::test_legacy_critic_receives_the_preference_statement. La migración explícita copia declaración, tags y prioridad a fuentes de prompt y términos sensibles; el test público del mismo archivo mide esa composición. Pero tests/capabilities/memory/test_fp_class_b_native_observables.py::test_a_migrated_core_preference_changes_no_executable_decision mantiene la misma decisión con y sin esos términos. El reflector nativo compuesto no recibe automáticamente la declaración como política. El test legacy de tests/agent/test_metacognition_proof.py mide la ruta anterior; no convierte la composición nueva en equivalente.

Restauración e impacto. Es viable componer explícitamente un reflector que reciba la preferencia, o escribir una regla ejecutable revisada por el adoptante; aún faltan replay del request crítico y comparación de decisiones para afirmar RESTORE. La evidencia mide contenido y una decisión controlada, no la frecuencia de adopción, la eficacia de cada preferencia ni paridad de seguridad. Inferir un guard o precondición desde prosa sería un cambio adicional.

Recomendación propuesta: APPROVE CHANGE para la composición explícita y responsabilidad del caller de proveer una política ejecutable cuando la necesite. Contra-caso: elegir RESTORE si aplicaciones dependen de que el crítico reciba esas declaraciones sin composición adicional; exigir entonces una ruta pública con request y decisión comparados antes de cerrar la fila.

Decisión aprobada (CORE-139, 2026-10-02). El owner aprueba un reviewer/policy explícito por aplicación (core_preference_governance) en lugar de un crítico legacy automático. La evidencia añadida muestra que legacy entrega la declaración al crítico y que la migración sola no la entrega al reviewer nativo; el veredicto del reviewer del fixture depende de su policy explícita, no de la prosa migrada (test_core_preferences_causal_differential.py), la policy (exige reviewer async declarado, falla cerrado ante reviewer ausente, con error o con veredicto malformado, y aísla apps) y una app generada que lo compone en el egress público. La migración sola sigue sin cambiar ninguna decisión. No es paridad de seguridad, ni mide frecuencia de adopción ni eficacia de cada preferencia, y no se infiere ninguna política desde prosa.

Registro aprobado; coincide con approved_changes. La recomendación y el contra-caso anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "domain.core_preferences",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Core preferences become an explicit per-app review policy: core_preference_governance enforces a caller-supplied async preference reviewer at public egress and fails closed when declared enforcement cannot be honoured, when the reviewer errors, or when its verdict is malformed. The legacy automatic critic received preference prose; migration alone delivers prompt sources and sensitive terms but does not deliver that statement into a native reviewer request or change the tested decision without explicit policy. The deterministic reviewer fixture demonstrates composition, not that the preference prose itself causes a verdict. No executable policy is inferred from prose; this is not safety parity, adoption frequency, or per-preference effectiveness.",
  "approval_reference": "Owner approval recorded in Plane CORE-139 comment 49c841c8-077b-476c-b365-7ccdd92821b4; the API comment author is provenance, not the approving owner.",
  "transition_nodes": [
    "tests/agent/test_metacognition_proof.py::TestMetacognitionEndToEnd::test_sensitive_tag_forces_reflection_and_refuse_replaces_response",
    "tests/platform/test_core_preferences_migration.py::test_legacy_critic_receives_the_preference_statement",
    "tests/platform/test_core_preferences_migration.py::test_public_core_preference_adapter_preserves_values_and_reaches_native_composition",
    "tests/capabilities/memory/test_fp_class_b_native_observables.py::test_a_migrated_core_preference_changes_no_executable_decision",
    "tests/platform/test_core_preferences_causal_differential.py::test_legacy_preference_changes_a_deterministic_critic_verdict",
    "tests/platform/test_core_preferences_causal_differential.py::test_native_preference_needs_explicit_reviewer_policy_to_change_decision",
    "tests/platform/test_core_preference_policy.py::test_enforced_reviewer_receives_preference_and_decides_on_egress",
    "tests/platform/test_core_preference_policy.py::test_enforced_reviewer_lets_a_compliant_draft_through",
    "tests/platform/test_core_preference_policy.py::test_enforcement_is_not_skipped_for_a_trivial_acknowledgement",
    "tests/platform/test_core_preference_policy.py::test_default_is_explicit_prompt_and_watch_only_with_no_decision",
    "tests/platform/test_core_preference_policy.py::test_caller_terms_extend_instead_of_erasing_migrated_sensitivity",
    "tests/platform/test_core_preference_policy.py::test_declared_enforcement_that_cannot_be_honoured_fails_closed[missing]",
    "tests/platform/test_core_preference_policy.py::test_declared_enforcement_that_cannot_be_honoured_fails_closed[no-review-method]",
    "tests/platform/test_core_preference_policy.py::test_declared_enforcement_that_cannot_be_honoured_fails_closed[reviewer-undeclared]",
    "tests/platform/test_core_preference_policy.py::test_declared_enforcement_that_cannot_be_honoured_fails_closed[reflector]",
    "tests/platform/test_core_preference_policy.py::test_declared_enforcement_that_cannot_be_honoured_fails_closed[trigger]",
    "tests/platform/test_core_preference_policy.py::test_enforcement_declared_over_no_preferences_is_refused",
    "tests/platform/test_core_preference_policy.py::test_synchronous_reviewer_is_refused_at_composition",
    "tests/platform/test_core_preference_policy.py::test_a_reviewer_that_fails_at_runtime_refuses_the_turn[raises]",
    "tests/platform/test_core_preference_policy.py::test_a_reviewer_that_fails_at_runtime_refuses_the_turn[wrong-type]",
    "tests/platform/test_core_preference_policy.py::test_malformed_reflection_never_releases_a_draft[missing-verdict]",
    "tests/platform/test_core_preference_policy.py::test_malformed_reflection_never_releases_a_draft[numeric-verdict]",
    "tests/platform/test_core_preference_policy.py::test_malformed_reflection_never_releases_a_draft[invalid-confidence]",
    "tests/platform/test_core_preference_policy.py::test_malformed_reflection_never_releases_a_draft[broken-accessor]",
    "tests/platform/test_core_preference_policy.py::test_apps_are_isolated_even_when_they_share_one_reviewer",
    "tests/platform/test_core_preference_policy.py::test_enforced_preferences_are_frozen_at_composition",
    "tests/cli/test_core139_generated_preference_policy.py::test_generated_app_composes_preference_reviewer_at_public_egress"
  ]
}

phase_12_action_type_from_tool_calls — veredicto del owner: APPROVE CHANGE

Observable y evidencia. El test tests/capabilities/memory/test_fp_class_b_native_observables.py::test_the_tool_call_fallback_decides_whether_a_draft_exists_at_all publica turnos con tool calls sin verbo de acción: LearningPolicy() no persiste draft; con promotion_use_tool_calls_fallback=True persiste uno con acción call deploy_staging. En el mismo archivo, otro test comprueba que FrameworkConfig declara true y la policy nativa por defecto declara false. tests/retirement/test_phase12_tool_call_route_defaults.py acota el legacy efectivo: la ruta de consolidación autoconstruida no crea draft, mientras el endpoint HTTP sí lo crea con la configuración por defecto.

Restauración e impacto. El opt-in nativo recupera el patrón derivado de tool calls, pero no restaura automáticamente todos los defaults legacy. Antes de elegir RESTORE habría que fijar qué ruta de construcción y qué default se promete, y ejecutar su comparación con la ruta nativa elegida. La prueba cubre el draft y su acción, no la prevalencia de cada ruta en adoptantes ni equivalencia de la promoción completa.

Recomendación propuesta: APPROVE CHANGE con opt-in nativo explícito para quien necesite tool calls como fallback. Contra-caso: RESTORE del default de una ruta legacy identificada si un adoptante depende de que el endpoint promueva sin opt-in; el owner debe delimitar esa ruta antes de aprobarlo.

Registro aprobado por instrucción explícita del owner; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "phase_12_action_type_from_tool_calls",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Native tool-call-derived procedural learning is explicit opt-in; route-dependent legacy defaults are not automatically preserved.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_fp_class_b_native_observables.py::test_the_tool_call_fallback_decides_whether_a_draft_exists_at_all",
    "tests/capabilities/memory/test_fp_class_b_native_observables.py::test_native_and_legacy_config_defaults_do_not_select_the_same_fallback"
  ]
}

G. Dossiers de las 12 filas aún resumidas en tablas

fabrication_refuse_min_confidence — veredicto del owner: APPROVE CHANGE

Observable y evidencia. La fila del inventario declara el observable refuse/allow y un único umbral legacy; agent/middleware/fabrication_wiring.py refusa en modo refuse cuando un hallazgo alcanza el default 0.8, y deja los hallazgos inferiores como observación. En Agent, el FabricationStage.apply usa dos umbrales: por debajo de min_confidence permite, en la banda intermedia emite STEER, y en el límite refuse_min_confidence o por encima refusa un hallazgo del detector. El test test_public_fabrication_floor_withholds_the_draft_at_both_doors mide ambos accesos públicos con hallazgos 0.59, 0.6, 0.79 y 0.8; confirma que el stream no emite el draft cuando se bloquea. platform/governance_verdict.py convierte STEER en egress en GovernanceRefused: la banda intermedia detiene la entrega. Un hallazgo derivado sólo de intención de acción, sin tool calls y con confianza al menos min_confidence (default 0.6), también eleva esa excepción con disposición STEER; por debajo de ese umbral permite. Lo mide test_intent_only_finding_uses_the_actionable_floor_without_detector_refusal, incluido 0.95 para comprobar que ni un intent superior al límite refuse eleva su disposición a REFUSE. No se entrega el draft con una mera advertencia en esos casos.

Restauración e impacto. Para un hallazgo del detector, igualar ambos umbrales al límite legacy parece reproducir allow/refuse; confianza media: falta replay del mismo corpus y de la interacción con metacognición para afirmar RESTORE del contrato completo. La banda intermedia STEER, el hallazgo de intención y el opt-out de refusal cambian el observable sólo donde el adoptante compone governance; los tests citados no miden cuántos adoptantes lo hacen ni el impacto de latencia o seguridad en producción. El comentario en agent/config.py que dice default nativo 0.9 contradice el constructor y la prueba pública actuales (0.8); no debe usarse como evidencia de runtime.

Decisión aprobada: APPROVE CHANGE para la banda intermedia que bloquea la entrega y los hallazgos de intención que también bloquean, conservando REFUSE del detector en 0.8. Aprobación explícita del owner en CORE-1 comentario 5596490f-891d-4dec-a42a-4bd1eac1bf70. Contra-caso: RESTORE si un consumidor depende de que todo hallazgo inferior al límite sea sólo telemetría; exigir entonces replay diferencial y política explícita para intención y metacognición. APPROVE REMOVAL no está respaldado: el stage nativo está cableado y ejerce rechazo público.

Registro aprobado; coincide con approved_changes:

{
  "row": "fabrication_refuse_min_confidence",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Public run and stream withhold intermediate STEER findings at the actionable 0.6 floor; detector findings REFUSE at 0.8 inclusive, while intent-only findings never produce REFUSE. The two-floor native policy is an approved observable change, not full legacy or metacognition parity.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/platform/test_fabrication_refusal_boundary_v11.py::test_public_fabrication_floor_withholds_the_draft_at_both_doors[0.59-None-run]",
    "tests/platform/test_fabrication_refusal_boundary_v11.py::test_public_fabrication_floor_withholds_the_draft_at_both_doors[0.6-steer-stream]",
    "tests/platform/test_fabrication_refusal_boundary_v11.py::test_public_fabrication_floor_withholds_the_draft_at_both_doors[0.8-refuse-run]",
    "tests/platform/test_fabrication_refusal_boundary_v11.py::test_intent_only_finding_uses_the_actionable_floor_without_detector_refusal[0.6-True-stream]",
    "tests/platform/test_fabrication_refusal_boundary_v11.py::test_intent_only_finding_uses_the_actionable_floor_without_detector_refusal[0.95-True-stream]"
  ]
}

ask_user_pause_ttl_seconds — veredicto del owner: APPROVE CHANGE

Observable medido. El inventario declara el TTL de un pause y su expiración en un host fresco; la ruta legacy ajusta un valor superior al máximo. En la ruta nativa, TTLPolicy.resolve rechaza ese valor antes de acuñar un token (test_public_pause_refuses_an_above_maximum_lifetime_before_minting). test_public_host_continues_a_durable_pause_in_a_fresh_process mide tres bordes: resume bajo el máximo, en el máximo y después de expirar. No demuestra que el clamp legacy y el rechazo nativo sean equivalentes.

Restauración e impacto. Restaurar el clamp requiere definir qué deadline persistido y qué token recibe quien pidió un TTL excesivo; factible en teoría, pero no medido en replay (confianza baja). El impacto probado se limita a la solicitud sobre el máximo y esos tres bordes de continuidad; se desconoce su prevalencia en adoptantes. Recomendación propuesta: APPROVE CHANGE para policy explícita y rechazo temprano. Contra-caso: RESTORE si hay callers que dependen del clamp; probar emisión y resume del mismo caso antes de firmar.

Registro aprobado por instrucción explícita del owner; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "ask_user_pause_ttl_seconds",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Explicit native TTL policy rejects above-maximum lifetimes rather than silently clamping. Early configuration validation remains follow-up; restart/expiry evidence is bounded.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/human/test_the_door.py::test_public_pause_refuses_an_above_maximum_lifetime_before_minting",
    "tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[resume-below]",
    "tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[resume-equal]",
    "tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[expired]"
  ]
}

enabled_layers — veredicto del owner: APPROVE CHANGE

Observable medido. Legacy decide qué capas hidratar, incluida precedencia de un orchestrator inyectado; el inventario lo declara, pero el test nativo no demuestra esa precedencia. La composición pública con RetrievalPolicy(enabled_layers={SEMANTIC}) entrega el conjunto efectivo al source y deja el marcador episódico fuera del prompt (test_public_agent_enabled_layers_reaches_source_and_model_prompt). TestEnabledLayers mide además el estrechamiento de query y la expulsión de un record de capa deshabilitada. CORE-44 añade backfill acotado tras ese filtro en tres invocaciones públicas, sin convertirlo en paridad de precedencia.

Restauración e impacto. La selección explícita existe; restaurar el orden de precedencia implícito requiere replay con orchestrator inyectado y configuración top-level (confianza de paridad: baja). El impacto probado es egress y recall de capas en los fixtures citados, no todos los stores ni adoptantes. Recomendación propuesta: APPROVE CHANGE hacia policy nativa explícita. Contra-caso: RESTORE si la precedencia legacy es contrato de un adoptante; probar el mismo corpus y ambas configuraciones.

Decisión aprobada (CORE-26, 2026-10-02). El owner aprueba retener el selector de un orchestrator inyectado explícitamente, con diagnóstico de conflicto cuando un FrameworkConfig.enabled_layers fijado explícitamente discrepa del snapshot orchestrator.config.enabled_layers, no necesariamente del selector efectivo tras deriva del snapshot; la policy nativa directa sigue siendo RetrievalPolicy.enabled_layers. La evidencia añadida (tests/retirement/test_core26_injected_orchestrator.py) cubre el facade de compatibilidad en su ruta kernel, en run/stream/stream_typed, con y sin deriva del snapshot, sin caer al cuerpo legacy, más el caso silencioso con selector coincidente o ausente, y el Agent directo. No establece paridad universal de recuperación, paridad de bytes ni retiro del engine; los demás selectores de esta fila no cambian.

Registro aprobado; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "enabled_layers",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "An explicitly injected orchestrator's enabled-layer selector is retained: the supplied orchestrator is not rewritten from FrameworkConfig.enabled_layers. An explicitly set FrameworkConfig value that disagrees with the orchestrator.config snapshot produces one symfonic.agent WARNING diagnostic, while a matching or unset snapshot value is quiet; this diagnostic does not compare the effective selector after snapshot drift. The listed fixtures drive the compatibility facade on its kernel route across run, stream and stream_typed with and without post-build snapshot drift, with no legacy-body fallback; direct Agent selects layers only through an explicit RetrievalPolicy.enabled_layers, so the legacy implicit precedence is not transferred to native composition. This is measured fixture behavior, not universal retrieval parity, byte parity, or engine retirement.",
  "approval_reference": "Owner approval recorded in Plane CORE-26 comment 6db8a76e-70c7-484c-bd50-793c121e3440; the API comment author is provenance, not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_enabled_layers_reaches_source_and_model_prompt",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[semantic-episodic-False-run]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[semantic-episodic-False-stream]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[semantic-episodic-False-stream_typed]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[semantic-episodic-True-run]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[semantic-episodic-True-stream]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[semantic-episodic-True-stream_typed]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[episodic-semantic-False-run]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[episodic-semantic-False-stream]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[episodic-semantic-False-stream_typed]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[episodic-semantic-True-run]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[episodic-semantic-True-stream]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_selects_layers_on_kernel_route[episodic-semantic-True-stream_typed]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_matching_or_unset_selector_is_quiet[False]",
    "tests/retirement/test_core26_injected_orchestrator.py::test_injected_orchestrator_matching_or_unset_selector_is_quiet[True]"
  ]
}

hydration_min_relevance — veredicto del owner: pendiente

La dirección APPROVE CHANGE hacia score compuesto y policy explícita fue aprobada en CORE-134; esta fila continúa sin firma hasta calibrar por app, auditar las composition roots y medir el rollout.

Observable medido. Legacy filtra por similitud; la ruta nativa aplica un score compuesto de RetrievalCoordinator._gate. Con pesos sólo de cue y floor 0.5, el test público admite cue 0.9 y excluye cue 0.1 antes de compilar el prompt (test_public_agent_applies_min_relevance_before_prompt_compilation). El diferencial sintético test_core134_hydration_relevance_differential.py mide además tres consultas y cuatro registros sintéticos en el prompt del provider: el cuerpo legacy con orquestador inyectado y configuración default aplica 0.2 al score crudo, Agent stock 0.0 admite todos, y Agent con 0.2 explícito aplica cue/salience compuesto. Para Hello un recuerdo de score crudo 0.15 queda fuera en legacy y entra en Agent; para unrelated weather otro de 0.22 entra en legacy y sale con el score compuesto nativo. Un registro sin score pasa ambos. El test fija el drop ledger nativo. Estos datos NO son corpus representativo de Aboga/Cifria ni calibran un umbral de despliegue. Tampoco prueban una composition root pública legacy, stream ni el comportamiento justo en el umbral.

Veredicto CORE-432 (declared split, firmado 2026-10-20). El owner dictamina que ninguna escala gana: la división es permanente por diseño. El número del floor viaja; la escala la declara la fuente: similitud cruda en el path legacy por capas (perfecto = 1.0), blend de cuatro señales del engine en el path legacy opt-in y en kernel-vía-puerto (perfecto ≈ 0.6), compuesto cue/salience en fuentes nativas. Ningún comparado se mueve, así que ningún número sintonizado se mueve con él. Esta firma resuelve qué escala rige; no firma el APPROVE CHANGE, que sigue pendiente de calibración por app (FP-3).

Restauración e impacto. Copiar numéricamente 0.2 no preserva la selección: el default nativo neutral puede ampliar recall y un floor compuesto puede excluir un registro que legacy admitía. El scaffold y CLI componen policy explícita con 0.0 inicial y ajuste nativo por app (CORE-134/PR #437); falta calibrar con corpus real y verificar cada root soportado. Recomendación propuesta: APPROVE CHANGE del scoring nativo tras medir recall/exclusiones y aprobar el umbral/rollout por app, sin restaurar HYDRATION_MIN_RELEVANCE. Contra-caso: RESTORE del floor crudo sólo si una app demuestra dependencia del borde legacy; exigir replay con scores y egress de esa app.

Propuesta no firmada:

{"row":"hydration_min_relevance","owner":null,"decision":null,"transition_nodes":[
  "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_applies_min_relevance_before_prompt_compilation",
  "tests/agent/cutover/test_core134_hydration_relevance_differential.py::test_legacy_engine_and_native_floors_are_provider_visible[Hello]",
  "tests/agent/cutover/test_core134_hydration_relevance_differential.py::test_legacy_engine_and_native_floors_are_provider_visible[orchid release]",
  "tests/agent/cutover/test_core134_hydration_relevance_differential.py::test_legacy_engine_and_native_floors_are_provider_visible[unrelated weather]",
  "tests/agent/cutover/test_core134_hydration_relevance_differential.py::test_public_stock_agent_memory_composition_has_no_relevance_floor"
]}

phase1_spreading_weight — veredicto del owner: APPROVE CHANGE

Observable medido. El contrato legacy es el cambio de importancia persistida tras un QUICK nap. Con LearningPolicy(phase1_spreading_weight=0) frente a 1, la ruta pública Agent.stream y un coordinator con schedule y lease persisten 5.0 frente a 5.5 y ejecutan la fase en ambos casos (test_public_quick_nap_persists_phase1_spreading_weight_effect). No se compara el valor legacy del mismo corpus.

Restauración e impacto. El peso puede componerse en policy nativa; importar automáticamente FrameworkConfig y reproducir su schedule no está demostrado. El impacto probado es una mutación de importancia y ese ciclo QUICK, no los demás ciclos ni prevalencia de adoptantes. Recomendación propuesta: APPROVE CHANGE con policy compuesta. Contra-caso: RESTORE de construcción legacy si una app depende de ella; probar schedule y valor persistido pareados.

Registro aprobado por instrucción explícita del owner; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "phase1_spreading_weight",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Explicit native learning policy and QUICK composition replace implicit legacy construction; selected persisted weighting is measured, not numerical legacy parity.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_quick_nap_persists_phase1_spreading_weight_effect"
  ]
}

scope_blend_mode — veredicto del owner: APPROVE CHANGE

Observable medido. La fila legacy controla ranking jerárquico de ancestros. En un fixture público de dos records, OFF deja parent (.6) antes de tip (.4) y BLEND con half-life 1 invierte el orden (test_public_agent_scope_blend_off_and_blend_choose_different_order). Otro test muestra BACKFILL tip-first frente al parent-first preservado por fuente pre_ranked (test_public_agent_same_scenario_uses_scorer_or_pre_ranked_order). El par de selectores es el contrato declarado por el inventario.

Restauración e impacto. Los tres modos existen, pero no hay comparación pareada con pesos legacy sobre un corpus amplio; RESTORE numérico queda desconocido. El impacto demostrado es orden en esos dos records, no ranking de todos los ancestros. Recomendación propuesta: APPROVE CHANGE para ScopeBlend explícito. Contra-caso: RESTORE si se exige el orden legacy exacto; fijar scope tree y scores de un despliegue real y hacer replay.

Registro aprobado por instrucción explícita del owner; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "scope_blend_mode",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Explicit native scope blending is accepted; observed OFF/BLEND and source-pre-ranked ordering do not promise identical ranking for every corpus.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_same_scenario_uses_scorer_or_pre_ranked_order",
    "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_scope_blend_off_and_blend_choose_different_order"
  ]
}

scorer_on_hot_path — veredicto del owner: APPROVE CHANGE

Observable medido. Legacy usa un boolean para escoger el ranking de recall. Agent distingue RetrievalCoordinator de candidatos marcados pre_ranked por el source: el mismo escenario da tip-first con BACKFILL y parent-first cuando el source declara ese orden (test_public_agent_same_scenario_uses_scorer_or_pre_ranked_order). No hay prueba de ranking equivalente para todos los scores o fuentes.

Restauración e impacto. La selección explícita de ownership del ranking está cableada; traducir el boolean a cada fuente requeriría inventariar sus contratos y replay (factibilidad desconocida). Impacto demostrado: el orden de dos records en un prompt público. Recomendación propuesta: APPROVE CHANGE con coordinator o source pre-ranked explícito. Contra-caso: RESTORE si un adoptante depende del boolean y del orden antiguo; medir su fuente real.

Registro aprobado por instrucción explícita del owner; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "scorer_on_hot_path",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Ranking ownership is explicit in the native coordinator or pre-ranked source, rather than the legacy boolean; universal ranking parity is not claimed.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_same_scenario_uses_scorer_or_pre_ranked_order"
  ]
}

working_layer_exclude_speakers — veredicto del owner: APPROVE CHANGE

Reconciliación tras CORE-133 (2026-10-02). El owner aprobó el filtro nativo antes de top_k, sustituyendo la dirección RESTORE de 2026-09-26. El caso saturado real fija doce records episódicos, once etiquetados assistant y uno user, con default_top_k=2, enable_hms_prompt=True y embeddings controlados. Legacy filtra el page ya limitado; kernel filtra antes de seleccionar. En run/stream/stream_typed ambos excluyen assistant, pero sólo kernel entrega el marker user al modelo. Prueba ejecutable: tests/retirement/test_restore_row_boundaries.py::test_saturated_recall_exclusion_does_not_restore_legacy_selection. Un control legacy sin exclusión hace visible recall assistant en top-2, y otro con el user aislado hace visible ese record en legacy. Así el cero filtrado no puede ser una ruta vacía de recall. Esto sustituye el UNKNOWN de selección/filtro por una diferencia medida en este perfil; la firma es de cambio, no de paridad. El mecanismo se deriva además de RetrievalCoordinator._gate/coordinate (filtro antes de select) y SymfonicAgent._hydrate_impl (filtro de all_entries después de retrieve). La prueba exige ambos controles positivos de recall legacy, compilación kernel ausente en legacy y presente en kernel, y ningún fallback kernel. El pin comparativo no es un fallback. Decisión vigente: CORE-133 acepta el filtro nativo antes del cap para conservar el recuerdo elegible. La dirección RESTORE de «Decisiones del owner — 2026-09-26» es histórica; ni la firma ni esta prueba autorizan retiro de engine.py.

Observable medido. Legacy excluye speakers de recall; la policy nativa filtra turnos de WorkingWindow.read y records recuperados con speaker explícito. Legacy descarta un record episódico etiquetado speaker=assistant en el hydrate cross-layer (test_assistant_episodic_row_excluded_when_knob_set); Agent excluye un record recuperado con esa misma etiqueta (test_public_agent_filters_tagged_recalled_speaker, run/stream). El filtro del transcript con turno user conservado se mide en tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_filters_transcript_speakers_but_not_unschematized_recall. Ambos conservan records sin etiqueta de speaker: la prueba nativa anterior de cita unschematized no era, por sí sola, evidencia de divergencia.

Restauración e impacto. El filtro nativo está implementado y conserva records sin etiqueta. El facade run/stream/stream_typed lo ejecuta sin fallback para configuración admitida (tests/capabilities/memory/test_tagged_speaker_transition.py::test_facade_filters_tagged_recall_without_fallback). El impacto probado cubre los fixtures públicos y un perfil saturado, no todos los stores ni la prevalencia de adoptantes. Contra-caso: una fuente que limita físicamente antes del filtro puede perder el recuerdo user; medirla separadamente. La fila permanece behavior-changed con transición aprobada.

Registro aprobado por decisión explícita del owner en CORE-133; coincide exactamente con approved_changes:

{
  "row": "working_layer_exclude_speakers",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Native Agent excludes explicitly tagged speakers before top_k selection. In the saturated top_k=2 fixture with 11 tagged assistant and one tagged user episodic records, its model prompt retains one eligible user hit versus zero on the legacy capped-page route, while both exclude assistant hits. An unfiltered legacy top-2 control renders assistant recall, and a singleton legacy control renders the user record. Untagged recall remains eligible; this is measured transition impact, not universal parity.",
  "approval_reference": "Explicit owner decision dated 2026-10-02, recorded in Plane CORE-133 work item b5286b07-f6ef-4afb-b9d6-4d163fcc2394 (child of CORE-1); the API record author is provenance, not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_tagged_speaker_transition.py::test_public_agent_filters_tagged_recalled_speaker[run]",
    "tests/capabilities/memory/test_tagged_speaker_transition.py::test_public_agent_filters_tagged_recalled_speaker[stream]",
    "tests/retirement/test_restore_row_boundaries.py::test_saturated_recall_exclusion_does_not_restore_legacy_selection[run]",
    "tests/retirement/test_restore_row_boundaries.py::test_saturated_recall_exclusion_does_not_restore_legacy_selection[stream]",
    "tests/retirement/test_restore_row_boundaries.py::test_saturated_recall_exclusion_does_not_restore_legacy_selection[stream_typed]"
  ]
}

dev_sqlite_checkpoint_path — veredicto del owner: APPROVE CHANGE

Observable medido. Legacy usa un archivo de checkpoint LangGraph cuando se habilita ask-user o persistencia de transcript y no tiene prioridad otro backend (agent/config.py, agent/engine.py). El contrato observable es el payload de resume después de reiniciar; el mismo path también servía get_transcript() y rehidratación de working deque cuando se habilitaba persistencia de transcript sin ask-user. AgentHost recupera en otro proceso con puertos de checkpoint y redención SQLite explícitos: los casos resume, single-use y wrong-scope prueban continuidad, consumo único y rechazo de scope ajeno. El scaffold rechaza el path suelto. La prueba de host usa puertos aportados por el adoptante, no un adaptador SQLite built-in. No mide reemplazo de las API de transcript ni import de archivos LangGraph existentes.

Decisión firmada. El owner aprobó CHANGE en Plane CORE-1, comentario 4ea3d6e3-7ce2-4895-b04b-0d36be5b4c9b: en 11.0 el adoptante compone puertos durables explícitos con AgentHost. No se migran archivos LangGraph SQLite legacy ni sus pausas, transcript o working deque. El path suelto se rechaza antes del dispatch; si hacen falta esos archivos, el pin publicable es 9.12. El cambio afecta al subconjunto que configuró ese path para resume o transcript; su tamaño no está medido. La evidencia de SQLitePorts prueba continuidad del nuevo puerto en otro proceso, no import ni paridad de archivos legacy. La migración global sigue bloqueada por otras filas y este veredicto no autoriza retirar el engine.

Registro de transición aprobado:

{"row":"dev_sqlite_checkpoint_path","owner":"amielsinue","decision":"APPROVE CHANGE",
 "rationale":"Version 11 requires explicit durable checkpoint and consumption ports composed with AgentHost. The legacy bare path refuses; existing LangGraph SQLite files, paused runs, transcripts, and working deque data are not imported. Fresh-process resume, single-use consumption, and scope isolation are measured only for the adopter-owned SQLite ports. Deployments needing legacy files stay on the published 9.12 line.",
 "approval_reference":"Explicit owner APPROVE CHANGE in Plane CORE-1 comment 4ea3d6e3-7ce2-4895-b04b-0d36be5b4c9b; the comment records the owner's decision, not a claim of legacy-file parity.",
 "transition_nodes":[
  "tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[resume]",
  "tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[single-use]",
  "tests/platform/test_fp3_public_preservation_journeys.py::test_public_host_continues_a_durable_pause_in_a_fresh_process[wrong-scope]",
  "tests/retirement/test_core137_sqlite_transition.py::test_legacy_sqlite_path_refuses_before_dispatch[run]",
  "tests/retirement/test_core137_sqlite_transition.py::test_legacy_sqlite_path_refuses_before_dispatch[stream]",
  "tests/retirement/test_core137_sqlite_transition.py::test_legacy_sqlite_path_refuses_before_dispatch[stream_typed]"
]}

domain_description_max_chars — veredicto del owner: APPROVE CHANGE

Estado vigente (CORE-140). Los límites full-HMS y JIT se aplican a los bytes de directiva que llegan al proveedor en Agent run/stream. La descripción vacía usa el fallback seleccionado sin aviso. El primer read de cada composición explícita emite una advertencia sin payload que nombra RegionalPromptPolicy.domain_description_max_chars; otro read de esa composición no añade avisos. Cada Agent nuevo emite su aviso al construirse; dos turnos posteriores no lo repiten. El aviso legacy sigue nombrando FrameworkConfig.domain_description_max_chars y vive una vez por SymfonicAgent.

Límite del observable. Dos composiciones de un mismo source se prueban directamente en la capability; el Agent público rechaza dos etapas prompting.context, así que la duración de dos composiciones en un mismo Agent queda UNKNOWN. La comparación de PR #439 mide el cuerpo JIT completo con su diferencia aprobada de ubicación del manifest. No se afirma paridad de template completo, reachability de toda instalación ni retiro de engine. Las propuestas previas de PR300 y la restauración de PR #419 quedan documentadas por sus pruebas; ya no son un veredicto pendiente.

Registro aprobado por el owner en CORE-1 comentario 50509c6e; coincide exactamente con approved_changes y sus nodos ejecutables:

{
  "row": "domain_description_max_chars",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "The public Agent composes RegionalPromptPolicy.domain_description_max_chars with independent full-HMS and JIT caps. The selected directive and empty fallback reach provider requests in run and stream. For truncation, the first contribution read for each of two capability compositions made from one shared source emits the exact payload-free RegionalPromptPolicy warning; the second read emits none. Each separate public Agent emits one notice during construction; two subsequent run/stream turns add none. Legacy retains its FrameworkConfig wording and once-per-SymfonicAgent lifetime. A public Agent accepts only one prompting stage and rejects two compositions, so the same-Agent multi-composition lifetime remains UNKNOWN through this API. This approval is scoped to the measured composition seam and public Agent routes; it does not claim general deployment reachability, whole-template parity, or engine retirement.",
  "approval_reference": "Owner approval recorded in Plane CORE-1 comment 50509c6e; the API comment author is provenance, not the approving owner.",
  "transition_nodes": [
    "tests/retirement/test_restore_row_boundaries.py::test_jit_domain_restores_legacy_directive_bytes[truncated-run]",
    "tests/retirement/test_core1_full_hms_domain_cap_restore.py::test_full_hms_domain_directive_matches_legacy[truncated-run]",
    "tests/retirement/test_core1_full_hms_domain_cap_restore.py::test_full_cap_is_independent_of_jit_cap[truncated]",
    "tests/retirement/test_core1_full_hms_domain_cap_restore.py::test_default_cap_is_legacy_default_on_public_agent_run[jit-401-400]",
    "tests/retirement/test_core1_full_hms_domain_cap_restore.py::test_full_hms_truncation_warns_once_per_composed_agent",
    "tests/retirement/test_core140_domain_cap_transition.py::test_native_notice_is_once_per_composition_across_separate_agents[stratified-7-run]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_native_notice_is_once_per_composition_across_separate_agents[stratified-7-stream]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_native_notice_is_once_per_composition_across_separate_agents[jit-3-run]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_native_notice_is_once_per_composition_across_separate_agents[jit-3-stream]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_empty_domain_fallback_is_provider_visible_without_notice[stratified-(no domain-specific directives)-run]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_empty_domain_fallback_is_provider_visible_without_notice[stratified-(no domain-specific directives)-stream]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_empty_domain_fallback_is_provider_visible_without_notice[jit-(none)-run]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_empty_domain_fallback_is_provider_visible_without_notice[jit-(none)-stream]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_shared_source_has_one_notice_guard_per_composition[stratified-7]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_shared_source_has_one_notice_guard_per_composition[jit-3]",
    "tests/retirement/test_core140_domain_cap_transition.py::test_public_agent_refuses_two_prompt_compositions"
  ]
}

state_class — veredicto del owner: APPROVE CHANGE

Observable medido. Legacy pasa un schema LangGraph/TypedDict extendido al grafo; tests/agent/test_state_class_extension.py fija el wiring y las anotaciones de claves, no ejecuta un reducer custom ni su recuperación. En Agent, state= entrega un mapping por turno a la capability compuesta: la prueba pública lo ve por run y stream, y el turno siguiente no lo hereda. La continuación recuperada tampoco reproduce silenciosamente el mapping (test_issue190_migration_contracts.py). La prueba diferencial CORE-21 observa los tres turnos con el mismo modelo guionado y comprueba que SymfonicAgent rechaza el schema configurado antes de despachar. No hay conversión automática de reducers ni persistencia del schema antiguo.

Restauración e impacto. Restaurar el schema completo requeriría un adapter de reducers y persistencia/recuperación host-owned; no hay replay de una clase de estado real (factibilidad desconocida). El cambio alcanza sólo a quienes pasan state_class no nulo; su población no está medida. Recomendación propuesta: APPROVE CHANGE hacia estado explícito por turno. Contra-caso: RESTORE si un adopter depende de merge de reducer o estado persistente; exigir fixture de schema y continuación antes de firmar.

Registro aprobado por instrucción explícita del owner; coincide con approved_changes. Las recomendaciones anteriores documentan la deliberación, no una decisión todavía pendiente:

{
  "row": "state_class",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Explicit per-turn mappings replace legacy state schemas; no automatic reducer conversion or continuation persistence is promised.",
  "approval_reference": "Explicit owner direction in conversation 2026-09-26, recorded by automation in Plane CORE-1 comment 5596490f-891d-4dec-a42a-4bd1eac1bf70; API comment author is not the approving owner.",
  "transition_nodes": [
    "tests/platform/test_issue190_migration_contracts.py::test_public_custom_turn_state_reaches_a_capability_and_stays_per_turn[run]",
    "tests/platform/test_issue190_migration_contracts.py::test_public_custom_turn_state_reaches_a_capability_and_stays_per_turn[stream]",
    "tests/platform/test_issue190_migration_contracts.py::test_recovered_continuation_does_not_silently_replay_custom_turn_state",
    "tests/retirement/test_core21_state_class_differential.py::test_custom_state_is_per_turn_and_legacy_schema_refuses_before_dispatch[run]",
    "tests/retirement/test_core21_state_class_differential.py::test_custom_state_is_per_turn_and_legacy_schema_refuses_before_dispatch[stream]"
  ]
}

working_memory_recent_turns — veredicto del owner: APPROVE CHANGE

Dirección vigente: APPROVE CHANGE (CORE-135, 2026-10-02), que sustituye el RESTORE autorizado en «Decisiones del owner — 2026-09-26»; la recomendación posterior de RESTORE es histórica, no una firma de paridad.

Observable medido. Legacy default 2 lee los últimos N turnos y cero deshabilita la ventana. En la ruta pública Agent, N=1 y N=2 alteran el prompt; memory_capabilities(conversation=..., recent_turns=0) acepta la composición (test_public_agent_recent_turns_changes_model_prompt_and_zero_disables_window). CORE-29 mide ventanas positivas en los tres entrypoints sin fallback, y el test público directo tests/retirement/test_core29_working_window_evidence.py::test_direct_agent_zero_disables_window_but_still_retrieves demuestra que WorkingWindow(0) omite la lectura sin perder recall; el factory público omite la lectura y el facade run/stream/stream_typed con cero no cae a fallback para configuración admitida. El recall independiente, incluidos records WORKING recuperados por ranking, permanece habilitado (tests/retirement/test_core29_working_window_evidence.py::test_facade_zero_disables_window_and_retrieves_without_fallback).

Restauración e impacto. El owner autorizó implementar RESTORE del cero que deshabilita ventana sin apagar recall. Factory y facade tienen evidencia ejecutable de admisión y ausencia de lectura; el impacto demostrado se limita a los fixtures y a quienes configuran cero, con prevalencia desconocida. La autorización de implementación no fue firma de equivalencia; la fila sigue behavior-changed y la firma vigente es la de abajo.

Decisión aprobada (CORE-135, 2026-10-02). El owner mantiene la ventana nativa explícita con HMS desactivado, y el scaffold cuenta N intercambios frente a N utterances nativas. Evidencia añadida (test_core135_working_window_differential.py y test_core135_window_prompt_and_scaffold.py):

  • Con HMS activo, en el corpus sembrado y N=0,1,2, el prefijo de recencia de legacy, nativo y la ruta admitida coincide en run y stream, sin fallback.
  • Con HMS desactivado, legacy envía la consulta sin prefijo; el Agent nativo y la ruta admitida conservan las N utterances (cambio aprobado).
  • Las celdas stream_typed se miden sólo en el facade de compatibilidad (legacy y admitida). El stream_typed nativo es UNKNOWN: Agent no expone stream_typed público.
  • El historial de chat del scaffold con N intercambios resuelve a 2N mensajes guardados, acotados a su sesión; el usuario y tenant ajenos son rechazados. La ventana nativa cuenta utterances, no pares.

Esto no es paridad del prompt completo, ni de bytes, ni retiro del engine; el recall rankeado independiente no forma parte de este prefijo.

Registro aprobado; coincide con approved_changes. La recomendación anterior documenta la deliberación, no una decisión todavía pendiente:

{
  "row": "working_memory_recent_turns",
  "owner": "amielsinue",
  "decision": "APPROVE CHANGE",
  "rationale": "Native memory_capabilities keeps an explicit conversation window of N utterances, retained with HMS prompting off, where the legacy HMS-off route sends a bare query; zero disables the window and ranked recall stays independent. The generated scaffold's chat history counts N exchanges, which resolve to 2N saved messages scoped to the caller's session, so scaffold N exchanges and native N utterances are different units. Legacy and native agree on the recency prefix only in the seeded run/stream differential corpus for N=0,1,2; the typed facade cells are measured on the compatibility facade only, and native stream_typed is UNKNOWN because Agent has no public stream_typed. This is not whole-prompt parity, not byte parity, and not engine retirement.",
  "approval_reference": "Owner approval recorded in Plane CORE-135 comment be4ee003-c9cd-4a8f-bfaa-f4ba24795d43; the API comment author is provenance, not the approving owner.",
  "transition_nodes": [
    "tests/capabilities/memory/test_issue188_public_retrieval_contracts.py::test_public_agent_recent_turns_changes_model_prompt_and_zero_disables_window",
    "tests/retirement/test_core135_working_window_differential.py::test_same_corpus_public_window_differential[run-0]",
    "tests/retirement/test_core135_working_window_differential.py::test_same_corpus_public_window_differential[run-1]",
    "tests/retirement/test_core135_working_window_differential.py::test_same_corpus_public_window_differential[run-2]",
    "tests/retirement/test_core135_working_window_differential.py::test_same_corpus_public_window_differential[stream-0]",
    "tests/retirement/test_core135_working_window_differential.py::test_same_corpus_public_window_differential[stream-1]",
    "tests/retirement/test_core135_working_window_differential.py::test_same_corpus_public_window_differential[stream-2]",
    "tests/retirement/test_core135_working_window_differential.py::test_hms_off_preserves_native_window_as_approved_change[run-0]",
    "tests/retirement/test_core135_working_window_differential.py::test_hms_off_preserves_native_window_as_approved_change[run-1]",
    "tests/retirement/test_core135_working_window_differential.py::test_hms_off_preserves_native_window_as_approved_change[run-2]",
    "tests/retirement/test_core135_working_window_differential.py::test_hms_off_preserves_native_window_as_approved_change[stream-0]",
    "tests/retirement/test_core135_working_window_differential.py::test_hms_off_preserves_native_window_as_approved_change[stream-1]",
    "tests/retirement/test_core135_working_window_differential.py::test_hms_off_preserves_native_window_as_approved_change[stream-2]",
    "tests/retirement/test_core135_working_window_differential.py::test_typed_facade_cells_and_native_unknown[0]",
    "tests/retirement/test_core135_working_window_differential.py::test_typed_facade_cells_and_native_unknown[1]",
    "tests/retirement/test_core135_working_window_differential.py::test_typed_facade_cells_and_native_unknown[2]",
    "tests/retirement/test_core135_window_prompt_and_scaffold.py::test_scaffold_window_is_2n_rows_and_scoped_to_its_session[0]",
    "tests/retirement/test_core135_window_prompt_and_scaffold.py::test_scaffold_window_is_2n_rows_and_scoped_to_its_session[1]",
    "tests/retirement/test_core135_window_prompt_and_scaffold.py::test_scaffold_window_is_2n_rows_and_scoped_to_its_session[2]",
    "tests/retirement/test_core135_window_prompt_and_scaffold.py::test_scaffold_window_refuses_other_user_and_other_tenant"
  ]
}

Checklist histórico de CORE-1

En 0f06678a hay exactamente estas 14 filas pendientes de disposición: ask_user_pause_ttl_seconds, dev_sqlite_checkpoint_path, domain.core_preferences, domain_description_max_chars, enabled_layers, fabrication_refuse_min_confidence, hydration_min_relevance, phase1_spreading_weight, phase_12_action_type_from_tool_calls, scope_blend_mode, scorer_on_hot_path, state_class, working_layer_exclude_speakers y working_memory_recent_turns.

Para cada una: confirmar owner del inventario y escoger RESTORE/CHANGE/REMOVAL. Si se restaura, ejecutar evidencia propia y actualizar el status tras revisión; si se aprueba un cambio o retiro, registrar la decisión firmada y nodos del outcome de esa fila. Hasta entonces la migración sigue bloqueada.