hikoutei 0.3.2 → 0.3.3

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 (211) hide show
  1. package/README.md +12 -2
  2. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts +2 -0
  3. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts.map +1 -1
  4. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js +5 -0
  5. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js.map +1 -1
  6. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts +52 -0
  7. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts.map +1 -1
  8. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js +195 -13
  9. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js.map +1 -1
  10. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts +24 -0
  11. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts.map +1 -0
  12. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js +124 -0
  13. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js.map +1 -0
  14. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js +1 -1
  15. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js.map +1 -1
  16. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.d.ts +15 -2
  17. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.d.ts.map +1 -1
  18. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js +27 -3
  19. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js.map +1 -1
  20. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts +1 -0
  21. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts.map +1 -1
  22. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js +1 -0
  23. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js.map +1 -1
  24. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +2 -0
  25. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -1
  26. package/dist/adapter/sheets/providers/apps-script-gateway/index.js +1 -0
  27. package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -1
  28. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts +3 -1
  29. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts.map +1 -1
  30. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js +9 -0
  31. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js.map +1 -1
  32. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts.map +1 -1
  33. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +137 -20
  34. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js.map +1 -1
  35. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +82 -34
  36. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js.map +1 -1
  37. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +31 -0
  38. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +1 -0
  39. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +567 -0
  40. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +1 -0
  41. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts +12 -17
  42. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts.map +1 -1
  43. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js +27 -213
  44. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js.map +1 -1
  45. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts.map +1 -1
  46. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js +81 -8
  47. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js.map +1 -1
  48. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +1 -6
  49. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -1
  50. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +15 -9
  51. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -1
  52. package/dist/application/orm/mapping/projection.js +1 -1
  53. package/dist/application/orm/mapping/projection.js.map +1 -1
  54. package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -1
  55. package/dist/application/orm/persistence/flush/flushCoordinator.js +1 -0
  56. package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -1
  57. package/dist/application/orm/persistence/lifecycle/entityLifecycle.js +1 -1
  58. package/dist/application/orm/persistence/lifecycle/entityLifecycle.js.map +1 -1
  59. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts +3 -1
  60. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts.map +1 -1
  61. package/dist/application/sync/gateway/SyncGatewayBootstrap.js +3 -1
  62. package/dist/application/sync/gateway/SyncGatewayBootstrap.js.map +1 -1
  63. package/dist/application/sync/gateway/conflictProjection.d.ts +13 -0
  64. package/dist/application/sync/gateway/conflictProjection.d.ts.map +1 -0
  65. package/dist/application/sync/gateway/conflictProjection.js +58 -0
  66. package/dist/application/sync/gateway/conflictProjection.js.map +1 -0
  67. package/dist/application/sync/gateway/conflictProjectionRegistration.d.ts +11 -0
  68. package/dist/application/sync/gateway/conflictProjectionRegistration.d.ts.map +1 -0
  69. package/dist/application/sync/gateway/conflictProjectionRegistration.js +70 -0
  70. package/dist/application/sync/gateway/conflictProjectionRegistration.js.map +1 -0
  71. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.d.ts +102 -0
  72. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.d.ts.map +1 -0
  73. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.js +221 -0
  74. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.js.map +1 -0
  75. package/dist/application/sync/gateway/coordinator/asyncMutex.d.ts +51 -0
  76. package/dist/application/sync/gateway/coordinator/asyncMutex.d.ts.map +1 -0
  77. package/dist/application/sync/gateway/coordinator/asyncMutex.js +65 -0
  78. package/dist/application/sync/gateway/coordinator/asyncMutex.js.map +1 -0
  79. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.d.ts +31 -0
  80. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.d.ts.map +1 -0
  81. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.js +13 -0
  82. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.js.map +1 -0
  83. package/dist/application/sync/gateway/syncGateway.d.ts +26 -6
  84. package/dist/application/sync/gateway/syncGateway.d.ts.map +1 -1
  85. package/dist/application/sync/gateway/syncGateway.js +10 -2
  86. package/dist/application/sync/gateway/syncGateway.js.map +1 -1
  87. package/dist/application/sync/gateway/transportClassification.d.ts +62 -0
  88. package/dist/application/sync/gateway/transportClassification.d.ts.map +1 -0
  89. package/dist/application/sync/gateway/transportClassification.js +133 -0
  90. package/dist/application/sync/gateway/transportClassification.js.map +1 -0
  91. package/dist/application/sync/inbound/autoSystemConflictResolution.d.ts +26 -0
  92. package/dist/application/sync/inbound/autoSystemConflictResolution.d.ts.map +1 -0
  93. package/dist/application/sync/inbound/autoSystemConflictResolution.js +335 -0
  94. package/dist/application/sync/inbound/autoSystemConflictResolution.js.map +1 -0
  95. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +50 -0
  96. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -0
  97. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +97 -0
  98. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -0
  99. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts +4 -1
  100. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
  101. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +35 -1
  102. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
  103. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +14 -2
  104. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
  105. package/dist/application/sync/outbound/effects/SyncEffectWorker.js +190 -31
  106. package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
  107. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +25 -2
  108. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
  109. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +25 -2
  110. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
  111. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +14 -7
  112. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
  113. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +118 -14
  114. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
  115. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +30 -9
  116. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
  117. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +102 -18
  118. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
  119. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts.map +1 -1
  120. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js +49 -14
  121. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js.map +1 -1
  122. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts.map +1 -1
  123. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js +97 -17
  124. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js.map +1 -1
  125. package/dist/application/sync/service/SyncServiceBootstrap.d.ts +17 -0
  126. package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
  127. package/dist/application/sync/service/SyncServiceBootstrap.js +125 -10
  128. package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
  129. package/dist/application/sync/service/contracts.d.ts +2 -0
  130. package/dist/application/sync/service/contracts.d.ts.map +1 -1
  131. package/dist/application/sync/telemetry/syncTiming.d.ts +6 -0
  132. package/dist/application/sync/telemetry/syncTiming.d.ts.map +1 -1
  133. package/dist/application/sync/telemetry/syncTiming.js +2 -0
  134. package/dist/application/sync/telemetry/syncTiming.js.map +1 -1
  135. package/dist/domain/conflict/index.d.ts +1 -1
  136. package/dist/domain/conflict/index.d.ts.map +1 -1
  137. package/dist/domain/conflict/index.js +1 -1
  138. package/dist/domain/conflict/index.js.map +1 -1
  139. package/dist/domain/conflict/transitions.d.ts +3 -0
  140. package/dist/domain/conflict/transitions.d.ts.map +1 -1
  141. package/dist/domain/conflict/transitions.js +3 -2
  142. package/dist/domain/conflict/transitions.js.map +1 -1
  143. package/dist/domain/model/constants.d.ts +1 -0
  144. package/dist/domain/model/constants.d.ts.map +1 -1
  145. package/dist/domain/model/constants.js +1 -0
  146. package/dist/domain/model/constants.js.map +1 -1
  147. package/dist/infrastructure/storage/index.d.ts +4 -2
  148. package/dist/infrastructure/storage/index.d.ts.map +1 -1
  149. package/dist/infrastructure/storage/index.js +2 -1
  150. package/dist/infrastructure/storage/index.js.map +1 -1
  151. package/dist/infrastructure/storage/sqlite/migrateSchema.d.ts.map +1 -1
  152. package/dist/infrastructure/storage/sqlite/migrateSchema.js +59 -1
  153. package/dist/infrastructure/storage/sqlite/migrateSchema.js.map +1 -1
  154. package/dist/infrastructure/storage/sqlite/schema.d.ts +12 -1
  155. package/dist/infrastructure/storage/sqlite/schema.d.ts.map +1 -1
  156. package/dist/infrastructure/storage/sqlite/schema.js +47 -3
  157. package/dist/infrastructure/storage/sqlite/schema.js.map +1 -1
  158. package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts +2 -2
  159. package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts.map +1 -1
  160. package/dist/infrastructure/storage/state/canonical/canonicalCommit.js +1 -1
  161. package/dist/infrastructure/storage/state/canonical/canonicalCommit.js.map +1 -1
  162. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.d.ts +1 -0
  163. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.d.ts.map +1 -1
  164. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.js +1 -1
  165. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.js.map +1 -1
  166. package/dist/infrastructure/storage/state/observation/observationAudit.js +5 -1
  167. package/dist/infrastructure/storage/state/observation/observationAudit.js.map +1 -1
  168. package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts +10 -0
  169. package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts.map +1 -1
  170. package/dist/infrastructure/storage/state/resolution/resolutionWriter.js +106 -20
  171. package/dist/infrastructure/storage/state/resolution/resolutionWriter.js.map +1 -1
  172. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts +9 -1
  173. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts.map +1 -1
  174. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js +3 -0
  175. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js.map +1 -1
  176. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts +11 -0
  177. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts.map +1 -1
  178. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js +35 -0
  179. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js.map +1 -1
  180. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +12 -4
  181. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
  182. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +46 -15
  183. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
  184. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts +24 -0
  185. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts.map +1 -1
  186. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js +1 -0
  187. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js.map +1 -1
  188. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +9 -7
  189. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
  190. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +44 -8
  191. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
  192. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts +3 -1
  193. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts.map +1 -1
  194. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js +35 -2
  195. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js.map +1 -1
  196. package/dist/infrastructure/storage/sync/outbound/reconciliationSql.js +1 -0
  197. package/dist/infrastructure/storage/sync/outbound/reconciliationSql.js.map +1 -1
  198. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.d.ts +31 -0
  199. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.d.ts.map +1 -0
  200. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.js +92 -0
  201. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.js.map +1 -0
  202. package/dist/infrastructure/storage/sync/shared/writerLease.js +3 -1
  203. package/dist/infrastructure/storage/sync/shared/writerLease.js.map +1 -1
  204. package/docs/advanced-sheets-gateway-concurrency-problem.md +434 -0
  205. package/docs/architecture.md +53 -11
  206. package/docs/google-sheets-sync-scaling-strategy.md +459 -0
  207. package/docs/quick-start.md +15 -1
  208. package/docs/sync-bulk-write-benchmark.md +520 -0
  209. package/docs/sync-observability.md +39 -3
  210. package/docs/write-and-synchronization-flow.md +76 -17
  211. package/package.json +1 -1
