docs(localdb-phase2): pre-answer Task 0's STOP condition — it does not fire
Phase 2's recon carries a STOP condition: a BLOB payload column in the legacy
alarm store-and-forward table could not be registered for replication and would
have to become base64 TEXT, sized against the chunk guidance. Resolved ahead of
execution so the answer survives into the Phase 2 session:
- No BLOB. All 8 columns are TEXT/INTEGER; the payload is PayloadJson TEXT NOT
NULL. No base64 conversion, no chunk sizing needed.
- The executed DDL (SqliteStoreAndForwardSink.cs:657-667) matches the class
doc-comment at :17-26 exactly — checked because a doc comment is not evidence.
- Payload is bounded by shape: a serialized AlarmHistorianEvent is 10 scalar
fields, no collections or nesting, so realistic worst case is low single-digit
KB against a 171 KB guidance.
- The PK IS autoincrement, confirming the plan's prediction that the migrator
must mint deterministic mig-{node}-{legacyId} ids and the new table needs a
TEXT GUID PK.
- Also captured for reuse: the drain's covering index (DeadLettered, RowId), and
the exact legacy column list the migrator's pragma_table_info intersection
check compares against.
Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
@@ -56,6 +56,29 @@ auth already in place, no in-memory SQLite in tests, cp-triplet-only rig inspect
|
||||
(**STOP condition:** a BLOB payload column cannot be registered — it must become base64 TEXT in
|
||||
the new schema, and the recon must size the largest realistic payload against the 171 KB-ish
|
||||
chunk guidance; alarm events are small JSON, so expect this to be fine, but verify).
|
||||
|
||||
> **PRE-ANSWERED 2026-07-21 (verified against `master` `d218282c`) — the STOP condition does NOT
|
||||
> fire.** Re-verify cheaply during recon, but do not expect a surprise:
|
||||
>
|
||||
> - **Executed DDL:** `SqliteStoreAndForwardSink.cs:657-667`. It matches the class doc-comment at
|
||||
> `:17-26` exactly — no drift between the documented and executed schema.
|
||||
> - **No BLOB.** All 8 columns are TEXT/INTEGER; the payload column is **`PayloadJson TEXT NOT
|
||||
> NULL`**. So no base64 conversion is needed and the chunk-size sizing is moot.
|
||||
> - **Payload is small and bounded by shape.** `PayloadJson` is a serialized
|
||||
> `AlarmHistorianEvent` — 10 scalar fields (`AlarmId`, `EquipmentPath`, `AlarmName`,
|
||||
> `AlarmTypeName`, `Severity`, `EventKind`, `Message`, `User`, `Comment?`, `TimestampUtc`).
|
||||
> No collections, no nesting. Realistic worst case is low single-digit KB (operator `Comment`
|
||||
> is the only unbounded-ish field), far under the 171 KB chunk guidance.
|
||||
> - **PK IS autoincrement** — `RowId INTEGER PRIMARY KEY AUTOINCREMENT`. This confirms the
|
||||
> plan's own prediction: LocalDb cannot replicate an autoincrement key, so the migrator
|
||||
> **must** mint deterministic `mig-{node}-{legacyId}` ids, and the new table needs a TEXT
|
||||
> GUID PK as already specified in the Architecture note.
|
||||
> - **One index to carry across:** `IX_Queue_Drain ON Queue (DeadLettered, RowId)` (`:667`) —
|
||||
> the drain's covering index. The `alarm_sf_events` equivalent wants the same shape over
|
||||
> (dead-lettered flag, insertion order) so the drain query stays index-covered.
|
||||
> - **Legacy column list for the migrator's `pragma_table_info` intersection check:**
|
||||
> `RowId, AlarmId, EnqueuedUtc, PayloadJson, AttemptCount, LastAttemptUtc, LastError,
|
||||
> DeadLettered`.
|
||||
2. The public seam: the interface the drain worker and producers use (e.g. `IAlarmHistorianSink` /
|
||||
enqueue+dequeue+markDelivered+deadLetter methods), so the rewire can keep it byte-compatible.
|
||||
3. Semantics to preserve: `Capacity` (1,000,000) enforcement, `MaxAttempts` (10), dead-letter
|
||||
|
||||
Reference in New Issue
Block a user