hikoutei 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +44 -21
- package/README.ko.md +43 -23
- package/README.md +49 -33
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts +3 -3
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.js +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarEntityRuntime.d.ts +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarEntityRuntime.js +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarRuntime.js +3 -3
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarRuntime.js.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts +3 -3
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js +15 -15
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js +3 -3
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.d.ts +5 -5
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.d.ts.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js +5 -5
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.d.ts +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js +5 -5
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js.map +1 -1
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingSql.js +3 -3
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingSql.js.map +1 -1
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts +156 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js +1112 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts +87 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.js +97 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts +53 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.js +61 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts +16 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.js +13 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +83 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js +413 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts +86 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js +439 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts +115 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js +522 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts +17 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js +99 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts +242 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js +707 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts +16 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js +29 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts +26 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js +57 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts +102 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js +375 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts +168 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js +247 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts +47 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js +60 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js.map +1 -0
- package/dist/api/Hikoutei.d.ts +1 -1
- package/dist/api/Hikoutei.js +1 -1
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +2 -2
- package/dist/application/orm/mapping/contracts.d.ts +2 -2
- package/dist/application/orm/mapping/contracts.d.ts.map +1 -1
- package/dist/application/orm/mapping/definition.js +5 -5
- package/dist/application/orm/mapping/definition.js.map +1 -1
- package/dist/application/orm/mapping/projection.js +7 -7
- package/dist/application/orm/mapping/projection.js.map +1 -1
- package/dist/application/orm/persistence/flush/flushCoordinator.d.ts +3 -3
- package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -1
- package/dist/application/orm/persistence/flush/flushCoordinator.js +2 -2
- package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -1
- package/dist/application/orm/persistence/projection/projectionEffects.d.ts +1 -1
- package/dist/application/orm/persistence/projection/projectionEffects.js +6 -6
- package/dist/application/orm/persistence/projection/projectionEffects.js.map +1 -1
- package/dist/application/orm/persistence/support/contracts.d.ts +2 -2
- package/dist/application/orm/persistence/support/contracts.d.ts.map +1 -1
- package/dist/application/sync/inbound/autoSystemConflictResolution.js +7 -7
- package/dist/application/sync/inbound/autoSystemConflictResolution.js.map +1 -1
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts +3 -3
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts.map +1 -1
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.js +1 -1
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.js.map +1 -1
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +17 -1
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +27 -1
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts +2 -2
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +26 -6
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +24 -9
- package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorker.js +128 -81
- package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +31 -14
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +32 -15
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +13 -9
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +53 -37
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +29 -19
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +59 -41
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts +4 -4
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js +3 -3
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts +3 -3
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js +42 -46
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js.map +1 -1
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts +8 -8
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts.map +1 -1
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js +15 -15
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js.map +1 -1
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts +3 -3
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts.map +1 -1
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js +10 -10
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js.map +1 -1
- package/dist/application/sync/service/SyncPollingSupervisor.d.ts +1 -1
- package/dist/application/sync/service/SyncPollingSupervisor.js +1 -1
- package/dist/application/sync/service/SyncServiceBootstrap.d.ts +29 -19
- package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
- package/dist/application/sync/service/SyncServiceBootstrap.js +103 -78
- package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
- package/dist/application/sync/service/errors.d.ts +1 -1
- package/dist/application/sync/service/errors.js +1 -1
- package/dist/application/sync/service/errors.js.map +1 -1
- package/dist/application/sync/sheets/conflictProjection.d.ts.map +1 -0
- package/dist/application/sync/sheets/conflictProjection.js.map +1 -0
- package/dist/application/sync/{gateway → sheets}/conflictProjectionRegistration.d.ts +1 -1
- package/dist/application/sync/sheets/conflictProjectionRegistration.d.ts.map +1 -0
- package/dist/application/sync/{gateway → sheets}/conflictProjectionRegistration.js +3 -3
- package/dist/application/sync/sheets/conflictProjectionRegistration.js.map +1 -0
- package/dist/application/sync/sheets/constants.d.ts +66 -0
- package/dist/application/sync/sheets/constants.d.ts.map +1 -0
- package/dist/application/sync/{gateway → sheets}/constants.js +15 -15
- package/dist/application/sync/sheets/constants.js.map +1 -0
- package/dist/application/sync/sheets/errors.d.ts +15 -0
- package/dist/application/sync/sheets/errors.d.ts.map +1 -0
- package/dist/application/sync/sheets/errors.js +16 -0
- package/dist/application/sync/sheets/errors.js.map +1 -0
- package/dist/application/sync/{gateway/coordinator/CoordinatedSyncGateway.d.ts → sheets/mutationCoordinator/CoordinatedSheetsProvider.d.ts} +29 -28
- package/dist/application/sync/sheets/mutationCoordinator/CoordinatedSheetsProvider.d.ts.map +1 -0
- package/dist/application/sync/{gateway/coordinator/CoordinatedSyncGateway.js → sheets/mutationCoordinator/CoordinatedSheetsProvider.js} +27 -26
- package/dist/application/sync/sheets/mutationCoordinator/CoordinatedSheetsProvider.js.map +1 -0
- package/dist/application/sync/{gateway/coordinator → sheets/mutationCoordinator}/asyncMutex.d.ts +2 -3
- package/dist/application/sync/sheets/mutationCoordinator/asyncMutex.d.ts.map +1 -0
- package/dist/application/sync/sheets/mutationCoordinator/asyncMutex.js.map +1 -0
- package/dist/application/sync/{gateway/coordinator/coordinatorTelemetry.d.ts → sheets/mutationCoordinator/laneTelemetry.d.ts} +4 -4
- package/dist/application/sync/sheets/mutationCoordinator/laneTelemetry.d.ts.map +1 -0
- package/dist/application/sync/{gateway/coordinator/coordinatorTelemetry.js → sheets/mutationCoordinator/laneTelemetry.js} +5 -5
- package/dist/application/sync/sheets/mutationCoordinator/laneTelemetry.js.map +1 -0
- package/dist/application/sync/{gateway/SyncGatewayBootstrap.d.ts → sheets/sheetsProvisioning.d.ts} +14 -14
- package/dist/application/sync/sheets/sheetsProvisioning.d.ts.map +1 -0
- package/dist/application/sync/sheets/sheetsProvisioning.js +95 -0
- package/dist/application/sync/sheets/sheetsProvisioning.js.map +1 -0
- package/dist/application/sync/{gateway/syncGateway.d.ts → sheets/syncSheets.d.ts} +61 -117
- package/dist/application/sync/sheets/syncSheets.d.ts.map +1 -0
- package/dist/application/sync/sheets/syncSheets.js +144 -0
- package/dist/application/sync/sheets/syncSheets.js.map +1 -0
- package/dist/application/sync/{gateway/transportClassification.d.ts → sheets/transportOutcome.d.ts} +23 -22
- package/dist/application/sync/sheets/transportOutcome.d.ts.map +1 -0
- package/dist/application/sync/sheets/transportOutcome.js +97 -0
- package/dist/application/sync/sheets/transportOutcome.js.map +1 -0
- package/dist/application/sync/sheets/validation.d.ts +22 -0
- package/dist/application/sync/sheets/validation.d.ts.map +1 -0
- package/dist/application/sync/sheets/validation.js +79 -0
- package/dist/application/sync/sheets/validation.js.map +1 -0
- package/dist/application/sync/telemetry/syncTiming.d.ts +7 -7
- package/dist/application/sync/telemetry/syncTiming.d.ts.map +1 -1
- package/dist/application/sync/telemetry/syncTiming.js +2 -2
- package/dist/application/sync/telemetry/syncTiming.js.map +1 -1
- package/dist/domain/evaluate/contracts.d.ts +1 -1
- package/dist/domain/evaluate/contracts.js +1 -1
- package/dist/domain/model/constants.d.ts +1 -1
- package/dist/domain/model/constants.d.ts.map +1 -1
- package/dist/domain/model/types.d.ts +1 -1
- package/dist/domain/model/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/storage/index.d.ts +1 -1
- package/dist/infrastructure/storage/index.d.ts.map +1 -1
- package/dist/infrastructure/storage/index.js +1 -1
- package/dist/infrastructure/storage/index.js.map +1 -1
- package/dist/infrastructure/storage/state/observation/observationAudit.d.ts +1 -1
- package/dist/infrastructure/storage/state/observation/observationAudit.js +1 -1
- package/dist/infrastructure/storage/state/observation/observationTypes.d.ts +3 -3
- package/dist/infrastructure/storage/state/observation/observationTypes.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +13 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +23 -2
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts +9 -3
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js +7 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +11 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +44 -3
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
- package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts +4 -4
- package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/shared/syncRegistry.js +4 -4
- package/dist/infrastructure/storage/sync/shared/syncRegistry.js.map +1 -1
- package/dist/shared/encoding/types.d.ts +1 -1
- package/docs/architecture.md +52 -23
- package/docs/ci.md +31 -23
- package/docs/code-guidelines.md +10 -18
- package/docs/development.md +37 -11
- package/docs/gateway-removal-inventory.md +147 -0
- package/docs/quick-start.md +36 -26
- package/docs/sync-bulk-write-benchmark.md +561 -0
- package/docs/sync-observability.md +38 -45
- package/docs/write-and-synchronization-flow.md +56 -39
- package/package.json +5 -4
- package/apps-script/gateway/Code.gs +0 -447
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts +0 -43
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.js +0 -52
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +0 -24
- package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/index.js +0 -13
- package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts +0 -44
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js +0 -181
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts +0 -3
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +0 -810
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts +0 -31
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +0 -560
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts +0 -12
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js +0 -166
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.d.ts +0 -8
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.js +0 -122
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +0 -31
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +0 -567
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts +0 -19
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js +0 -37
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts +0 -51
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js +0 -60
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts +0 -44
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js +0 -40
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts +0 -12
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js +0 -41
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts +0 -5
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js +0 -53
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts +0 -4
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js +0 -2
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts +0 -11
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js +0 -36
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts +0 -68
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js +0 -273
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +0 -73
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +0 -363
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/validation.d.ts +0 -3
- package/dist/adapter/sheets/providers/apps-script-gateway/validation.d.ts.map +0 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/validation.js +0 -10
- package/dist/adapter/sheets/providers/apps-script-gateway/validation.js.map +0 -1
- package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts.map +0 -1
- package/dist/application/sync/gateway/SyncGatewayBootstrap.js +0 -95
- package/dist/application/sync/gateway/SyncGatewayBootstrap.js.map +0 -1
- package/dist/application/sync/gateway/conflictProjection.d.ts.map +0 -1
- package/dist/application/sync/gateway/conflictProjection.js.map +0 -1
- package/dist/application/sync/gateway/conflictProjectionRegistration.d.ts.map +0 -1
- package/dist/application/sync/gateway/conflictProjectionRegistration.js.map +0 -1
- package/dist/application/sync/gateway/constants.d.ts +0 -66
- package/dist/application/sync/gateway/constants.d.ts.map +0 -1
- package/dist/application/sync/gateway/constants.js.map +0 -1
- package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.d.ts.map +0 -1
- package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.js.map +0 -1
- package/dist/application/sync/gateway/coordinator/asyncMutex.d.ts.map +0 -1
- package/dist/application/sync/gateway/coordinator/asyncMutex.js.map +0 -1
- package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.d.ts.map +0 -1
- package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.js.map +0 -1
- package/dist/application/sync/gateway/errors.d.ts +0 -15
- package/dist/application/sync/gateway/errors.d.ts.map +0 -1
- package/dist/application/sync/gateway/errors.js +0 -16
- package/dist/application/sync/gateway/errors.js.map +0 -1
- package/dist/application/sync/gateway/syncGateway.d.ts.map +0 -1
- package/dist/application/sync/gateway/syncGateway.js +0 -191
- package/dist/application/sync/gateway/syncGateway.js.map +0 -1
- package/dist/application/sync/gateway/transportClassification.d.ts.map +0 -1
- package/dist/application/sync/gateway/transportClassification.js +0 -133
- package/dist/application/sync/gateway/transportClassification.js.map +0 -1
- package/dist/application/sync/gateway/validation.d.ts +0 -22
- package/dist/application/sync/gateway/validation.d.ts.map +0 -1
- package/dist/application/sync/gateway/validation.js +0 -79
- package/dist/application/sync/gateway/validation.js.map +0 -1
- /package/dist/application/sync/{gateway → sheets}/conflictProjection.d.ts +0 -0
- /package/dist/application/sync/{gateway → sheets}/conflictProjection.js +0 -0
- /package/dist/application/sync/{gateway/coordinator → sheets/mutationCoordinator}/asyncMutex.js +0 -0
|
@@ -1554,3 +1554,564 @@ eliminate the documented two-flush crash window between target and receipt
|
|
|
1554
1554
|
writes.
|
|
1555
1555
|
|
|
1556
1556
|
Artifact: `.local/gateway-write-verification-20260804.json`.
|
|
1557
|
+
|
|
1558
|
+
## 2026-08-04 — Direct Sheets API service-account gate (blocked at auth)
|
|
1559
|
+
|
|
1560
|
+
- Branch: `feature/service-account-sheets`
|
|
1561
|
+
- Command: `node --env-file=.env scripts/bench/direct-sheets-api-service-account.mjs`
|
|
1562
|
+
- Backend: Node direct Google Sheets API client using `GoogleAuth` and a local
|
|
1563
|
+
service-account JSON path; Apps Script, `Code.gs`, Advanced Sheets Service, and
|
|
1564
|
+
Drive API were not used. Credential values and spreadsheet identifiers are not
|
|
1565
|
+
recorded.
|
|
1566
|
+
- Setup: Stage 0 attempted one spreadsheet metadata read. No benchmark tab was
|
|
1567
|
+
created because authentication/authorization failed before setup.
|
|
1568
|
+
|
|
1569
|
+
| Stage | Result |
|
|
1570
|
+
| --- | --- |
|
|
1571
|
+
| Environment/credential shape | local file readable and service-account JSON shape valid |
|
|
1572
|
+
| Stage 0 metadata/auth smoke | blocked: classified `permission` / HTTP `403` |
|
|
1573
|
+
| Stage 1 raw append | not run |
|
|
1574
|
+
| Stage 2 key reads | not run |
|
|
1575
|
+
| Stage 3 postcondition | not run |
|
|
1576
|
+
| Stage 4 response-loss replay | not run |
|
|
1577
|
+
| Cleanup | `ok`, 0 tabs created, 0 deleted, 0 remaining |
|
|
1578
|
+
|
|
1579
|
+
This run confirms that the benchmark reaches the Google Sheets API but does not
|
|
1580
|
+
prove Direct API performance or correctness. The external setup still requires
|
|
1581
|
+
the Sheets API to be enabled in the Service Account's Cloud project and the
|
|
1582
|
+
target test Spreadsheet to be shared with that Service Account as an Editor.
|
|
1583
|
+
The 403 result is preserved as an environment/permission gate, not converted to
|
|
1584
|
+
a benchmark success or a production conclusion.
|
|
1585
|
+
|
|
1586
|
+
Artifact: `.local/direct-sheets-api-2026-08-04T12-48-35-851Z-098c074b.json`.
|
|
1587
|
+
|
|
1588
|
+
A retry after the external access check produced the same classified result:
|
|
1589
|
+
Stage 0 returned `permission` / HTTP `403` after about 1.1 seconds, no temporary
|
|
1590
|
+
tab was created, and cleanup remained `ok` with 0 created, 0 deleted, and 0
|
|
1591
|
+
remaining tabs. The retry artifact is
|
|
1592
|
+
`.local/direct-sheets-api-2026-08-04T13-40-14-546Z-0dfd69b2.json`.
|
|
1593
|
+
|
|
1594
|
+
A redacted one-request diagnostic confirmed the API detail as
|
|
1595
|
+
`PERMISSION_DENIED`, reason `forbidden`, message `The caller does not have
|
|
1596
|
+
permission`; this is an access mismatch rather than a timeout, quota, or
|
|
1597
|
+
benchmark failure.
|
|
1598
|
+
|
|
1599
|
+
## 2026-08-04 — Direct Sheets API service-account benchmark (access restored)
|
|
1600
|
+
|
|
1601
|
+
- Branch: `feature/service-account-sheets`
|
|
1602
|
+
- Command: `node --env-file=.env scripts/bench/direct-sheets-api-service-account.mjs`
|
|
1603
|
+
- Backend: Node `@googleapis/sheets` client with `GoogleAuth` and a local
|
|
1604
|
+
service-account JSON. The credential path was changed to the ignored local
|
|
1605
|
+
file under `.local/credentials/`; no credential value or spreadsheet ID is
|
|
1606
|
+
recorded here. Apps Script, `Code.gs`, Advanced Sheets Service, and Drive API
|
|
1607
|
+
were not used.
|
|
1608
|
+
- Dataset: 4,000 requests total across 20 cells: 1/10/100/500 rows per
|
|
1609
|
+
request × concurrency 1/2/4/10/20, 20 requests per cell. Setup and cleanup
|
|
1610
|
+
are reported separately from the steady-state append measurements.
|
|
1611
|
+
|
|
1612
|
+
| Setup/check | Result |
|
|
1613
|
+
| --- | --- |
|
|
1614
|
+
| Stage 0 metadata smoke | passed in 1,033 ms; one existing tab observed |
|
|
1615
|
+
| Temporary tabs/header setup | 21/21 tabs, 21 header appends, 12,450 ms |
|
|
1616
|
+
| Cleanup | passed; 21/21 deleted, 0 generated tabs remaining |
|
|
1617
|
+
| Total run | 123,057 ms; artifact exit code 0 |
|
|
1618
|
+
|
|
1619
|
+
### Stage 1 — raw append
|
|
1620
|
+
|
|
1621
|
+
The table reports `successful requests / requests`, accepted rows, and the
|
|
1622
|
+
cell-local rows/s value. A failed request was classified as `rate_limited`
|
|
1623
|
+
(HTTP `429`); no append response anomaly was recorded.
|
|
1624
|
+
|
|
1625
|
+
| Rows/request | Concurrency | Append success | Rows appended | Rows/s | Error |
|
|
1626
|
+
| ---: | ---: | ---: | ---: | ---: | --- |
|
|
1627
|
+
| 1 | 1 | 20/20 | 20 | 1.9 | — |
|
|
1628
|
+
| 1 | 2 | 20/20 | 20 | 3.7 | — |
|
|
1629
|
+
| 1 | 4 | 10/20 | 10 | 3.3 | 10 × 429 |
|
|
1630
|
+
| 1 | 10 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1631
|
+
| 1 | 20 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1632
|
+
| 10 | 1 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1633
|
+
| 10 | 2 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1634
|
+
| 10 | 4 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1635
|
+
| 10 | 10 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1636
|
+
| 10 | 20 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1637
|
+
| 100 | 1 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1638
|
+
| 100 | 2 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1639
|
+
| 100 | 4 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1640
|
+
| 100 | 10 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1641
|
+
| 100 | 20 | 16/20 | 1,600 | 689.4 | 4 × 429 |
|
|
1642
|
+
| 500 | 1 | 20/20 | 10,000 | 856.6 | — |
|
|
1643
|
+
| 500 | 2 | 20/20 | 10,000 | 1,702.9 | — |
|
|
1644
|
+
| 500 | 4 | 8/20 | 4,000 | 1,284.6 | 12 × 429 |
|
|
1645
|
+
| 500 | 10 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1646
|
+
| 500 | 20 | 0/20 | 0 | 0.0 | 20 × 429 |
|
|
1647
|
+
|
|
1648
|
+
Aggregate Stage 1: `114/400` requests succeeded, `25,650` rows were
|
|
1649
|
+
accepted, and `286` requests were classified as `429`. Across all requests,
|
|
1650
|
+
p50/p95/p99/max latency was `495/986/1,841/2,320 ms`; the measured aggregate
|
|
1651
|
+
steady-state rate was `341.6 rows/s`. This is direct Sheets API quota evidence,
|
|
1652
|
+
not evidence that concurrency 20 is production-capable.
|
|
1653
|
+
|
|
1654
|
+
### Stage 2 — key read and batch comparison
|
|
1655
|
+
|
|
1656
|
+
Stage 2 issued one leading-window `values.get` and one four-range
|
|
1657
|
+
`values.batchGet` per cell. All 20 single-range reads returned HTTP success;
|
|
1658
|
+
seven batch reads returned classified `bad_request` / HTTP `400`. The remaining
|
|
1659
|
+
batch reads compared keys order-independently. Key-read latency was
|
|
1660
|
+
p50/p95/max `521/532/545 ms`; batch-read latency was `524/673/835 ms`.
|
|
1661
|
+
|
|
1662
|
+
| Cell | Key window observed/missing | Batch result |
|
|
1663
|
+
| --- | ---: | --- |
|
|
1664
|
+
| r1_c1 | 20/0 | 20 matched, 0 missing |
|
|
1665
|
+
| r1_c2 | 20/0 | 20 matched, 0 missing |
|
|
1666
|
+
| r1_c4 | 10/10 | 10 matched, 10 missing |
|
|
1667
|
+
| r1_c10 | 0/20 | 0 matched, 20 missing |
|
|
1668
|
+
| r1_c20 | 0/20 | 0 matched, 20 missing |
|
|
1669
|
+
| r10_c1 | 0/100 | 0 matched, 200 missing |
|
|
1670
|
+
| r10_c2 | 0/100 | 0 matched, 200 missing |
|
|
1671
|
+
| r10_c4 | 0/100 | 0 matched, 200 missing |
|
|
1672
|
+
| r10_c10 | 0/100 | 0 matched, 200 missing |
|
|
1673
|
+
| r10_c20 | 0/100 | 0 matched, 200 missing |
|
|
1674
|
+
| r100_c1 | 0/100 | HTTP 400 |
|
|
1675
|
+
| r100_c2 | 0/100 | HTTP 400 |
|
|
1676
|
+
| r100_c4 | 0/100 | HTTP 400 |
|
|
1677
|
+
| r100_c10 | 0/100 | HTTP 400 |
|
|
1678
|
+
| r100_c20 | 100/100 | 1,600 matched, 400 missing |
|
|
1679
|
+
| r500_c1 | 100/0 | 10,000 matched, 0 missing |
|
|
1680
|
+
| r500_c2 | 100/0 | 10,000 matched, 0 missing |
|
|
1681
|
+
| r500_c4 | 100/100 | HTTP 400 |
|
|
1682
|
+
| r500_c10 | 0/100 | HTTP 400 |
|
|
1683
|
+
| r500_c20 | 0/100 | HTTP 400 |
|
|
1684
|
+
|
|
1685
|
+
The missing rows reflect the preceding Stage 1 quota failures and concurrent
|
|
1686
|
+
partial writes; they are not treated as successful row delivery.
|
|
1687
|
+
|
|
1688
|
+
### Stage 3 — batch postcondition
|
|
1689
|
+
|
|
1690
|
+
One `values.get` postcondition read was issued per cell. `4/20` cells passed
|
|
1691
|
+
both row-count and deterministic-key checks. Postcondition latency was
|
|
1692
|
+
p50/p95/max `524/681/697 ms`. The other cells had missing rows consistent with
|
|
1693
|
+
Stage 1's `429` results.
|
|
1694
|
+
|
|
1695
|
+
### Stage 4 — response-loss boundary
|
|
1696
|
+
|
|
1697
|
+
The full sweep's two replay appends were both unsuccessful after quota
|
|
1698
|
+
pressure, so that sweep recorded `unexpected_count` rather than claiming
|
|
1699
|
+
duplicate evidence. A separate five-row minimal probe was then run with the
|
|
1700
|
+
same Direct API client and fresh temporary tab:
|
|
1701
|
+
|
|
1702
|
+
| Check | Result |
|
|
1703
|
+
| --- | --- |
|
|
1704
|
+
| First append; response discarded | succeeded, 403 ms |
|
|
1705
|
+
| Deterministic replay | succeeded, 390 ms |
|
|
1706
|
+
| Readback | 10 rows, 5 unique keys, 5 duplicates |
|
|
1707
|
+
| Verdict | `duplicate_replay` |
|
|
1708
|
+
| Cleanup | passed; 1/1 tab deleted, 0 remaining |
|
|
1709
|
+
|
|
1710
|
+
This confirms that raw `values.append` has no idempotency/receipt protection;
|
|
1711
|
+
replaying after response loss duplicated all five rows. It is evidence for
|
|
1712
|
+
keeping SQLite outbox, receipt, and recovery semantics outside this raw
|
|
1713
|
+
transport, not a production-safe provider result.
|
|
1714
|
+
|
|
1715
|
+
Artifacts:
|
|
1716
|
+
|
|
1717
|
+
- `.local/direct-sheets-api-2026-08-04T13-53-31-116Z-33b98b28.json`
|
|
1718
|
+
- `.local/direct-sheets-api-response-loss-2026-08-04T13-58-53-371Z-2a65266b.json`
|
|
1719
|
+
|
|
1720
|
+
## 2026-08-04 — Direct Sheets API batch-write comparison: UpdateCells vs values.batchUpdate
|
|
1721
|
+
|
|
1722
|
+
- Branch: `feature/service-account-sheets`
|
|
1723
|
+
- Command: `node --env-file=.env scripts/bench/direct-sheets-api-batch-update.mjs`
|
|
1724
|
+
- Backend: Node `v24.3.0`, `@googleapis/sheets` client with `GoogleAuth` and a
|
|
1725
|
+
local service-account JSON. Apps Script, `Code.gs`, Advanced Sheets Service,
|
|
1726
|
+
and Drive API were not used. Credential values and the spreadsheet ID are
|
|
1727
|
+
not recorded.
|
|
1728
|
+
- Dataset: total **10,000 records × 3 string cells** (`bench_key`, `seq`,
|
|
1729
|
+
`payload`) per scenario, split across 1/2/4/10/20 temporary tabs
|
|
1730
|
+
(10,000/5,000/2,500/1,000/500 rows per tab). Each scenario is exactly one
|
|
1731
|
+
write request, always sequential (request concurrency 1; no `Promise.all` or
|
|
1732
|
+
parallel workers). Warm-up 1 (unmeasured) and measured repetitions 3 per
|
|
1733
|
+
scenario.
|
|
1734
|
+
- Two raw write paths on the same spreadsheet:
|
|
1735
|
+
1. `spreadsheets.batchUpdate` + one `UpdateCellsRequest` per tab
|
|
1736
|
+
(`userEnteredValue.stringValue`, `fields: "userEnteredValue"`), grid
|
|
1737
|
+
pre-sized to rows+1 × 3 columns.
|
|
1738
|
+
2. `spreadsheets.values.batchUpdate` + one `ValueRange` per tab
|
|
1739
|
+
(`valueInputOption: "RAW"`), same grid.
|
|
1740
|
+
- Setup (addSheet with pre-sized grid, one batched header write per scenario),
|
|
1741
|
+
write round-trip latency, verification, and cleanup are recorded
|
|
1742
|
+
separately; verification time is never part of write latency. Measured
|
|
1743
|
+
writes are never auto-retried; `429`/timeouts/4xx/5xx would be recorded as
|
|
1744
|
+
failures.
|
|
1745
|
+
- **Every attempt writes its own unique deterministic key set**: the attempt
|
|
1746
|
+
marker (`w0` warm-up, `r0`/`r1`/`r2` measured repetitions) is folded into
|
|
1747
|
+
every key, so each attempt writes DIFFERENT keys into the same fixed
|
|
1748
|
+
ranges. Stale data from an earlier attempt can never pass a later
|
|
1749
|
+
attempt's verification (leftover keys surface as `missing` + `extra`); a
|
|
1750
|
+
no-op or partial write cannot be silently masked by prior data.
|
|
1751
|
+
- **Every measured repetition is verified individually, always**: after each
|
|
1752
|
+
of the 30 measured writes — including after timeout/4xx/5xx/response-format
|
|
1753
|
+
failures, because a lost-response write may still have applied — a separate
|
|
1754
|
+
`values.batchGet` re-reads every tab and compares exact per-tab row counts
|
|
1755
|
+
plus the deterministic key set (missing/duplicate/unexpected keys) against
|
|
1756
|
+
THAT attempt's expected rows. Write-response outcome and verification
|
|
1757
|
+
outcome are stored independently per repetition (`responseOk`, `verified`,
|
|
1758
|
+
`outcome`); a repetition is a successful benchmark write only when BOTH
|
|
1759
|
+
pass. A failed response whose data was nevertheless verified is preserved
|
|
1760
|
+
as `write_response_failed_but_data_verified` evidence and never counted as
|
|
1761
|
+
a success. Verification latency is recorded per repetition and never
|
|
1762
|
+
enters write latency.
|
|
1763
|
+
- **Scenarios are isolated and the matrix stops on contamination**: each
|
|
1764
|
+
scenario's temporary tabs are deleted right after that scenario (before
|
|
1765
|
+
the next one starts). If a per-scenario cleanup fails, the matrix is
|
|
1766
|
+
aborted with an explicit `matrixAborted` reason — no later scenario ever
|
|
1767
|
+
runs on possibly contaminated state — and the `finally` recovery cleanup
|
|
1768
|
+
retries the leftovers. The recovery cleanup is idempotent: it resolves
|
|
1769
|
+
remaining tabs from a metadata read (single source of truth); a generated
|
|
1770
|
+
title the metadata does NOT list is already gone (e.g. a delete whose
|
|
1771
|
+
response was lost after applying) and is forgotten instead of being
|
|
1772
|
+
re-deleted, so a clean zero-remaining state never becomes a false cleanup
|
|
1773
|
+
failure. Map ids are used as a fallback only when metadata is unavailable.
|
|
1774
|
+
- **Scenario order is a deterministic seeded shuffle** (seed
|
|
1775
|
+
`DIRECT_BATCH_SEED`, default `20260804`; mulberry32 + Fisher–Yates) of all
|
|
1776
|
+
(tabCount, api) pairs — no fixed-order bias (updateCells always first, tab
|
|
1777
|
+
counts always ascending), no uncontrolled randomness. The seed and the
|
|
1778
|
+
exact order are recorded in the artifact. Request concurrency stays 1.
|
|
1779
|
+
- **Signals**: SIGINT/SIGTERM request an orderly stop — the current request
|
|
1780
|
+
settles, cleanup runs, the artifact is written, and the process exits
|
|
1781
|
+
nonzero; cleanup is never skipped to exit faster.
|
|
1782
|
+
- **Configuration safety**: numeric env values (`DIRECT_BATCH_TOTAL_ROWS`,
|
|
1783
|
+
`DIRECT_BATCH_WARMUP`, `DIRECT_BATCH_REPETITIONS`, each
|
|
1784
|
+
`DIRECT_BATCH_TAB_COUNTS` entry, `DIRECT_BATCH_SEED`) must be safe
|
|
1785
|
+
integers; values above `Number.MAX_SAFE_INTEGER` are rejected with an
|
|
1786
|
+
`unsafe_integer` classification before any tab is created. An unexpected
|
|
1787
|
+
fatal error preserves the whole recorded artifact (stages, completed
|
|
1788
|
+
scenarios, cleanup) and appends a redacted fatal classification plus a
|
|
1789
|
+
nonzero overall verdict instead of replacing it.
|
|
1790
|
+
- Exit code 0 only for a complete matrix: every measured write response-ok
|
|
1791
|
+
AND post-write verified, clean setup, per-scenario cleanups and the final
|
|
1792
|
+
recovery cleanup all complete, no interrupt. Any partial outcome (failed or
|
|
1793
|
+
unverified write, setup/verification/cleanup problem, matrix abort, signal
|
|
1794
|
+
interrupt) exits nonzero with a classified reason.
|
|
1795
|
+
|
|
1796
|
+
### Result
|
|
1797
|
+
|
|
1798
|
+
Rerun with the corrected semantics (per-attempt unique key sets, always-run
|
|
1799
|
+
verification, seeded order). All 30 measured writes (10 scenarios × 3
|
|
1800
|
+
repetitions) returned HTTP 200 with matching response signals, and **every
|
|
1801
|
+
repetition's own post-write verification passed**: per-tab row counts matched
|
|
1802
|
+
exactly and each attempt's key set was complete with zero
|
|
1803
|
+
missing/duplicate/unexpected keys (all repetitions `outcome: success`;
|
|
1804
|
+
`write_response_failed_but_data_verified` never occurred). Per-repetition
|
|
1805
|
+
verification reads took ~0.5–1.1 s each. Each scenario's tabs were deleted
|
|
1806
|
+
before the next scenario (per-scenario cleanup 0.8–1.8 s each); the final
|
|
1807
|
+
recovery cleanup found 0 remaining generated tabs. The run exited 0
|
|
1808
|
+
(complete matrix: 30/30 measured writes verified). Stage 0 metadata/auth
|
|
1809
|
+
smoke took 1,154 ms; the whole run took 125,731 ms.
|
|
1810
|
+
|
|
1811
|
+
Actual scenario order (seed 20260804): `valuesBatchUpdate@20` →
|
|
1812
|
+
`updateCells@20` → `updateCells@4` → `valuesBatchUpdate@4` →
|
|
1813
|
+
`valuesBatchUpdate@1` → `valuesBatchUpdate@10` → `updateCells@10` →
|
|
1814
|
+
`updateCells@1` → `updateCells@2` → `valuesBatchUpdate@2`.
|
|
1815
|
+
|
|
1816
|
+
| API | Tabs | Rows/tab | Payload bytes | Rep latencies (ms) | p50 / p95 / max (ms) | Rows/s | Cells/s |
|
|
1817
|
+
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
|
1818
|
+
| `values.batchUpdate` | 20 | 500 | 846,765 | 2,090 / 2,220 / 2,272 | 2,220 / 2,272 / 2,272 | 4,558 | 13,673 |
|
|
1819
|
+
| `updateCells` | 20 | 500 | 2,067,308 | 2,816 / 3,419 / 3,361 | 3,361 / 3,419 / 3,419 | 3,126 | 9,379 |
|
|
1820
|
+
| `updateCells` | 4 | 2,500 | 2,060,473 | 1,968 / 2,491 / 3,241 | 2,491 / 3,241 / 3,241 | 3,896 | 11,689 |
|
|
1821
|
+
| `values.batchUpdate` | 4 | 2,500 | 840,379 | 1,640 / 2,301 / 1,785 | 1,785 / 2,301 / 2,301 | 5,238 | 15,715 |
|
|
1822
|
+
| `values.batchUpdate` | 1 | 10,000 | 840,122 | 2,783 / 1,507 / 2,527 | 2,527 / 2,783 / 2,783 | 4,401 | 13,204 |
|
|
1823
|
+
| `values.batchUpdate` | 10 | 1,000 | 840,905 | 1,312 / 1,538 / 1,317 | 1,317 / 1,538 / 1,538 | 7,200 | 21,601 |
|
|
1824
|
+
| `updateCells` | 10 | 1,000 | 2,061,157 | 2,071 / 2,248 / 1,902 | 2,071 / 2,248 / 2,248 | 4,822 | 14,467 |
|
|
1825
|
+
| `updateCells` | 1 | 10,000 | 2,060,128 | 1,899 / 2,141 / 1,850 | 1,899 / 2,141 / 2,141 | 5,093 | 15,280 |
|
|
1826
|
+
| `updateCells` | 2 | 5,000 | 2,060,243 | 1,665 / 1,602 / 1,699 | 1,665 / 1,699 / 1,699 | 6,041 | 18,124 |
|
|
1827
|
+
| `values.batchUpdate` | 2 | 5,000 | 840,207 | 1,454 / 1,545 / 1,761 | 1,545 / 1,761 / 1,761 | 6,303 | 18,908 |
|
|
1828
|
+
|
|
1829
|
+
Per-scenario setup (tabs + headers) took 824–1,610 ms; per-repetition
|
|
1830
|
+
verification reads took ~0.5–1.1 s each and all 30 passed (per-scenario
|
|
1831
|
+
verification totals: 1.7–2.4 s for its 3 repetitions). Per-scenario cleanup
|
|
1832
|
+
(delete + remaining-tab check) took 0.8–1.8 s each. Warm-up latencies
|
|
1833
|
+
followed the same pattern as the measured repetitions. Rows/s is
|
|
1834
|
+
`(successful repetitions × 10,000) / sum of successful repetition durations`
|
|
1835
|
+
— total proven rows over the summed round-trip time of those repetitions;
|
|
1836
|
+
cells/s is rows/s × 3.
|
|
1837
|
+
|
|
1838
|
+
### Reading the result
|
|
1839
|
+
|
|
1840
|
+
- **`values.batchUpdate` is the faster and smaller path again**: its payload
|
|
1841
|
+
is about 840 KB versus 2.06 MB for `updateCells` (per-cell JSON envelope
|
|
1842
|
+
cost), and it was faster in 7 of 10 scenario cells (1.31–2.78 s vs
|
|
1843
|
+
1.60–3.42 s round-trip; 4,401–7,200 rows/s vs 3,126–6,041 rows/s).
|
|
1844
|
+
- **Tab-count effects remain modest and noisy**: this run's fastest cell was
|
|
1845
|
+
`values.batchUpdate` with 10 tabs (7,200 rows/s) and its slowest was
|
|
1846
|
+
`updateCells` with 20 tabs (3,126 rows/s), while the single-tab cells sat
|
|
1847
|
+
mid-pack — a different relative pattern from the previous fixed-order run
|
|
1848
|
+
(where single-tab was slowest for both APIs). The comparison is dominated
|
|
1849
|
+
by network/backend variance between scenario cells, not by a hard tab
|
|
1850
|
+
count rule; three repetitions per cell cannot prove one.
|
|
1851
|
+
- This is a raw-transport comparison on one spreadsheet, one run, three
|
|
1852
|
+
repetitions per cell, each repetition individually verified against its
|
|
1853
|
+
own unique key set. It measures the Google Sheets REST path only and says
|
|
1854
|
+
nothing about the Hikoutei worker/coordinator drain rate, outbox, receipts,
|
|
1855
|
+
CAS, or Apps Script gateway behavior. The 10,000-row request is the
|
|
1856
|
+
largest tested here; larger sizes were not attempted.
|
|
1857
|
+
|
|
1858
|
+
### Quota observation
|
|
1859
|
+
|
|
1860
|
+
A first run of this benchmark (before the setup batching below) hit HTTP `429`
|
|
1861
|
+
on 4 of 8 cleanup `deleteSheet` chunks after roughly 120 requests, stranding
|
|
1862
|
+
34 tabs; the stranded tabs were deleted by a paced follow-up. The fixed rerun
|
|
1863
|
+
reduced setup writes from ~2 per tab to O(1) per scenario (grid pre-sized in
|
|
1864
|
+
`addSheet`, headers written with one `values.batchUpdate`). The corrected run
|
|
1865
|
+
above added per-repetition verification reads (30 `batchGet` calls) and
|
|
1866
|
+
per-scenario cleanup (10 delete rounds plus remaining-tab checks) and still
|
|
1867
|
+
completed with zero `429`s, zero verification failures, and zero stranded
|
|
1868
|
+
tabs. Per-scenario cleanup also bounds the damage of an interrupt: at most the
|
|
1869
|
+
in-progress scenario's tabs can remain, and the signal handler runs the
|
|
1870
|
+
recovery cleanup before exiting nonzero. One intermediate rerun (16:54, see
|
|
1871
|
+
artifacts) hit the always-run verification gate with a verification
|
|
1872
|
+
normalization bug (raw `ValueRange` objects compared instead of their
|
|
1873
|
+
`values` arrays) and correctly exited 1 with `0 of 30 measured writes
|
|
1874
|
+
verified` rather than reporting a false success. This is observed quota
|
|
1875
|
+
pressure evidence, not a remaining-quota counter; Sheets REST write quota is
|
|
1876
|
+
per-minute per project and must be checked in the Cloud console.
|
|
1877
|
+
|
|
1878
|
+
### How to run
|
|
1879
|
+
|
|
1880
|
+
```sh
|
|
1881
|
+
node --env-file=.env scripts/bench/direct-sheets-api-batch-update.mjs
|
|
1882
|
+
```
|
|
1883
|
+
|
|
1884
|
+
Required environment: `GOOGLE_APPLICATION_CREDENTIALS` (service-account JSON
|
|
1885
|
+
readable locally) and `GOOGLE_SHEETS_TEST_SPREADSHEET_ID` (the service account
|
|
1886
|
+
must be shared on that spreadsheet as an Editor). Optional knobs:
|
|
1887
|
+
|
|
1888
|
+
- `DIRECT_BATCH_TAB_COUNTS=1,2,4,10,20` — tab-count matrix (each count must
|
|
1889
|
+
divide the total rows evenly)
|
|
1890
|
+
- `DIRECT_BATCH_TOTAL_ROWS=10000` — records per scenario
|
|
1891
|
+
- `DIRECT_BATCH_WARMUP=1` — unmeasured warm-up requests per scenario
|
|
1892
|
+
- `DIRECT_BATCH_REPETITIONS=3` — measured repetitions per scenario
|
|
1893
|
+
- `DIRECT_BATCH_SEED=20260804` — deterministic scenario-order shuffle seed
|
|
1894
|
+
(unsigned 32-bit integer; the seed and actual order are recorded in the
|
|
1895
|
+
artifact)
|
|
1896
|
+
|
|
1897
|
+
Invalid env values (non-integers, values above `Number.MAX_SAFE_INTEGER`,
|
|
1898
|
+
non-positive counts, uneven tab splits, out-of-range seeds) are classified
|
|
1899
|
+
and abort before any tab is created. If authentication or sharing is blocked,
|
|
1900
|
+
Stage 0 fails with a classified `auth`/`permission` result and cleanup stays
|
|
1901
|
+
trivially clean; the run is never reported as a benchmark success in that
|
|
1902
|
+
case. The exit code is 0 only when the complete matrix ran: every measured
|
|
1903
|
+
write response-ok AND post-write verified, setup clean, per-scenario cleanups
|
|
1904
|
+
and final recovery cleanup complete, no signal interrupt; anything less exits
|
|
1905
|
+
1 with a classified reason in the artifact.
|
|
1906
|
+
|
|
1907
|
+
Artifacts (raw JSON, in the ignored `.local/` directory):
|
|
1908
|
+
|
|
1909
|
+
- `.local/direct-sheets-api-batch-update-2026-08-04T16-57-19-098Z-65c1e7a5.json` (clean run above: per-attempt unique keys, always-run verification, seeded order)
|
|
1910
|
+
- `.local/direct-sheets-api-batch-update-2026-08-04T16-54-50-919Z-0c3ffca3.json` (superseded: verification normalization bug — every write correctly failed the always-run verification gate, exit 1, no false success)
|
|
1911
|
+
- `.local/direct-sheets-api-batch-update-2026-08-04T16-21-51-910Z-7013fc02.json` (superseded: pre-fix semantics — fixed order, shared key set across repetitions, verification only after response-ok writes)
|
|
1912
|
+
- `.local/direct-sheets-api-batch-update-2026-08-04T15-59-24-945Z-b7134a7a.json` (superseded: pre-fix semantics — single aggregate verification, rows/s under-reported 3×)
|
|
1913
|
+
- `.local/direct-sheets-api-batch-update-2026-08-04T15-49-31-777Z-ba3d0297.json` (first run: pre-fix `values.batchUpdate` range bug + cleanup 429 evidence)
|
|
1914
|
+
|
|
1915
|
+
## 2026-08-05 — Integrated Apps Script `appendTestBatch` load
|
|
1916
|
+
|
|
1917
|
+
- Branch: `feature/service-account-sheets`
|
|
1918
|
+
- Command: `node --env-file=.env --env-file=.local/gateway-test-override.env .local/run-append-load.mjs`
|
|
1919
|
+
- Backend: deployed Apps Script Gateway with the Advanced Sheets v4 service;
|
|
1920
|
+
credentials and spreadsheet identifiers are intentionally not recorded.
|
|
1921
|
+
- Dataset: **10,000 entity inserts** into one temporary `System_State` tab,
|
|
1922
|
+
one SQLite outbox/runtime, sequential worker dispatch, 1,000 append rows per
|
|
1923
|
+
request, and a 1,100 ms minimum interval between append request starts.
|
|
1924
|
+
Updates/deletes were not included.
|
|
1925
|
+
- Setup, SQLite seed/flush, worker upload, verification, and cleanup were
|
|
1926
|
+
measured separately. The worker made 10 successful append requests plus
|
|
1927
|
+
provisioning, verification, and cleanup requests; no gateway request failed.
|
|
1928
|
+
|
|
1929
|
+
| Phase | Duration |
|
|
1930
|
+
| --- | ---: |
|
|
1931
|
+
| Runtime setup/provisioning | 4.68 s |
|
|
1932
|
+
| SQLite seed + outbox flush | 4.52 s |
|
|
1933
|
+
| Worker append drain | 798.10 s (13m 18.10s) |
|
|
1934
|
+
| Remote verification | 3.56 s |
|
|
1935
|
+
| Remote cleanup | 2.66 s |
|
|
1936
|
+
|
|
1937
|
+
Append request durations were 51.43–119.89 s (p50 75.90 s, p95/max
|
|
1938
|
+
119.89 s). All 10,000 rows were applied and remotely verified; cleanup left no
|
|
1939
|
+
load tabs. The measured integrated drain rate was approximately **12.53
|
|
1940
|
+
rows/s**, despite the 1,000-row API batches. This is materially slower than the
|
|
1941
|
+
raw service-account `values.batchUpdate` result above because the integrated
|
|
1942
|
+
path also pays Apps Script execution, receipt handling, identity/postcondition
|
|
1943
|
+
scans, gateway transport, and worker lease overhead. This run confirms
|
|
1944
|
+
correctness and batching, but does **not** show that the end-to-end upload
|
|
1945
|
+
bottleneck has been eliminated.
|
|
1946
|
+
|
|
1947
|
+
Artifact:
|
|
1948
|
+
|
|
1949
|
+
- `.local/append-test-load-msfndo05-ecd2cf98.json`
|
|
1950
|
+
|
|
1951
|
+
Caveat: this is one sequential run on one spreadsheet; Apps Script cold starts,
|
|
1952
|
+
quota pressure, network latency, and the current receipt/postcondition work can
|
|
1953
|
+
vary substantially. The authority fence was reset on the dedicated test
|
|
1954
|
+
spreadsheet before the run; no production spreadsheet should be reset this
|
|
1955
|
+
way.
|
|
1956
|
+
|
|
1957
|
+
## 2026-08-05 — Direct Google Sheets API outbound worker load
|
|
1958
|
+
|
|
1959
|
+
- Branch: `feature/service-account-sheets`
|
|
1960
|
+
- Command: `node --env-file=.env .local/run-append-load-direct.mjs`
|
|
1961
|
+
- Backend: direct Google Sheets REST API outbound worker (service account via
|
|
1962
|
+
Application Default Credentials, `GOOGLE_APPLICATION_CREDENTIALS`) against
|
|
1963
|
+
the shared test spreadsheet; SQLite outbox/worker state machine unchanged;
|
|
1964
|
+
Apps Script gateway not involved in the write path (provisioning of the
|
|
1965
|
+
temporary tab was done by the service account itself). Credentials and
|
|
1966
|
+
spreadsheet identifiers are intentionally not recorded.
|
|
1967
|
+
- Dataset: **10,000 entity inserts** into one temporary `System_State` tab
|
|
1968
|
+
(`id`, `status`, `__typed_sheets_deleted`), one SQLite outbox/runtime,
|
|
1969
|
+
sequential worker dispatch, 1,000 append rows per `batchUpdate`, the worker
|
|
1970
|
+
append throttle (1,100 ms between append request starts) and the provider's
|
|
1971
|
+
read/write request-start limiters (1,100 ms per class) all active.
|
|
1972
|
+
Updates/deletes were not included.
|
|
1973
|
+
- Setup, SQLite seed/flush, worker upload, verification, and cleanup were
|
|
1974
|
+
measured separately. The worker made 10 successful append batches plus
|
|
1975
|
+
per-batch preflight reads, verification, and cleanup; no provider request
|
|
1976
|
+
failed (20/20 requests ok).
|
|
1977
|
+
|
|
1978
|
+
| Phase | Duration |
|
|
1979
|
+
| --- | ---: |
|
|
1980
|
+
| Runtime setup/provisioning | 3.08 s |
|
|
1981
|
+
| SQLite seed + outbox flush | 4.44 s |
|
|
1982
|
+
| Worker append drain | 39.47 s |
|
|
1983
|
+
| Remote verification | 0.50 s |
|
|
1984
|
+
| Remote cleanup | 1.06 s |
|
|
1985
|
+
|
|
1986
|
+
Append `batchUpdate` durations were 0.99–1.59 s (p50 1.45 s, max 1.59 s);
|
|
1987
|
+
per-batch preflight reads (sheet enumeration + grid data, two calls per batch
|
|
1988
|
+
spaced by the 1,100 ms read limiter) were 1.21–2.03 s. All 10,000 rows were
|
|
1989
|
+
applied (10 batches × 1,000), zero failures/deferred/requeues, and the read-back
|
|
1990
|
+
verification confirmed 10,000 rows with the expected first/last keys; cleanup
|
|
1991
|
+
left no load tabs and removed the receipt tab.
|
|
1992
|
+
|
|
1993
|
+
### Comparison with the previous integrated run (2026-08-05, same spreadsheet
|
|
1994
|
+
class, same 10,000 rows, same 1,000-row batch and 1,100 ms interval):
|
|
1995
|
+
|
|
1996
|
+
| Metric | Apps Script gateway | Direct Sheets API | Delta |
|
|
1997
|
+
| --- | ---: | ---: | ---: |
|
|
1998
|
+
| Worker append drain | 798.10 s | 39.47 s | **20.2× faster** |
|
|
1999
|
+
| Integrated throughput | 12.53 rows/s | 253.4 rows/s | +20.2× |
|
|
2000
|
+
| Per-batch latency p50 | 75.90 s | 1.45 s | 52× lower |
|
|
2001
|
+
| Per-batch latency max | 119.89 s | 1.59 s | 75× lower |
|
|
2002
|
+
| Failed/uncertain effects | 0 | 0 | same |
|
|
2003
|
+
|
|
2004
|
+
Steady-state (drain-only) result: **10,000 rows in 39.47 s ≈ 253 rows/s**;
|
|
2005
|
+
excluding the 1,100 ms request-start pacing of the worker throttle and the
|
|
2006
|
+
provider read/write limiters, the raw `batchUpdate` time alone was ~13 s for
|
|
2007
|
+
all 10 batches (1.3 s/batch). The drain time is dominated by the deliberate
|
|
2008
|
+
quota pacing, not by Sheets latency.
|
|
2009
|
+
|
|
2010
|
+
Artifact:
|
|
2011
|
+
|
|
2012
|
+
- `.local/append-test-load-direct-msfuq2yb-3a862d7a.json`
|
|
2013
|
+
|
|
2014
|
+
Caveats: one sequential run on one spreadsheet; a provider bug found during
|
|
2015
|
+
this live test (receipt-tab discovery: `spreadsheets.get` with `ranges`
|
|
2016
|
+
returns only intersecting sheets, so the second batch could not see the
|
|
2017
|
+
receipt tab created by the first and attempted to recreate it, failing the
|
|
2018
|
+
batch with 400 INVALID_ARGUMENT) was fixed in the provider before this run
|
|
2019
|
+
(2-call preflight: sheet enumeration without ranges, then target+receipt data
|
|
2020
|
+
ranges) and is covered by regression tests. Results are not a claim about
|
|
2021
|
+
quota headroom at higher concurrency, update/delete throughput, or
|
|
2022
|
+
multi-writer behavior; the direct provider additionally paces reads at
|
|
2023
|
+
1,100 ms, so observation-heavy workloads were not measured here.
|
|
2024
|
+
|
|
2025
|
+
## 2026-08-05 — Direct outbound update/delete correctness gate (passed)
|
|
2026
|
+
|
|
2027
|
+
- Branch: `feature/service-account-sheets`
|
|
2028
|
+
- Command: `node --env-file=.env .local/run-update-delete-direct.mjs`
|
|
2029
|
+
- Backend: direct Google Sheets API outbound worker (service account via ADC)
|
|
2030
|
+
on the shared test spreadsheet; two projections per entity (`system_state`
|
|
2031
|
+
tab A:C and `user_input` tab A:B), one SQLite outbox/runtime, no Apps
|
|
2032
|
+
Script involvement. Credentials and spreadsheet identifiers are not
|
|
2033
|
+
recorded.
|
|
2034
|
+
- Dataset: 100 entities (id/status), seeded through the mapped ORM, then 50
|
|
2035
|
+
bulk updates, two simulated human-edit CAS scenarios, and 25 entity
|
|
2036
|
+
deletions, each step drained by the real effect worker through the direct
|
|
2037
|
+
provider and verified by service-account read-back.
|
|
2038
|
+
|
|
2039
|
+
| Step | Result |
|
|
2040
|
+
| --- | --- |
|
|
2041
|
+
| Seed + append (100 system + 100 input rows) | 200 effects applied; both tabs 100 rows |
|
|
2042
|
+
| Bulk update 50 → "paid" | 100 effects applied; both tabs exactly 50 "paid" |
|
|
2043
|
+
| Human edit on user_input tab + local update | input mirror effect parked as `blocked_candidate`/`candidate_guard_mismatch`; sheet keeps human value; system tab applied "paid-v2" |
|
|
2044
|
+
| Human edit on system tab + local update | system effect recorded as durable `conflict`/`visible_guard_mismatch`; sheet keeps "human-sys-edit"; input mirror applied |
|
|
2045
|
+
| Delete 25 entities | 25 system rows flagged `__typed_sheets_deleted=true`, 25 user_input rows physically removed; 75 rows remain; human-edited rows preserved |
|
|
2046
|
+
| Cleanup | passed; load tabs + receipt tab removed |
|
|
2047
|
+
|
|
2048
|
+
This gate confirms the direct provider's guarded update (visible-hash CAS
|
|
2049
|
+
with the same conflict semantics as the gateway path: `blocked_candidate` for
|
|
2050
|
+
candidate-protected user_input effects, `conflict` for system projection
|
|
2051
|
+
effects), physical delete with full-row guard, receipt-backed evidence, and
|
|
2052
|
+
per-step worker/outbox bookkeeping against the real Sheets API. It is a
|
|
2053
|
+
correctness gate, not a throughput measurement; delete/update volume here is
|
|
2054
|
+
small (≤100 effects per step) and paced by the same 1,100 ms request-start
|
|
2055
|
+
limiters.
|
|
2056
|
+
|
|
2057
|
+
Artifact:
|
|
2058
|
+
|
|
2059
|
+
- `.local/update-delete-direct-msfv3rd0-72dc5b6e.json`
|
|
2060
|
+
|
|
2061
|
+
Caveats: single run on one spreadsheet; the guard scenarios mutate rows
|
|
2062
|
+
outside the worker and rely on the worker's existing conflict semantics, so
|
|
2063
|
+
their expected statuses are `blocked_candidate`/`conflict`, not failures.
|
|
2064
|
+
|
|
2065
|
+
## 2026-08-05 — Direct full-provider live correctness gate (passed)
|
|
2066
|
+
|
|
2067
|
+
- Branch: `feature/service-account-sheets`
|
|
2068
|
+
- Command: `node --env-file=.env scripts/ci/run-api-scenario.mjs --backend=live --outbound=direct`
|
|
2069
|
+
- Backend: the full `GoogleSheetsApiSyncProvider` (service account via ADC)
|
|
2070
|
+
on the shared test spreadsheet, provisioning from an EMPTY spreadsheet state
|
|
2071
|
+
(no tabs) through the tracked scenario. No Apps Script gateway, no
|
|
2072
|
+
`TYPED_SHEETS_GATEWAY_*` secrets. Credentials and spreadsheet identifiers
|
|
2073
|
+
are never recorded; the report keeps only `sheetMatched: true`.
|
|
2074
|
+
|
|
2075
|
+
| Step | Result |
|
|
2076
|
+
| --- | --- |
|
|
2077
|
+
| Provisioning from empty spreadsheet | 3 tabs created + headers initialized (one atomic batch), `createdSheets`/`initializedHeaders` asserted |
|
|
2078
|
+
| ORM create → worker append | system fast append + user_input create; receipt tab evidence (2 receipt rows, no duplicates) |
|
|
2079
|
+
| Guarded update + read-back | ORM update → drain → sheet value verified |
|
|
2080
|
+
| Mapped polling of SA-simulated human edit | full observation → SQLite entity reflects `edited-by-user` (appliedRows 1) |
|
|
2081
|
+
| Stale input edit | input mirror effect parked `blocked_candidate`/`candidate_guard_mismatch`; sheet keeps `human-2` |
|
|
2082
|
+
| Stale system edit | system effect recorded as durable `conflict`/`visible_guard_mismatch`; sheet keeps `human-sys` |
|
|
2083
|
+
| Delete | system row tombstoned (`__typed_sheets_deleted=true`), user_input row physically removed; 3 system rows / 2 input rows remain |
|
|
2084
|
+
| Anchor evidence | user_input rows anchored (polling observation pass), system rows identity-located, no duplicate materialization (unique ids) |
|
|
2085
|
+
| Cleanup | passed; fixture tabs + receipt tab removed |
|
|
2086
|
+
|
|
2087
|
+
Totals: 19 steps, 35 assertions, all passed. Setup 1.61 s; steady-state
|
|
2088
|
+
drain/observation/verification 39.41 s; total 42.06 s (paced by the same
|
|
2089
|
+
1,100 ms per-request-class limiters). Artifact:
|
|
2090
|
+
|
|
2091
|
+
- `.local/live-direct-parity-2026-08-05T20-33-29.json`
|
|
2092
|
+
|
|
2093
|
+
This gate verifies the full-provider parity checklist (R9 of the promotion
|
|
2094
|
+
plan) against the real Sheets API: provisioning from empty state, append /
|
|
2095
|
+
update / delete with receipts, mapped User_Input polling into SQLite, both
|
|
2096
|
+
CAS guard paths, anchor evidence, and cleanup — with zero Apps Script
|
|
2097
|
+
involvement. It is a correctness gate, not a throughput measurement.
|
|
2098
|
+
|
|
2099
|
+
Caveats: single sequential run on one spreadsheet; the tracked workflow
|
|
2100
|
+
(`.github/workflows/live-integration.yml`) runs the same scenario
|
|
2101
|
+
service-account-only via `GOOGLE_SERVICE_ACCOUNT_CREDENTIALS_JSON` + `GOOGLE_SHEETS_TEST_SPREADSHEET_ID`.
|
|
2102
|
+
|
|
2103
|
+
## Direct full-provider parity (tracked live scenario)
|
|
2104
|
+
|
|
2105
|
+
No new throughput measurement was run for the full-provider promotion; this
|
|
2106
|
+
document records only evidence that was actually measured. The full direct
|
|
2107
|
+
provider (`googleSheetsApi`) is exercised live by the tracked scenario
|
|
2108
|
+
(`scripts/ci/run-api-scenario.mjs --backend live --outbound direct`), which is
|
|
2109
|
+
the correctness gate for provisioning from an empty spreadsheet, append /
|
|
2110
|
+
update / delete delivery, receipt evidence, mapped User_Input polling,
|
|
2111
|
+
stale-edit CAS guards (`blocked_candidate` / `visible_guard_mismatch`), anchor
|
|
2112
|
+
evidence, and cleanup — all through the service account with no Apps Script.
|
|
2113
|
+
The unguarded raw-transport throughput numbers above do not include receipts
|
|
2114
|
+
or compare-and-set, so they are not provider throughput claims. Live artifacts
|
|
2115
|
+
from the update/delete correctness gate live under `.local/`
|
|
2116
|
+
(`.local/update-delete-direct-*.json`), and the workflow report is uploaded as
|
|
2117
|
+
the `hikoutei-live-google-sheets-direct` artifact.
|