For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Generate explainable cross-source device-match candidates, govern manual or tightly gated automatic merges, and preserve complete rollback evidence without deleting source assets or source identities.
Architecture: PostgreSQL remains authoritative for match candidates, immutable reviews, merge events, and rollback events. A merge is a non-destructive canonical/member relationship: WP-04 asset rows, versions, and source mappings remain unchanged, while the active merge event determines the canonical asset and its grouped source identities. Deterministic rules generate the first production-ready candidates; governed AI proposals may enter the same lifecycle with provider, model, evidence, and confidence, but cannot auto-merge in WP-06.
Tech Stack: Flask, SQLAlchemy, PostgreSQL JSONB, Alembic, Vue 2, Vuetify, pytest.
[0, 1], and evidence UIDs.device-entities:review plus the unique accountable asset_manager for device_mapping/DEVICE_ENTITY_RESOLUTION may approve, reject, auto-merge, or roll back.0.98, requires the initiating actor to pass the accountable-manager gate, and writes the same review and merge evidence as a manual approval.device_assets, device_asset_source_mappings, or device_asset_versions.codex/dataops-phase1-equipment-governance; do not push or deploy remotely.Files:
app/core/data_research/device_entity_resolution.pyapp/core/data_research/errors.pytests/data_research/test_device_entity_resolution.pyInterfaces:
DeviceEntityCandidateRecord, DeviceEntityReviewRecord, DeviceEntityMergeRecord, and DeviceEntityRollbackRecord.score_device_pair(left, right), DeviceEntityResolutionService.generate, submit_ai_candidate, search, get, review, rollback, reviews, merges, and rollbacks.Repository boundary supplies assets with source mappings, open-pair lookup, candidate persistence, row locks, active canonical/member lookup, and immutable evidence append methods.
[x] Step 1: Write failing scoring and lifecycle tests
Cover hand-derived score literals, Unicode/case/spacing normalization, same-source and different-type rejection, bounded generation, duplicate-open-candidate suppression, required evidence, AI-provider requirements, secret rejection, manual approval, accountable-manager rejection, automatic-merge default-off, strict rule-only automatic merge, canonical/member conflicts, immutable reviews, and append-only rollback.
Run:
PYTHONPATH=. .venv/bin/pytest -q \
tests/data_research/test_device_entity_resolution.py
Expected: collection fails because device_entity_resolution does not exist.
Implement deterministic normalization and signal scoring without external model calls. Store explanations as a list of {signal, matched, weight, left, right} entries and evidence as bounded UID lists. Treat approval as an atomic review plus non-destructive merge event; reject invalid transitions and stale versions with 409.
Run the Task 1 test command and expect all domain tests to pass.
Files:
app/core/data_research/device_entity_repository.pyapp/models/data_research.pymigrations/versions/20260729_310_device_entity_resolution.pytests/test_database_migrations.pytests/integration/test_device_entity_resolution_postgres.pyInterfaces:
SqlAlchemyDeviceEntityResolutionRepository.device_entity_match_candidates, device_entity_match_reviews, device_entity_merge_events, and device_entity_merge_rollbacks.pending|merged|rejected|rolled_back; suggestion source is rule|ai|manual; review decision is approve|reject|auto_approve.Active membership is a merge event without a corresponding rollback event.
[x] Step 1: Write failing migration and real-PostgreSQL tests
Cover database constraints, pair lookup, bounded filters, row locks, multiple members under one canonical asset, single active canonical per member, merge snapshots, immutable review records, immutable rollback records, and cleanup limited to test-owned rows.
Run:
TEST_DATABASE_URL=postgresql+psycopg2://dataops:dataops-test-password@127.0.0.1:15432/dataops \
PYTHONPATH=. .venv/bin/pytest -q \
tests/test_database_migrations.py::test_device_entity_resolution_migration_is_non_destructive_and_reversible \
tests/integration/test_device_entity_resolution_postgres.py
Expected: failure because the migration and repository do not exist.
Use UUIDv7 identities, JSONB evidence/explanations/snapshots, a partial unique index for one open pair, transactional active-member conflict checks, and FOR UPDATE for review and rollback. Keep downgrade data-preserving.
Upgrade the isolated local database to 20260729_310, then rerun the Task 2 command with TEST_DATABASE_URL.
Files:
app/api/data_development/routes.pyapp/core/system/permissions.pytests/data_research/test_device_entity_resolution_api.pytests/test_permission_matrix.pyInterfaces:
Produces:
GET /api/development/v1/device-entities/candidatesPOST /api/development/v1/device-entities/candidates/generatePOST /api/development/v1/device-entities/candidatesGET /api/development/v1/device-entities/candidates/{candidate_uid}POST /api/development/v1/device-entities/candidates/{candidate_uid}/reviewGET /api/development/v1/device-entities/candidates/{candidate_uid}/reviewsGET /api/development/v1/device-entities/candidates/{candidate_uid}/mergesPOST /api/development/v1/device-entities/merges/{merge_uid}/rollbackGET /api/development/v1/device-entities/merges/{merge_uid}/rollbacks[x] Step 1: Write failing API and permission tests
Cover viewer reads, viewer write denial, editor generation/AI submission, editor review denial, admin platform permission plus accountable-manager runtime denial, safe bounded filters, automatic-merge feature flag serialization, review/merge/rollback evidence, and safe error envelopes.
Run:
PYTHONPATH=. .venv/bin/pytest -q \
tests/data_research/test_device_entity_resolution_api.py \
tests/test_permission_matrix.py
Expected: failure because the routes and dedicated permissions do not exist.
Add device-entities:edit to editor/admin and device-entities:review to admin. Reads remain on governance:read; /review and /rollback require the review permission, while the service repeats the unique accountable-manager runtime check for device_mapping/DEVICE_ENTITY_RESOLUTION.
Run the Task 3 command and expect all tests to pass.
Files:
frontend/src/api/dataDevelopment.jsfrontend/src/router/routes.jsfrontend/src/views/dataGovernance/development/index.vuefrontend/src/views/dataGovernance/development/deviceEntityResolution.vuefrontend/src/views/dataGovernance/development/deviceEntityResolutionModel.jsfrontend/tests/device-entity-resolution-model.test.mjsdocs/architecture/OPENAPI.yamldocs/architecture/DATA_MODEL.mddocs/FUNCTION_MODULE_CENSUS_20260726.mddocs/DATAOPS_PHASE1_3_MONTH_WORK_PLAN_20260729.mddeployment/app/ for the WP-06 backend subset.Interfaces:
Produces /data-governance/development/entity-resolution with candidate status filters, explainable signal comparison, evidence display, generate action, permission-aware approve/reject controls, canonical-asset selection, merge history, and rollback evidence.
[x] Step 1: Write failing frontend model tests
Cover status and source labels, confidence formatting, matched-signal summary, canonical/member selection, and permission-aware review/rollback decisions.
Run:
cd frontend
node --test tests/device-entity-resolution-model.test.mjs
Expected: failure because the frontend model module does not exist.
Add the development-center entry and responsive workbench. Keep candidate evidence and lifecycle visible to viewers; hide mutation actions without permissions; display that AI candidates always require manual review and that physical deduplication/survivorship remains outside WP-06.
Run:
.venv/bin/python scripts/generate_openapi.py \
--output docs/architecture/OPENAPI.yaml
Record SEM-15 and SEM-17 as engineering complete pending enterprise data acceptance. Record SEM-16 as partially built because deterministic high-confidence auto-merge is feature-gated and governed AI auto-merge remains intentionally disabled.
Run only the WP-06 domain, PostgreSQL, API, permission, migration, OpenAPI, frontend model, targeted lint, production build, release-copy parity, and local browser workflow. In the browser generate a cross-source candidate, inspect its score explanation, approve it as the accountable asset manager, confirm grouped identities, roll it back, and confirm zero console errors. Run git diff --check.
Create one independently reversible WP-06 engineering commit. Do not push.