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_typedse miden sólo en el facade de compatibilidad (legacy y admitida). Elstream_typednativo es UNKNOWN:Agentno exponestream_typedpú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.