Files
query-orchestration/plans/mutable.metadata.review.combo.v3.codex.md
T
Jay Brown 17fc813823 Merged in feature/mutable-metadata1 (pull request #221)
M1, M2 and M3 complete

* M1, M2 and M3 complete

* review changes

* docs

* docs
2026-04-16 23:11:26 +00:00

87 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mutable Metadata Plan v3 Review (Codex)
A review of plans/mutable.metadata.plan.combo.v3.md and plans/mutable.metadata.plan.combo.v3.tracking.md since they are to be used as a pair to implement the plans/mutable.metadata.plan.combo.v3.md plan.
I reviewed the current legacy field-extraction flow first so the plan review is anchored to real behavior:
- `api/queryAPI/fieldextractions.go:20-69` binds the request, calls `FieldExtraction.CreateFieldExtraction`, and currently maps any create error to HTTP 500.
- `internal/fieldextraction/service.go:27-100` creates the extraction row, then locks existing version rows, computes `max(version)+1`, and inserts the version row.
- Authorization today is checked as `(user, action, first-path-segment resource)` with no document/client object passed into Permit.io: `internal/cognitoauth/middleware.go:84-110`, `internal/cognitoauth/permitio.go:79-89`.
## Findings
1. **Blocking: the tracking docs migration numbers collide with live migrations already in the repo.**
References:
- `plans/mutable.metadata.plan.combo.v3.tracking.md:48-75`
- `internal/database/migrations`: existing `00000000000120_*` through `00000000000123_*` are already present (`00000000000120_remove_text_extraction`, `00000000000121_create_eula_tables`, `00000000000122_make_eula_effective_date_nullable`, `00000000000123_create_ui_settings`)
Impact:
- Phase 1 cannot start as written.
- Any implementation that follows the tracking doc literally will create filename collisions and broken migration ordering.
Recommendation:
- Renumber all new mutable-metadata migrations to the next free sequence and update every tracking reference before coding.
2. **Blocking: the plan grants `/custom-metadata` read/write to `client_user`, but the current auth model is not tenant-scoped.**
References:
- Plan grants: `plans/mutable.metadata.plan.combo.v3.md:730-780`
- Current auth check: `internal/cognitoauth/middleware.go:105-110`, `internal/cognitoauth/permitio.go:79-89`
- Current documented limitation: `cmd/auth_related/permit.setup/permit_policies.yaml:155-184`
Impact:
- `custom-metadata:get/post` would be authorized purely by resource/action on the first path segment.
- Without new application-level document/client ownership checks, a `client_user` or `user_admin` who knows another document UUID can read/write that documents custom metadata across clients.
Recommendation:
- Resolve scoping before implementation. Either:
- Add explicit document/client ownership enforcement in the custom-metadata service/controller and track it as first-class work, or
- Do not grant `client_user`/`user_admin` write access to `/custom-metadata` until tenant scoping exists.
3. **High: Phase 5a in the tracking doc misses the HTTP-layer work needed to return the documented 409.**
References:
- Tracking: `plans/mutable.metadata.plan.combo.v3.tracking.md:290-299`
- Current controller behavior: `api/queryAPI/fieldextractions.go:45-50`
Impact:
- Adding only a service pre-check will not produce the promised HTTP 409.
- As written, `POST /field-extractions` will still return 500 for the new mutual-exclusivity error.
Recommendation:
- Add explicit controller error mapping and HTTP tests for the legacy write guard, not just service tests.
4. **High: the reset-metadata section is internally inconsistent about documents that already have legacy field extractions.**
References:
- `plans/mutable.metadata.plan.combo.v3.md:643-653`
Impact:
- The behavior bullets say a legacy-extraction document “succeeds trivially.”
- The validation section says the same condition returns `409 Conflict`.
- The tracking doc appears to assume `409`, so the plan and tracker are not actually aligned.
Recommendation:
- Pick one behavior and update both docs. I recommend `409`, because it matches the mutual-exclusivity rule and avoids false-success responses on legacy documents.
5. **High: the custom-metadata versioning plan overstates its concurrency safety, especially on first write.**
References:
- Plan claim: `plans/mutable.metadata.plan.combo.v3.md:152-153`
- Tracking task: `plans/mutable.metadata.plan.combo.v3.tracking.md:239-245`
- Current legacy pattern: `internal/fieldextraction/service.go:70-100`
Impact:
- `SELECT ... FOR UPDATE` on the max-version row does not serialize the first write for a document, because there is no row to lock yet.
- Two concurrent first writes can still race and one will fail on `UNIQUE (document_id, version)`.
Recommendation:
- Decide on a real serialization strategy now:
- Lock the document row before version assignment, or
- Retry on unique-violation explicitly.
- Add a “concurrent first write” test to the tracker, not just a generic concurrency test.
6. **Medium: actor/audit provenance is underspecified and currently inconsistent with the plans audit goals.**
References:
- Request bodies still carry caller-supplied `createdBy`: `plans/mutable.metadata.plan.combo.v3.md:566-571`, `847-858`
- Tracking only explicitly extracts caller identity for reset: `plans/mutable.metadata.plan.combo.v3.tracking.md:431-447`, `502`
- Reset refers to a not-yet-defined “same log sink used by `AssignSchema` / `DeleteSchema`”: `plans/mutable.metadata.plan.combo.v3.md:638`, `1069`
Impact:
- If `created_by` is meant to be audit-authoritative, client-supplied JSON is not trustworthy.
- The tracker does not currently include the work to derive actor identity from auth context for schema create/update/delete, folder assign, or metadata writes.
- The audit sink itself is assumed rather than designed.
Recommendation:
- Decide now whether actor identity is authoritative or merely display metadata.
- If authoritative, derive it from auth context everywhere and add explicit tracking tasks.
- Define the concrete audit sink/API instead of leaving it implied.
## Bottom Line
I would not start implementation until Findings 1 and 2 are resolved. Findings 3 through 6 should be folded into the tracking doc before work starts, otherwise the implementation will either drift from the plan or discover these gaps mid-phase.