@@ -39,8 +39,8 @@ SQLite transaction
39
39
  internal effect supervisor
40
40
  ├─ claim with a lease
41
41
  ├─ send a signed operation batch
42
- ├─ retry or recover an uncertain response
43
- └─ mark the effect applied/failed
42
+ ├─ persist uncertain delivery and schedule a durable postcondition probe
43
+ └─ mark the effect applied, terminally failed, or recoverably pending
44
44
  │
45
45
  ▼
46
46
  Apps Script gateway ──▶ Google Sheets
@@ -55,49 +55,108 @@ completed.
55
55
  New System_State rows use the bounded fast append operation where possible.
56
56
  Updates and deletes use guarded effects with expected visible revision/hash
57
57
  evidence. The same internal worker handles retries, response-loss recovery, and
58
- reconciliation. These operation types are implementation details and are not
59
- methods on the public EntityManager.
58
+ reconciliation. Each physical route's effects are split into bounded sub-batches
59
+ so one gateway call returns a complete result set instead of a partial prefix.
60
+ These operation types are implementation details and are not methods on the
61
+ public EntityManager.
60
62
 
61
63
  ## Inbound User_Input flow
62
64
 
63
65
  The internal service polls registered `User_Input` projections on a bounded
64
- interval. It reads the visible row, compares it with canonical SQLite state,
65
- and sends changed fields through the evaluator:
66
+ interval. By default each pass runs an adaptive values-only preflight: it reads
67
+ the cheap value surface, compares it with canonical SQLite state, and only
68
+ escalates a table to the metadata-preserving snapshot read when the preflight
69
+ cannot certify it as unchanged:
66
70
 
