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
--executedentro 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:
MART inicial no esta vacia: daily=1 seller=25 customer=173 sku=180- 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 --executeno puede ser idempotente por reintento exitoso; debe terminarBLOCKED/ABORTEDsin nuevosINSERT - 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