Parfii-bot
|
02e4b25af2
|
fix(entity-store/a1): C1 type coercion + C2 FTS transaction + FTS5 injection + M3 SQL escape + TEXT cap + M2 migration version
6 critical/high bugs from post-convergence audit fixed in one pass.
New src/verbs/validate.rs (95 LOC) — shared typed validator:
- coerce() returns VerbError::InvalidType{field,expected,got} on wrong-kind JSON
- Preserves "missing key → default" semantics (additive, not breaking)
- MAX_TEXT_BYTES 64 KiB cap enforced on all text fields (M2 audit)
verbs/create.rs + update.rs (C1 + C2):
- Typed validation replaces silent 0/""/empty coercion
- insert_tx() + update_tx() wrap INSERT + FTS DELETE+INSERT in
conn.unchecked_transaction(); mid-flight failure rolls back both
main row + FTS sidecar together (no orphan FTS rows)
verbs/search.rs — fts5_quote() defends FTS5 syntax injection:
- User query wrapped in "..." phrase quotes, internal " doubled
- Column-prefix `title:secret`, NEAR(), wildcards become literal
- Integration + unit tests
engine.rs:
- ddl_column() escapes ' → '' on TextDefault values (M3)
- apply_user_version() stamps CURRENT_USER_VERSION=1 via PRAGMA;
idempotent (won't downgrade). Opens migration path (M2).
Tests: 22/22 (was 10, +12). kei-task 9/9 preserved — no regression.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-23 05:27:59 +08:00 |
|
Parfii-bot
|
793b91bc43
|
feat(convergence/p1): kei-entity-store engine + schema fragments + kei-task pilot
Layer A + B of convergence wave. Extract common SQLite-CRUD + graph
logic into kei-entity-store engine; introduce JSON Schema fragments;
pilot-migrate kei-task to verify parity.
New crate _primitives/_rust/kei-entity-store/ (1151 LOC):
- src/schema.rs — EntitySchema + FieldDef + enabled_verbs + fts_columns
+ edge_table + custom_migrations
- src/engine.rs — Store::open with WAL pragma + migration runner
- src/verbs/ — 8 data-driven verb modules (create/get/list/search/
update/delete/link/rank) uniform JSON-in/JSON-out signature
- src/error.rs — typed VerbError enum
- tests/verb_smoke.rs — 10/10 green
New _schemas/fragments/ (83 LOC JSON):
- entity-base.json, titled.json, titled-content.json, edge.json
kei-task pilot migration:
- TASK_SCHEMA: EntitySchema static (67 LOC, was 58)
- store.rs becomes thin shim over engine::Store
- atoms/create.rs + atoms/search.rs delegate to engine verbs
- atoms/schemas/*.json use $ref to _schemas/fragments/ (DRY)
- Task-specific secondary tables (milestones, task_deps) stay via
schema.custom_migrations; cycle-detection in deps.rs stays
hand-rolled (domain logic, not generic CRUD)
- 9/9 tests green — full behavioural parity
Convergence delta:
- kei-task touched files: 342 → 389 LOC (+47 for JSON marshalling
boundary; net wash on pilot)
- BUT each remaining 5 sibling crate can shrink ~400-500 LOC on migration
- Expected total reduction when all 6 migrated: ~2500 LOC across the cluster
Follow-ups declared:
- Migrate kei-chat-store, kei-content-store, kei-social-store to engine
- Migrate kei-sage (needs string-id edge variant; currently generic
link/rank assume int ids)
- Migrate kei-crossdomain
- Expose list/delete atoms in kei-task (engine supports, atoms not yet)
- Fold kei-curator as engine::hygiene module (per P4 audit)
- Fold kei-search-core entities, keep workflow as thin kei-search-pipeline
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-04-23 04:46:47 +08:00 |
|