67
71
  ```text
68
72
  User_Input polling
69
- ├─ normalize literal/blank cells
73
+ ├─ values-only preflight over registered projections
74
+ ├─ escalate changed/ambiguous/schema tables to full metadata
75
+ ├─ normalize literal/blank cells and retain formula/merge/error metadata
70
76
  ├─ resolve business-key row binding
71
77
  ├─ validate ownership and field revisions
72
78
  ├─ classify accepted, conflict, stale, or quarantine
79
+ ├─ record Sync_Conflicts evidence
80
+ ├─ CAS-resolve conflicts in favor of canonical SQLite state
73
81
  └─ persist accepted observation and entity mutation in SQLite
74
82
  ```
75
83
 
84
+ The preflight never accepts or persists edits. It escalates a table whenever a
85
+ row changed, a business key is unknown or duplicated, an expected active entity
86
+ is missing from the projection, or any cell fails its literal/blank type check,
87
+ so the existing quarantine and conflict rules stay authoritative. Because the
88
+ values-only read drops formula, merged, and error metadata, the bootstrap also
89
+ forces a periodic metadata-preserving safety full scan (default one minute,
90
+ configurable) so invalid cells are rechecked and quarantined rather than
91
+ mistaken for literal user edits. The coordinator records any overdue safety-scan
92
+ lag, including a scan delayed by writer-lease contention, through internal
93
+ polling telemetry without changing the SQLite write boundary.
94
+
76
95
  Accepted observation writes update canonical state and the application entity in
77
96
  the same SQLite transaction. They do not enqueue a duplicate User_Input effect;
78
97
  only the required system projection repair/materialization is considered.
79
98
  Conflicts, stale writes, duplicate keys, and malformed cells remain visible in
