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.
Files changed (355) hide show
  1. package/README.ja.md +44 -21
  2. package/README.ko.md +43 -23
  3. package/README.md +49 -33
  4. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts +3 -3
  5. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts.map +1 -1
  6. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.js +1 -1
  7. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarEntityRuntime.d.ts +1 -1
  8. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarEntityRuntime.js +1 -1
  9. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarRuntime.js +3 -3
  10. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmScalarRuntime.js.map +1 -1
  11. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts +3 -3
  12. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts.map +1 -1
  13. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js +15 -15
  14. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js.map +1 -1
  15. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts +1 -1
  16. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts.map +1 -1
  17. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js +3 -3
  18. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js.map +1 -1
  19. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.d.ts +5 -5
  20. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.d.ts.map +1 -1
  21. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js +5 -5
  22. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js.map +1 -1
  23. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.d.ts +1 -1
  24. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js +5 -5
  25. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js.map +1 -1
  26. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingSql.js +3 -3
  27. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingSql.js.map +1 -1
  28. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts +156 -0
  29. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts.map +1 -0
  30. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js +1112 -0
  31. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js.map +1 -0
  32. package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts +87 -0
  33. package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts.map +1 -0
  34. package/dist/adapter/sheets/providers/google-sheets-api/constants.js +97 -0
  35. package/dist/adapter/sheets/providers/google-sheets-api/constants.js.map +1 -0
  36. package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts +53 -0
  37. package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts.map +1 -0
  38. package/dist/adapter/sheets/providers/google-sheets-api/errors.js +61 -0
  39. package/dist/adapter/sheets/providers/google-sheets-api/errors.js.map +1 -0
  40. package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts +16 -0
  41. package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts.map +1 -0
  42. package/dist/adapter/sheets/providers/google-sheets-api/index.js +13 -0
  43. package/dist/adapter/sheets/providers/google-sheets-api/index.js.map +1 -0
  44. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +83 -0
  45. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -0
  46. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js +413 -0
  47. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -0
  48. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts +86 -0
  49. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts.map +1 -0
  50. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js +439 -0
  51. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js.map +1 -0
  52. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts +115 -0
  53. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -0
  54. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js +522 -0
  55. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js.map +1 -0
  56. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts +17 -0
  57. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts.map +1 -0
  58. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js +99 -0
  59. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js.map +1 -0
  60. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts +242 -0
  61. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts.map +1 -0
  62. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js +707 -0
  63. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js.map +1 -0
  64. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts +16 -0
  65. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts.map +1 -0
  66. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js +29 -0
  67. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js.map +1 -0
  68. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts +26 -0
  69. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts.map +1 -0
  70. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js +57 -0
  71. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js.map +1 -0
  72. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts +102 -0
  73. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts.map +1 -0
  74. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js +375 -0
  75. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js.map +1 -0
  76. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts +168 -0
  77. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts.map +1 -0
  78. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js +247 -0
  79. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js.map +1 -0
  80. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts +47 -0
  81. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts.map +1 -0
  82. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js +60 -0
  83. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js.map +1 -0
  84. package/dist/api/Hikoutei.d.ts +1 -1
  85. package/dist/api/Hikoutei.js +1 -1
  86. package/dist/api/index.d.ts +2 -2
  87. package/dist/api/index.js +2 -2
  88. package/dist/application/orm/mapping/contracts.d.ts +2 -2
  89. package/dist/application/orm/mapping/contracts.d.ts.map +1 -1
  90. package/dist/application/orm/mapping/definition.js +5 -5
  91. package/dist/application/orm/mapping/definition.js.map +1 -1
  92. package/dist/application/orm/mapping/projection.js +7 -7
  93. package/dist/application/orm/mapping/projection.js.map +1 -1
  94. package/dist/application/orm/persistence/flush/flushCoordinator.d.ts +3 -3
  95. package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -1
  96. package/dist/application/orm/persistence/flush/flushCoordinator.js +2 -2
  97. package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -1
  98. package/dist/application/orm/persistence/projection/projectionEffects.d.ts +1 -1
  99. package/dist/application/orm/persistence/projection/projectionEffects.js +6 -6
  100. package/dist/application/orm/persistence/projection/projectionEffects.js.map +1 -1
  101. package/dist/application/orm/persistence/support/contracts.d.ts +2 -2
  102. package/dist/application/orm/persistence/support/contracts.d.ts.map +1 -1
  103. package/dist/application/sync/inbound/autoSystemConflictResolution.js +7 -7
  104. package/dist/application/sync/inbound/autoSystemConflictResolution.js.map +1 -1
  105. package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts +3 -3
  106. package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts.map +1 -1
  107. package/dist/application/sync/inbound/polling/SimpleSheetPolling.js +1 -1
  108. package/dist/application/sync/inbound/polling/SimpleSheetPolling.js.map +1 -1
  109. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +17 -1
  110. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -1
  111. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +27 -1
  112. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -1
  113. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts +2 -2
  114. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
  115. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +26 -6
  116. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
  117. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +24 -9
  118. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
  119. package/dist/application/sync/outbound/effects/SyncEffectWorker.js +128 -81
  120. package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
  121. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +31 -14
  122. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
  123. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +32 -15
  124. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
  125. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +13 -9
  126. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
  127. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +53 -37
  128. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
  129. package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js +1 -1
  130. package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js.map +1 -1
  131. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +29 -19
  132. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
  133. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +59 -41
  134. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
  135. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts +4 -4
  136. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts.map +1 -1
  137. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js +3 -3
  138. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js.map +1 -1
  139. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts +3 -3
  140. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts.map +1 -1
  141. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js +42 -46
  142. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js.map +1 -1
  143. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts +8 -8
  144. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts.map +1 -1
  145. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js +15 -15
  146. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js.map +1 -1
  147. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts +3 -3
  148. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts.map +1 -1
  149. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js +10 -10
  150. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js.map +1 -1
  151. package/dist/application/sync/service/SyncPollingSupervisor.d.ts +1 -1
  152. package/dist/application/sync/service/SyncPollingSupervisor.js +1 -1
  153. package/dist/application/sync/service/SyncServiceBootstrap.d.ts +29 -19
  154. package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
  155. package/dist/application/sync/service/SyncServiceBootstrap.js +103 -78
  156. package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
  157. package/dist/application/sync/service/errors.d.ts +1 -1
  158. package/dist/application/sync/service/errors.js +1 -1
  159. package/dist/application/sync/service/errors.js.map +1 -1
  160. package/dist/application/sync/sheets/conflictProjection.d.ts.map +1 -0
  161. package/dist/application/sync/sheets/conflictProjection.js.map +1 -0
  162. package/dist/application/sync/{gateway → sheets}/conflictProjectionRegistration.d.ts +1 -1
  163. package/dist/application/sync/sheets/conflictProjectionRegistration.d.ts.map +1 -0
  164. package/dist/application/sync/{gateway → sheets}/conflictProjectionRegistration.js +3 -3
  165. package/dist/application/sync/sheets/conflictProjectionRegistration.js.map +1 -0
  166. package/dist/application/sync/sheets/constants.d.ts +66 -0
  167. package/dist/application/sync/sheets/constants.d.ts.map +1 -0
  168. package/dist/application/sync/{gateway → sheets}/constants.js +15 -15
  169. package/dist/application/sync/sheets/constants.js.map +1 -0
  170. package/dist/application/sync/sheets/errors.d.ts +15 -0
  171. package/dist/application/sync/sheets/errors.d.ts.map +1 -0
  172. package/dist/application/sync/sheets/errors.js +16 -0
  173. package/dist/application/sync/sheets/errors.js.map +1 -0
  174. package/dist/application/sync/{gateway/coordinator/CoordinatedSyncGateway.d.ts → sheets/mutationCoordinator/CoordinatedSheetsProvider.d.ts} +29 -28
  175. package/dist/application/sync/sheets/mutationCoordinator/CoordinatedSheetsProvider.d.ts.map +1 -0
  176. package/dist/application/sync/{gateway/coordinator/CoordinatedSyncGateway.js → sheets/mutationCoordinator/CoordinatedSheetsProvider.js} +27 -26
  177. package/dist/application/sync/sheets/mutationCoordinator/CoordinatedSheetsProvider.js.map +1 -0
  178. package/dist/application/sync/{gateway/coordinator → sheets/mutationCoordinator}/asyncMutex.d.ts +2 -3
  179. package/dist/application/sync/sheets/mutationCoordinator/asyncMutex.d.ts.map +1 -0
  180. package/dist/application/sync/sheets/mutationCoordinator/asyncMutex.js.map +1 -0
  181. package/dist/application/sync/{gateway/coordinator/coordinatorTelemetry.d.ts → sheets/mutationCoordinator/laneTelemetry.d.ts} +4 -4
  182. package/dist/application/sync/sheets/mutationCoordinator/laneTelemetry.d.ts.map +1 -0
  183. package/dist/application/sync/{gateway/coordinator/coordinatorTelemetry.js → sheets/mutationCoordinator/laneTelemetry.js} +5 -5
  184. package/dist/application/sync/sheets/mutationCoordinator/laneTelemetry.js.map +1 -0
  185. package/dist/application/sync/{gateway/SyncGatewayBootstrap.d.ts → sheets/sheetsProvisioning.d.ts} +14 -14
  186. package/dist/application/sync/sheets/sheetsProvisioning.d.ts.map +1 -0
  187. package/dist/application/sync/sheets/sheetsProvisioning.js +95 -0
  188. package/dist/application/sync/sheets/sheetsProvisioning.js.map +1 -0
  189. package/dist/application/sync/{gateway/syncGateway.d.ts → sheets/syncSheets.d.ts} +61 -117
  190. package/dist/application/sync/sheets/syncSheets.d.ts.map +1 -0
  191. package/dist/application/sync/sheets/syncSheets.js +144 -0
  192. package/dist/application/sync/sheets/syncSheets.js.map +1 -0
  193. package/dist/application/sync/{gateway/transportClassification.d.ts → sheets/transportOutcome.d.ts} +23 -22
  194. package/dist/application/sync/sheets/transportOutcome.d.ts.map +1 -0
  195. package/dist/application/sync/sheets/transportOutcome.js +97 -0
  196. package/dist/application/sync/sheets/transportOutcome.js.map +1 -0
  197. package/dist/application/sync/sheets/validation.d.ts +22 -0
  198. package/dist/application/sync/sheets/validation.d.ts.map +1 -0
  199. package/dist/application/sync/sheets/validation.js +79 -0
  200. package/dist/application/sync/sheets/validation.js.map +1 -0
  201. package/dist/application/sync/telemetry/syncTiming.d.ts +7 -7
  202. package/dist/application/sync/telemetry/syncTiming.d.ts.map +1 -1
  203. package/dist/application/sync/telemetry/syncTiming.js +2 -2
  204. package/dist/application/sync/telemetry/syncTiming.js.map +1 -1
  205. package/dist/domain/evaluate/contracts.d.ts +1 -1
  206. package/dist/domain/evaluate/contracts.js +1 -1
  207. package/dist/domain/model/constants.d.ts +1 -1
  208. package/dist/domain/model/constants.d.ts.map +1 -1
  209. package/dist/domain/model/types.d.ts +1 -1
  210. package/dist/domain/model/types.d.ts.map +1 -1
  211. package/dist/index.d.ts +3 -2
  212. package/dist/index.d.ts.map +1 -1
  213. package/dist/index.js +3 -2
  214. package/dist/index.js.map +1 -1
  215. package/dist/infrastructure/storage/index.d.ts +1 -1
  216. package/dist/infrastructure/storage/index.d.ts.map +1 -1
  217. package/dist/infrastructure/storage/index.js +1 -1
  218. package/dist/infrastructure/storage/index.js.map +1 -1
  219. package/dist/infrastructure/storage/state/observation/observationAudit.d.ts +1 -1
  220. package/dist/infrastructure/storage/state/observation/observationAudit.js +1 -1
  221. package/dist/infrastructure/storage/state/observation/observationTypes.d.ts +3 -3
  222. package/dist/infrastructure/storage/state/observation/observationTypes.d.ts.map +1 -1
  223. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +13 -1
  224. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
  225. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +23 -2
  226. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
  227. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts +9 -3
  228. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts.map +1 -1
  229. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js +7 -1
  230. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js.map +1 -1
  231. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +11 -1
  232. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
  233. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +44 -3
  234. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
  235. package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts +4 -4
  236. package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts.map +1 -1
  237. package/dist/infrastructure/storage/sync/shared/syncRegistry.js +4 -4
  238. package/dist/infrastructure/storage/sync/shared/syncRegistry.js.map +1 -1
  239. package/dist/shared/encoding/types.d.ts +1 -1
  240. package/docs/architecture.md +52 -23
  241. package/docs/ci.md +31 -23
  242. package/docs/code-guidelines.md +10 -18
  243. package/docs/development.md +37 -11
  244. package/docs/gateway-removal-inventory.md +147 -0
  245. package/docs/quick-start.md +36 -26
  246. package/docs/sync-bulk-write-benchmark.md +561 -0
  247. package/docs/sync-observability.md +38 -45
  248. package/docs/write-and-synchronization-flow.md +56 -39
  249. package/package.json +5 -4
  250. package/apps-script/gateway/Code.gs +0 -447
  251. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts +0 -43
  252. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts.map +0 -1
  253. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js +0 -52
  254. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js.map +0 -1
  255. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +0 -24
  256. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +0 -1
  257. package/dist/adapter/sheets/providers/apps-script-gateway/index.js +0 -13
  258. package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +0 -1
  259. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts +0 -44
  260. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts.map +0 -1
  261. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js +0 -181
  262. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js.map +0 -1
  263. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts +0 -3
  264. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts.map +0 -1
  265. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +0 -810
  266. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js.map +0 -1
  267. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts +0 -31
  268. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts.map +0 -1
  269. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +0 -560
  270. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js.map +0 -1
  271. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts +0 -12
  272. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts.map +0 -1
  273. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js +0 -166
  274. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js.map +0 -1
  275. package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.d.ts +0 -8
  276. package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.d.ts.map +0 -1
  277. package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.js +0 -122
  278. package/dist/adapter/sheets/providers/apps-script-gateway/operations/shared/appsScriptStableCodecSource.js.map +0 -1
  279. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +0 -31
  280. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +0 -1
  281. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +0 -567
  282. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +0 -1
  283. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts +0 -19
  284. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts.map +0 -1
  285. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js +0 -37
  286. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js.map +0 -1
  287. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts +0 -51
  288. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts.map +0 -1
  289. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js +0 -60
  290. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js.map +0 -1
  291. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts +0 -44
  292. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts.map +0 -1
  293. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js +0 -40
  294. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js.map +0 -1
  295. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts +0 -12
  296. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts.map +0 -1
  297. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js +0 -41
  298. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js.map +0 -1
  299. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts +0 -5
  300. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts.map +0 -1
  301. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js +0 -53
  302. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js.map +0 -1
  303. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts +0 -4
  304. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts.map +0 -1
  305. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js +0 -2
  306. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js.map +0 -1
  307. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts +0 -11
  308. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts.map +0 -1
  309. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js +0 -36
  310. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js.map +0 -1
  311. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts +0 -68
  312. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts.map +0 -1
  313. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js +0 -273
  314. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js.map +0 -1
  315. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +0 -73
  316. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +0 -1
  317. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +0 -363
  318. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +0 -1
  319. package/dist/adapter/sheets/providers/apps-script-gateway/validation.d.ts +0 -3
  320. package/dist/adapter/sheets/providers/apps-script-gateway/validation.d.ts.map +0 -1
  321. package/dist/adapter/sheets/providers/apps-script-gateway/validation.js +0 -10
  322. package/dist/adapter/sheets/providers/apps-script-gateway/validation.js.map +0 -1
  323. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts.map +0 -1
  324. package/dist/application/sync/gateway/SyncGatewayBootstrap.js +0 -95
  325. package/dist/application/sync/gateway/SyncGatewayBootstrap.js.map +0 -1
  326. package/dist/application/sync/gateway/conflictProjection.d.ts.map +0 -1
  327. package/dist/application/sync/gateway/conflictProjection.js.map +0 -1
  328. package/dist/application/sync/gateway/conflictProjectionRegistration.d.ts.map +0 -1
  329. package/dist/application/sync/gateway/conflictProjectionRegistration.js.map +0 -1
  330. package/dist/application/sync/gateway/constants.d.ts +0 -66
  331. package/dist/application/sync/gateway/constants.d.ts.map +0 -1
  332. package/dist/application/sync/gateway/constants.js.map +0 -1
  333. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.d.ts.map +0 -1
  334. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.js.map +0 -1
  335. package/dist/application/sync/gateway/coordinator/asyncMutex.d.ts.map +0 -1
  336. package/dist/application/sync/gateway/coordinator/asyncMutex.js.map +0 -1
  337. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.d.ts.map +0 -1
  338. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.js.map +0 -1
  339. package/dist/application/sync/gateway/errors.d.ts +0 -15
  340. package/dist/application/sync/gateway/errors.d.ts.map +0 -1
  341. package/dist/application/sync/gateway/errors.js +0 -16
  342. package/dist/application/sync/gateway/errors.js.map +0 -1
  343. package/dist/application/sync/gateway/syncGateway.d.ts.map +0 -1
  344. package/dist/application/sync/gateway/syncGateway.js +0 -191
  345. package/dist/application/sync/gateway/syncGateway.js.map +0 -1
  346. package/dist/application/sync/gateway/transportClassification.d.ts.map +0 -1
  347. package/dist/application/sync/gateway/transportClassification.js +0 -133
  348. package/dist/application/sync/gateway/transportClassification.js.map +0 -1
  349. package/dist/application/sync/gateway/validation.d.ts +0 -22
  350. package/dist/application/sync/gateway/validation.d.ts.map +0 -1
  351. package/dist/application/sync/gateway/validation.js +0 -79
  352. package/dist/application/sync/gateway/validation.js.map +0 -1
  353. /package/dist/application/sync/{gateway → sheets}/conflictProjection.d.ts +0 -0
  354. /package/dist/application/sync/{gateway → sheets}/conflictProjection.js +0 -0
  355. /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.