Skip to content

Commit 8c5c222

Browse files
++
1 parent 10b480c commit 8c5c222

15 files changed

+670
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# TASK-075: Spec (RGRTDD) — `crsql_automigrate` behavior
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
high
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Rust reference implementation: `core/rs/core/src/automigrate.rs`
18+
- Rust integration tests: `core/rs/integration_check/src/t/automigrate.rs`
19+
- Zig alter path: `zig/src/schema_alter.zig`
20+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
21+
22+
## Description
23+
Define the intended behavior of `crsql_automigrate(schema_sql[, cleanup_sql])` by capturing it in executable tests.
24+
25+
The goal is to make it hard to accidentally ship a “toy” automigrate:
26+
- It must be idempotent.
27+
- It must be atomic.
28+
- It must preserve CRR invariants (when migrating CRR tables it must use the alter flow).
29+
30+
This is a **spec/tests-only** task. Do not implement `crsql_automigrate` here.
31+
32+
## Files to Modify
33+
- `zig/harness/test-automigrate.sh` (new)
34+
- `zig/harness/test-parity.sh` (wire into suite)
35+
- `research/zig-cr/92-gap-backlog.md`
36+
37+
## Acceptance Criteria
38+
- [ ] Test suite exists that fails on current Zig (missing function).
39+
- [ ] Tests describe behavior (no “should”).
40+
- [ ] At minimum, tests cover:
41+
1. **Empty schema is a no-op**: `SELECT crsql_automigrate('')` returns `migration complete`.
42+
2. **Create tables**: schema with a new table results in the table existing.
43+
3. **Drop tables**: tables not present in desired schema are dropped (excluding `sqlite_%`, `crsql_%`, `__crsql_%`, and `%__crsql_%`).
44+
4. **Add column**: adding a column via desired schema results in column existing.
45+
5. **Drop column**: removing a column results in column dropped.
46+
6. **Index reconciliation**: indices match the desired schema.
47+
7. **CRR table migration uses alter flow**: if the table is a CRR, automigrate uses `crsql_begin_alter`/`crsql_commit_alter` semantics so triggers remain correct.
48+
8. **Atomicity**: if the schema is invalid, no partial changes persist.
49+
50+
## Progress Log
51+
### 2025-12-18
52+
- Task created from Rust↔Zig gap analysis.
53+
54+
## Completion Notes
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# TASK-076: Implement (RGRTDD) — `crsql_automigrate` in Zig
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
high
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Spec task: `.tasks/backlog/TASK-075-spec-automigrate.md`
18+
- Rust reference: `core/rs/core/src/automigrate.rs`
19+
- Zig alter functions: `zig/src/schema_alter.zig`
20+
- Registration point: `zig/src/ffi/init.zig`
21+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
22+
23+
## Description
24+
Implement `crsql_automigrate` in Zig so that the RGRTDD tests from TASK-075 pass.
25+
26+
Mirror Rust semantics where possible:
27+
- Create an in-memory database to parse/validate desired schema.
28+
- Strip CRR statements when validating in memory.
29+
- Use a savepoint for atomic migration.
30+
- Apply diffs (drop tables/cols, add cols, reconcile indices).
31+
- For CRR tables, wrap modifications with begin/commit alter.
32+
33+
## Files to Modify
34+
- `zig/src/automigrate.zig` (new)
35+
- `zig/src/ffi/init.zig`
36+
- `zig/src/root.zig` (if module wiring required)
37+
- `zig/src/schema_alter.zig` (only if needed)
38+
- `research/zig-cr/92-gap-backlog.md`
39+
40+
## Acceptance Criteria
41+
- [ ] `zig/harness/test-automigrate.sh` passes.
42+
- [ ] No regression in `make -C zig test-parity`.
43+
- [ ] Failure modes are surfaced as SQLite errors (message + error code) consistent with Rust behavior.
44+
45+
## Progress Log
46+
### 2025-12-18
47+
- Task created from Rust↔Zig gap analysis.
48+
49+
## Completion Notes
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# TASK-077: Spec (RGRTDD) — `crsql_as_crr` backfills existing rows
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
high
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Rust reference: `core/rs/core/src/create_crr.rs`, `core/rs/core/src/backfill.rs`
18+
- Rust integration tests: `core/rs/integration_check/src/t/backfill.rs`
19+
- Zig implementation: `zig/src/as_crr.zig`
20+
- Zig parity tests: `zig/harness/test-parity.sh`
21+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
22+
23+
## Description
24+
Define the required behavior when upgrading a pre-populated table to a CRR.
25+
26+
In real systems, schema conversion often happens after data exists (migrations, importing from legacy DBs).
27+
28+
This is a **spec/tests-only** task.
29+
30+
## Files to Modify
31+
- `zig/harness/test-as-crr-backfill.sh` (new)
32+
- `zig/harness/test-parity.sh` (wire into suite)
33+
- `research/zig-cr/92-gap-backlog.md`
34+
35+
## Acceptance Criteria
36+
- [ ] Test fails on current Zig (currently it only creates schema/triggers).
37+
- [ ] Test asserts at least:
38+
1. If a table already contains rows, after `SELECT crsql_as_crr('t')`:
39+
- `t__crsql_pks` contains an entry per row.
40+
- `t__crsql_clock` contains entries for each non-PK column per row; and if no non-PK columns exist, it contains sentinel (`'-1'`) entries.
41+
2. Backfill is idempotent: calling `crsql_as_crr` twice does not duplicate clock/pk entries.
42+
3. Backfill does not rewrite rows already present in `__crsql_pks`/`__crsql_clock`.
43+
44+
## Progress Log
45+
### 2025-12-18
46+
- Task created from Rust↔Zig gap analysis.
47+
48+
## Completion Notes
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# TASK-078: Implement (RGRTDD) — `crsql_as_crr` backfill in Zig
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
high
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Spec task: `.tasks/backlog/TASK-077-spec-as-crr-backfill.md`
18+
- Rust reference backfill: `core/rs/core/src/backfill.rs`
19+
- Zig implementation: `zig/src/as_crr.zig`
20+
- Registration point: `zig/src/ffi/init.zig`
21+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
22+
23+
## Description
24+
Implement backfill behavior for `crsql_as_crr` in Zig.
25+
26+
Design intent:
27+
- Populate `__crsql_pks` and `__crsql_clock` for existing rows.
28+
- Use savepoints for atomicity.
29+
- Keep behavior idempotent (EXCEPT/LEFT JOIN style filters like Rust).
30+
31+
## Files to Modify
32+
- `zig/src/as_crr.zig`
33+
- `zig/src/backfill.zig` (new, if needed)
34+
- `research/zig-cr/92-gap-backlog.md`
35+
36+
## Acceptance Criteria
37+
- [ ] `zig/harness/test-as-crr-backfill.sh` passes.
38+
- [ ] No regression in `make -C zig test-parity`.
39+
40+
## Progress Log
41+
### 2025-12-18
42+
- Task created from Rust↔Zig gap analysis.
43+
44+
## Completion Notes
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# TASK-079: Spec (RGRTDD) — `clset` virtual table module
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
medium
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Rust reference: `core/rs/core/src/create_cl_set_vtab.rs`
18+
- Rust integration tests: `core/rs/integration_check/src/t/test_cl_set_vtab.rs`
19+
- Zig: (missing)
20+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
21+
22+
## Description
23+
Define behavior for the `clset` module ("Causal Length Set" virtual table).
24+
25+
This task creates failing tests that define:
26+
- Required naming conventions (`*_schema`).
27+
- Which physical tables are created.
28+
- That the base table is converted to CRR.
29+
30+
This is a **spec/tests-only** task.
31+
32+
## Files to Modify
33+
- `zig/harness/test-clset-vtab.sh` (new)
34+
- `zig/harness/test-parity.sh` (wire into suite)
35+
- `research/zig-cr/92-gap-backlog.md`
36+
37+
## Acceptance Criteria
38+
- [ ] Test fails on current Zig (module missing).
39+
- [ ] At minimum, tests cover:
40+
1. `CREATE VIRTUAL TABLE something_schema USING clset(...)` succeeds.
41+
2. Creating a virtual table without `_schema` suffix fails with a clear error.
42+
3. After create, physical tables exist:
43+
- `<base>` (storage)
44+
- `<base>__crsql_clock`
45+
- `<base>__crsql_pks`
46+
4. The base table is a CRR (e.g. `SELECT crsql_is_crr('<base>')` returns true).
47+
48+
## Progress Log
49+
### 2025-12-18
50+
- Task created from Rust↔Zig gap analysis.
51+
52+
## Completion Notes
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# TASK-080: Implement (RGRTDD) — `clset` virtual table module in Zig
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
medium
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Spec task: `.tasks/backlog/TASK-079-spec-clset-vtab.md`
18+
- Rust reference: `core/rs/core/src/create_cl_set_vtab.rs`
19+
- Registration point: `zig/src/ffi/init.zig`
20+
- Zig CRR creation: `zig/src/as_crr.zig`
21+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
22+
23+
## Description
24+
Implement the `clset` module in Zig so that tests from TASK-079 pass.
25+
26+
Important notes from Rust behavior:
27+
- Virtual table name must end with `_schema`.
28+
- It creates a base storage table and upgrades it to a CRR.
29+
- It declares a schema vtab interface with hidden columns.
30+
31+
## Files to Modify
32+
- `zig/src/clset_vtab.zig` (new)
33+
- `zig/src/ffi/init.zig`
34+
- `zig/src/as_crr.zig` (only if needed)
35+
- `research/zig-cr/92-gap-backlog.md`
36+
37+
## Acceptance Criteria
38+
- [ ] `zig/harness/test-clset-vtab.sh` passes.
39+
- [ ] No regression in `make -C zig test-parity`.
40+
41+
## Progress Log
42+
### 2025-12-18
43+
- Task created from Rust↔Zig gap analysis.
44+
45+
## Completion Notes
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# TASK-081: Spec (RGRTDD) — `crsql_unpack_columns` virtual table
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
medium
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Rust reference implementation: `core/rs/core/src/unpack_columns_vtab.rs`
18+
- Rust pack/unpack code: `core/rs/core/src/pack_columns.rs`
19+
- Zig pack code: `zig/src/pack_columns.zig`
20+
- Zig codec helpers: `zig/src/codec.zig`
21+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
22+
23+
## Description
24+
Define the behavior of the `crsql_unpack_columns` virtual table.
25+
26+
This vtab is a debugging/inspection tool and is part of the “real system” ergonomics: it helps users validate and troubleshoot packed PK formats.
27+
28+
This is a **spec/tests-only** task.
29+
30+
## Files to Modify
31+
- `zig/harness/test-unpack-columns-vtab.sh` (new)
32+
- `zig/harness/test-parity.sh` (wire into suite)
33+
- `research/zig-cr/92-gap-backlog.md`
34+
35+
## Acceptance Criteria
36+
- [ ] Test fails on current Zig (module missing).
37+
- [ ] At minimum, test asserts:
38+
1. `SELECT cell FROM crsql_unpack_columns WHERE package = crsql_pack_columns(12, 'str', x'010203')` returns the sequence `12`, `str`, `x'010203'`.
39+
2. The vtab is INNOCUOUS (cannot write / no side effects).
40+
3. Filter requires the hidden `package` constraint (like Rust best-index behavior).
41+
42+
## Progress Log
43+
### 2025-12-18
44+
- Task created from Rust↔Zig gap analysis.
45+
46+
## Completion Notes
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# TASK-082: Implement (RGRTDD) — `crsql_unpack_columns` vtab in Zig
2+
3+
## Status
4+
- [ ] Planned
5+
- [ ] Assigned
6+
- [ ] In Progress
7+
- [ ] Blocked (reason: ...)
8+
- [ ] Complete
9+
10+
## Priority
11+
medium
12+
13+
## Assigned To
14+
(unassigned)
15+
16+
## Parent Docs / Cross-links
17+
- Spec task: `.tasks/backlog/TASK-081-spec-unpack-columns-vtab.md`
18+
- Rust reference: `core/rs/core/src/unpack_columns_vtab.rs`
19+
- Zig pack/unpack: `zig/src/codec.zig`, `zig/src/pack_columns.zig`
20+
- Registration point: `zig/src/ffi/init.zig`
21+
- Gap backlog: `research/zig-cr/92-gap-backlog.md`
22+
23+
## Description
24+
Implement `crsql_unpack_columns` module in Zig.
25+
26+
Key behaviors to match:
27+
- It is a virtual table with schema `CREATE TABLE x(cell ANY, package BLOB hidden)`.
28+
- It requires a usable constraint on the hidden `package` column.
29+
- It iterates unpacked columns as rows.
30+
31+
## Files to Modify
32+
- `zig/src/unpack_columns_vtab.zig` (new)
33+
- `zig/src/ffi/init.zig`
34+
- `zig/src/codec.zig` (only if needed)
35+
- `research/zig-cr/92-gap-backlog.md`
36+
37+
## Acceptance Criteria
38+
- [ ] `zig/harness/test-unpack-columns-vtab.sh` passes.
39+
- [ ] No regression in `make -C zig test-parity`.
40+
41+
## Progress Log
42+
### 2025-12-18
43+
- Task created from Rust↔Zig gap analysis.
44+
45+
## Completion Notes

0 commit comments

Comments
 (0)