80
- SQLite evidence tables for later handling.
99
+ SQLite evidence tables. A conflict is not left open indefinitely: the internal
100
+ resolver submits a fenced `acknowledge_system` command using the current
101
+ canonical revision, active candidate hash, and candidate epoch. When it applies,
102
+ it clears the candidate pointer and appends both the guarded canonical
103
+ User_Input rewrite and the `Sync_Conflicts` audit effect in the same SQLite
104
+ transaction. If the CAS is stale, the newer candidate remains authoritative for
105
+ the next observation pass rather than being overwritten.
81
106
 
82
107
  ## Provisioning and gateway boundary
83
108
 
84
109
  Projection provisioning is an internal service-start operation. The bootstrap
85
- generates route registrations and headers from the internal mapping, verifies
86
- remote schema drift, and starts workers only after provisioning succeeds. The
87
- Apps Script gateway remains intentionally thin:
110
+ generates route registrations and headers for the required System_State,
111
+ User_Input, and Sync_Conflicts projections, verifies remote schema drift, and
112
+ starts workers only after provisioning and unresolved-conflict backfill succeed.
113
+ The Apps Script gateway remains intentionally thin:
88
114
 
89
115
  1. verify the signed operation envelope
90
116
  2. validate the operation contract
91
- 3. execute the allowlisted Sheet operation
117
+ 3. execute the signed operation source, whose contract validates the registered Sheet operation
92
118
  4. return a structured result to the internal worker
93
119
 
120
+ The MVP gateway contract is a single deployable file:
121
+ `apps-script/gateway/Code.gs`. A user copies it into a spreadsheet-bound Apps
122
+ Script project, deploys it as a Web App, pastes the deployed `/exec` URL into
123
+ the `TYPED_SHEETS_GATEWAY_URL` constant, and runs `setupSyncGateway()` from the
124
+ editor. That setup writes the bound spreadsheet ID and a generated shared
125
+ secret into Script Properties and logs a copyable local `.env` block. This path
126
+ requires no `appsscript.json` manifest, no Apps Script Advanced Sheets Service,
127
+ no Google Cloud Sheets API activation, and no service account; the gateway runs
128
+ on the built-in `SpreadsheetApp`, `LockService`, and `PropertiesService`
129
+ services only. The signed gateway secret is a code-execution trust boundary;
130
+ keep it private and rotate the previously exposed value before production
131
+ deployment.
132
+
133
+ Sheet consistency is not provided by cross-request Sheet transactions; Google
134
+ Sheets offers no serializable isolation between separate API calls. It comes
135
+ from the Apps Script script lock (serializing concurrent gateway executions),
136
+ the hidden effect-receipt tab (each effect id and payload hash is recorded with
137
+ its visible evidence), effect-id/payload-hash dedupe (a replayed or concurrent
138
+ effect is recognized as already applied and never double-materialized), the
139
+ SQLite durable outbox (effects survive restarts and are delivered
140
+ at-least-once), fencing (spreadsheet authority epoch/token and worker/effect
141
+ leases reject stale writers), and postcondition recovery (uncertain deliveries
142
+ are probed until receipt-backed visible evidence matches). A batch-append
143
+ operation source that would use the Apps Script Advanced Sheets Service and an
144
+ `appsscript.json` manifest exists only as an out-of-MVP performance experiment;
145
+ it is not part of the default installation.
146
+
94
147
  Applications do not import or call the gateway client, protocol, operation
95
148
  builders, polling functions, or provisioning interfaces.
96
149
 
97
150
  ## Failure model
98
151
 
99
- An HTTP timeout or lost response does not prove that a Sheet write failed. The
100
- worker preserves durable work, classifies recoverable failures, and uses
101
- idempotent effects plus reconciliation to repair drift later. The SQLite commit
102
- is the application success boundary; remote delivery is at-least-once and
103
- asynchronous.
152
+ An HTTP timeout, non-JSON response, 404, or lost connection does not prove that
153
+ a Sheet write failed. The worker persists `delivery_uncertain` with a durable
154
+ probe schedule and dispatch identity, then promotes the effect only after
155
+ receipt-backed visible evidence is read. An explicit structured remote failure
156
+ uses the terminal failure path. SQLite also records a per-spreadsheet authority
157
+ epoch/token; gateway mutations carrying an older token are rejected. A pass that only
158
+ requeued uncertain work (a response-loss or postcondition-unapplied loop) backs
159
+ off with a bounded, jittered delay that resets as soon as forward progress
160
+ resumes; lease expiry and recovery keep effects live during the backoff. The
161
+ SQLite commit is the application success boundary; remote delivery is
162
+ at-least-once and asynchronous.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hikoutei",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Hikoutei — typed repository and safe write layer for Google Sheets-backed MVPs.",
5
5
  "repository": {
6
6
  "type": "git",