# WP09 Device Relations and Evidence-Bound Root Cause Implementation Plan > **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:** Build an auditable device relationship graph that connects assets, operational events, and quality issues, then returns root-cause candidates only when persisted evidence paths support them. **Architecture:** PostgreSQL remains the canonical source for operational events and typed evidence relations. Graph and root-cause responses are bounded projections calculated from canonical rows; Neo4j is not required for correctness. Root-cause analysis is deterministic and evidence-bound: it returns candidate paths and limitations, never an automatic causal verdict, repair, maintenance plan, or prediction. **Tech Stack:** Flask, SQLAlchemy/PostgreSQL, Alembic, Vue 2/Vuetify, ECharts, pytest, Node test runner. --- ## Scope and constraints - Cover `CAT-16`, `DQA-13`, the device-only portion of `DQA-14`, `OBS-09`, and `OBS-10`. `DQA-15` remains planned because WP09 does not generate repair actions. - Supported node kinds are `asset`, `event`, and `quality_issue`. - Supported event types are `alarm`, `fault`, `maintenance`, and `downtime`. - Supported directed relation types are `part_of`, `occurred_on`, `indicates`, `triggered`, `addresses`, `impacts`, `evidences`, and `related_to`. - Cause-to-effect relations are `indicates`, `triggered`, and `evidences`. Root-cause traversal follows those edges upstream and includes other relations only as context. - Import is immutable and idempotent by source identity. Reusing an identity with different content is a conflict, not an update. - Limit one import to 200 events and 500 relations; graph traversal to 3 hops, 100 nodes, and 200 edges. - Evidence is bounded and secret fields are rejected. Raw source rows, credentials, prompts, and unrestricted attributes are never returned. - Do not add predictive maintenance, remaining-life prediction, automatic repair, maintenance-plan generation, generic ticket integration, or an LLM causal conclusion. - Use targeted WP09 tests only; do not run the full repository regression suite. ## Task 1: Domain contract and deterministic analysis **Files:** - Create: `app/core/data_research/device_observability.py` - Modify: `app/core/data_research/errors.py` - Create: `tests/data_research/test_device_observability.py` - [x] Write failing tests for event normalization, secret rejection, immutable source identity, node existence, graph bounds, upstream cause traversal, supported candidates, and `insufficient_evidence`. - [x] Run `PYTHONPATH=. .venv/bin/pytest -q tests/data_research/test_device_observability.py` and confirm failures are caused by the missing WP09 service. - [x] Implement `OperationalEventRecord`, `EvidenceRelationRecord`, `GraphProjection`, `RootCauseAnalysis`, and `DeviceObservabilityService`. - [x] Return `analysis_status="supported_candidates"` only when at least one persisted upstream causal path exists; otherwise return `analysis_status="insufficient_evidence"` and the fixed conclusion `证据不足,无法确认根因`. - [x] Re-run the domain test until it passes. ## Task 2: Canonical persistence and migration **Files:** - Create: `app/core/data_research/device_observability_repository.py` - Modify: `app/models/data_research.py` - Create: `migrations/versions/20260729_350_device_observability.py` - Create: `tests/integration/test_device_observability_postgres.py` - [x] Write a failing PostgreSQL integration test for idempotent event import, conflicting identity rejection, validated polymorphic relations, bounded graph traversal, quality-issue anchors, and deterministic root-cause paths. - [x] Add `device_operational_events` with source identity, event type, asset/component references, severity, status, occurrence window, safe evidence, and content hash. - [x] Add `device_evidence_relations` with typed endpoints, relation type, safe evidence, source, and a unique edge identity. - [x] Implement repository lookups, bulk inserts, paginated event search, bounded adjacency reads, and node summaries. - [x] Apply migration `20260729_350` to the local PostgreSQL test database and run only the WP09 integration test. ## Task 3: Governed API and permission boundary **Files:** - Modify: `app/api/data_development/routes.py` - Modify: `app/core/system/permissions.py` - Modify: `tests/test_permission_matrix.py` - Create: `tests/data_research/test_device_observability_api.py` - [x] Write failing tests for the following contract: - `GET /api/development/v1/device-observability/events` - `POST /api/development/v1/device-observability/import` - `GET /api/development/v1/device-observability/graph` - `GET /api/development/v1/device-observability/root-cause` - [x] Add `device-observability:edit` to editor and admin roles. All reads require `governance:read`; import requires the new edit permission. - [x] Add serializers that expose bounded event, relation, graph, candidate, evidence-reference, and limitation fields. - [x] Keep root-cause analysis read-only and deterministic; do not persist a generated conclusion. - [x] Run only WP09 API and permission tests. ## Task 4: Device relationship and root-cause workbench **Files:** - Modify: `frontend/src/api/dataDevelopment.js` - Modify: `frontend/src/router/routes.js` - Modify: `frontend/src/views/dataGovernance/development/index.vue` - Create: `frontend/src/views/dataGovernance/development/deviceObservabilityModel.js` - Create: `frontend/src/views/dataGovernance/development/deviceObservability.vue` - Create: `frontend/tests/device-observability-model.test.mjs` - Create: `tests/data_research/test_device_observability_frontend_contract.py` - [x] Write failing model tests for event labels, node categories, graph conversion, analysis status, candidate path labels, and permission visibility. - [x] Add a viewer-safe page with event filters, anchor selection, bounded relationship graph, evidence table, root-cause candidate cards, and an explicit insufficient-evidence state. - [x] Add an editor-only import dialog for bounded event and relation evidence; present source identity and evidence fields without exposing credentials. - [x] Render the relationship graph with the existing ECharts graph component and show directed edge labels. - [x] Add the hidden route and the data-research-center entry. - [x] Run the Node model test and frontend contract test. ## Task 5: Release copy, architecture, and ledger **Files:** - Mirror backend changes under: `deployment/app/` - Mirror migration under: `deployment/migrations/versions/` - Modify: `docs/architecture/DATA_MODEL.md` - Regenerate: `docs/architecture/OPENAPI.yaml` - Modify: `docs/FUNCTION_MODULE_CENSUS_20260726.md` - Modify: `docs/DATAOPS_PHASE1_3_MONTH_WORK_PLAN_20260729.md` - Modify: `tests/test_architecture_artifacts.py` - [x] Document PostgreSQL authority, graph projection bounds, evidence-path semantics, and the prohibition on deterministic causal claims without evidence. - [x] Mark WP09 engineering status separately from enterprise operating-event and expert validation. - [x] Update `DQA-13`, device-only `DQA-14`, `DQA-15`, `OBS-09`, and `OBS-10` without overstating cross-product impact or AI completion. - [x] Regenerate OpenAPI and assert the WP09 endpoints and migration are represented. - [x] Verify each changed `app/` file is identical to its `deployment/app/` copy. ## Task 6: Targeted verification and stage commit - [x] Run WP09 domain, API, frontend contract, PostgreSQL integration, permission, and architecture tests only. - [x] Run Ruff only on changed Python files. - [x] Run ESLint only on changed frontend files and the Node model test. - [x] Build the frontend production bundle because the workbench and route changed. - [x] Apply migration through the container and verify `20260729_350 (head)`. - [x] Use the local browser to import a bounded alarm/fault/downtime evidence chain, render its graph, verify supported candidates, and verify a disconnected event returns `证据不足,无法确认根因`. - [x] Confirm browser console has no errors and the issue/quality pages still load through the unchanged navigation. - [x] Commit the verified WP09 change on `codex/dataops-phase1-equipment-governance`; do not push or deploy.