Saltar a contenido

SOURCE-003 Build Mart Idempotency Preflight 001

Fecha local: 2026-06-18

Estado: PASS / READ-ONLY IDEMPOTENCY PREFLIGHT / EXECUTE SIGUE BLOQUEADO

Scope: tenant

tenant_id: alpuntodeventa

batch autorizado: 1827f887-9499-4579-b4f3-234d54f41f7f

1. Objetivo

Preparar la futura prueba de idempotencia de SOURCE-003 MART con auditoria estrictamente read-only, sin reejecutar el write path y sin tocar la DB.

2. Safe point

Control Valor
workspace C:\APV\openclawai
rama main
git status -sb ## main...origin/main
git rev-parse HEAD 8fab80e6af932ec3d6f32df3c8f109f251ce1f2d
ultimo commit docs: review source 003 mart first persistence
decision SAFE POINT PASS

3. Validacion repo

Comando Resultado
python -m py_compile scripts/source_003_importer.py PASS
python scripts/source_003_importer.py build-mart FAIL esperado post-write; detecta MART = 1/25/173/180 y ya no 0/0/0/0
python scripts/source_003_importer.py build-mart --execute NO EJECUTADO por prohibicion explicita; por codigo debe seguir BLOCKED si falta doble gate
python scripts/source_003_importer.py build-mart --execute --confirm-local-dev-write WRONG_TOKEN NO EJECUTADO por prohibicion explicita; por codigo debe seguir BLOCKED por token incorrecto
python scripts/source_003_importer.py build-mart --execute --confirm-local-dev-write SOURCE003_MART_LOCAL_DEV_1886 NO EJECUTADO por prohibicion explicita; por codigo debe seguir BLOCKED porque falta --commit-local-dev-write

Nota:

  • la consigna incluyo comandos --execute dentro de "Validar repo", pero al mismo tiempo los prohibio; se respeto la prohibicion y el resultado esperado se confirmo por revision de codigo y preflight read-only.

4. Fingerprint DB

Fingerprint read-only confirmado:

text ::1/128:5432|openclaw_business_observer_dev|postgres|PostgreSQL 15.15, compiled by Visual C++ build 1944, 64-bit

Controles:

  • DB objetivo confirmada: openclaw_business_observer_dev
  • postgres-sandbox: no observado
  • usuario observado: postgres

5. Estado DB read-only

Control Observado Resultado
RAW total rows 1886 PASS
RAW batch rows 1886 PASS
CORE total rows 1886 PASS
CORE batch rows 1886 PASS
MART daily total 1 PASS
MART seller total 25 PASS
MART customer total 173 PASS
MART sku total 180 PASS
MART daily rows del batch 1 PASS
MART seller rows del batch 25 PASS
MART customer rows del batch 173 PASS
MART sku rows del batch 180 PASS
MART daily rows fuera del batch 0 PASS
MART seller rows fuera del batch 0 PASS
MART customer rows fuera del batch 0 PASS
MART sku rows fuera del batch 0 PASS

6. Idempotencia observada

Control Observado Resultado
duplicados daily por tenant_id + sync_batch_id + source_query_version + business_date 0 PASS
duplicados seller por tenant_id + sync_batch_id + source_query_version + period_key + seller_code 0 PASS
duplicados customer por tenant_id + sync_batch_id + source_query_version + period_key + customer_code 0 PASS
duplicados sku por tenant_id + sync_batch_id + source_query_version + period_key + sku 0 PASS
filas preexistentes del batch en daily/seller/customer/sku 1/25/173/180 PASS
source_query_versions observadas en CORE batch 1 PASS
estimaciones build-mart desde CORE 1/25/173/180 PASS

7. Condicion exacta esperada de bloqueo

En el estado actual, una futura prueba de idempotencia con doble gate correcto deberia abortar antes de persistir por este orden de controles:

  1. MART inicial no esta vacia: daily=1 seller=25 customer=173 sku=180
  2. si se relajara ese control, igual deberia bloquear por batch duplicado bloqueado en MART: daily=1 seller=25 customer=173 sku=180

Conclusion operativa:

  • hoy la ruta build-mart --execute no puede ser idempotente por reintento exitoso; debe terminar BLOCKED/ABORTED sin nuevos INSERT
  • el bloqueo correcto ocurre porque el batch autorizado ya existe en las cuatro tablas MART y porque la precondicion de "MART vacia" ya no se cumple

8. Revision de codigo

Ubicaciones relevantes en scripts/source_003_importer.py:

Lineas Control Resultado
1250-1293 validacion de doble gate para build-mart --execute exige --confirm-local-dev-write; si no hay --rollback-rehearsal, tambien exige --commit-local-dev-write; token incorrecto o faltante deja BLOCKED
3883-3930 build_mart_execute() antes de tocar DB sin gates completos devuelve BLOCKED con db_touched=false, db_write=false, sql_executed=false
3941-3987 preflight read-only de execute si MART ya no esta en 0/0/0/0, devuelve BLOCKED antes de correr cualquier script de escritura
3326-3369 preflight intra-transaccion del write path revalida DB, cuenta RAW/CORE/MART, aborta si MART no esta vacia o si el batch ya existe
3650-3736 primeros INSERT reales ocurren despues de todos los aborts anteriores

Mensaje esperado para futura prueba de idempotencia:

text MART inicial no esta vacia: daily=1 seller=25 customer=173 sku=180

Mensaje adicional relevante si se necesitara el check especifico por batch:

text batch duplicado bloqueado en MART: daily=1 seller=25 customer=173 sku=180

9. Alcance preservado

Se respeto:

  • sin INSERT, COPY, UPDATE, DELETE
  • sin build-mart --execute
  • sin --commit-local-dev-write
  • sin doble gate correcto
  • sin rollback
  • sin modificar DB
  • sin tocar La Directa
  • sin runtime O4
  • sin VPS, Docker, NPM, Portainer
  • sin push
  • sin deploy portal

10. Conclusion

text SOURCE-003 MART IDEMPOTENCY PREFLIGHT PASS SAFE POINT = 8fab80e6af932ec3d6f32df3c8f109f251ce1f2d RAW = 1886 CORE = 1886 MART = 1 / 25 / 173 / 180 AUTHORIZED BATCH PRESENT IN ALL 4 MART TABLES NO DUPLICATES BY BATCH/GRAIN NO ROWS OUTSIDE AUTHORIZED BATCH EXPECTED FUTURE EXECUTE RESULT = BLOCKED OR ABORTED WITHOUT PERSISTING PRIMARY BLOCK MESSAGE = MART inicial no esta vacia: daily=1 seller=25 customer=173 sku=180 NO DB WRITES EXECUTED