New canonical openspec/specs/service-storage/spec.md (28 reqs SS-101..128). Change-side delta + sync-report. web-ui + prometheus-charting canonicals untouched.
11 KiB
Sync Report — service-storage-harness
Phase: sync · Change:
service-storage-harness· Repo:/home/user/manageMode: file-backed (artifactStore: openspec). No source-code edits; only OpenSpec artifacts were written. Not committed (parent owns the commit). The change folder was not moved (that issdd-archive's job).
Status: SYNCED. A new canonical domain openspec/specs/service-storage/spec.md was created
from the verified change, and the change-side domain delta spec that unblocks the native status
engine's sync/archive gates is also in place.
1. Executive summary
The service-storage-harness change shipped a complete but flat openspec/changes/service-storage-harness/spec.md
(28 requirements, SS-101 … SS-128) with no per-domain delta spec under
openspec/changes/service-storage-harness/specs/<domain>/. sdd-sync requires a domain delta
spec; the flat spec alone does not satisfy the canonical-merge contract.
Verify already returned PASS (verdict in verify-report.md; all four gates green — backend
pytest 322 passed, ruff clean, frontend npm run build exit 0, npm run lint 0 errors).
Functional coverage was 28/28 fully PASS. The verify report's single CRITICAL was an archive
blocker (30 unchecked task checkboxes + missing apply-progress.md); apply-progress.md now exists
and reconciles the 35 tasks (the task tracker condition does not block sdd-sync of the green
code).
This sync reconciles the flat-spec-vs-domain-spec gap:
- Authored the missing change-side domain delta spec —
openspec/changes/service-storage-harness/specs/service-storage/spec.md— using a clean## ADDED Requirementsstructure that preserves the exact requirement IDs (SS-101 … SS-128) and text from the verified flatspec.md. This is what flips the native status engine'sspecsartifact from partial → done. - Synced the end-state into the canonical store —
openspec/specs/service-storage/spec.md— the actual sync target. Because the canonicalservice-storagedomain did not previously exist, the native helper rule applies: when the canonical spec does not exist, the change spec becomes the new canonical spec. The two files therefore carry identical requirement bodies (delta under## ADDED Requirements; canonical under## Requirements).
Domain name service-storage was chosen (per the dispatch brief) because it covers the full
new model: the lifecycle-only ServiceDataHarness layer, the qBittorrent store + client + widget
stack, and the MediaIndex migration that established the per-service storage pattern. It is distinct
from the existing canonical domains web-ui (MUI→shadcn migration) and prometheus-charting
(direct Prometheus metric visualization), neither of which was touched.
2. Structured status & actionContext findings
The native gentle-pi.sdd-status passed by the parent reports changeName: null with
blockedReasons: ["Change selection is ambiguous: mobile-responsive-parity, service-storage-harness, services-as-hub-ia."] because the engine auto-detected three active changes. This sync task was
explicitly assigned service-storage-harness; the ambiguity is a parent-resolution artifact
and does not block this phase (isNonAuthoritative: false).
artifactStore: openspec; change rootopenspec/changes/service-storage-harness/.- Artifacts present:
proposal.md,spec.md,design.md,tasks.md,verify-report.md,apply-progress.md. verify: PASS(verify-report verdict; gates green atc9404f0).actionContext:mode: repo-local,workspaceRoot: /home/user/manage,allowedEditRoots: ["/home/user/manage"],warnings: []. All three files written are inside the authoritative workspace / allowed edit roots. ✓relationships.sameDomainActiveChanges: [],collisions: []— no active same-domain collisions, so no archive/sync ordering decision was required.- The new
service-storagedomain is distinct from the existingweb-uiandprometheus-chartingcanonical domains; both were left untouched.
Post-sync structural change: openspec/changes/service-storage-harness/specs/service-storage/spec.md
now exists (hasDomainSpecs → true), resolving the missing-domain-spec condition that gated sync.
The flat spec.md is intentionally left in place as the authoritative planning artifact the
work was built against (the archive convention keeps flat specs too); it no longer triggers the
"flat spec without domain specs" condition now that a domain delta sits alongside it.
3. Domains synced & canonical files updated
| Domain | Change-side delta (source) | Canonical (sync target) | Action |
|---|---|---|---|
service-storage |
openspec/changes/service-storage-harness/specs/service-storage/spec.md |
openspec/specs/service-storage/spec.md |
NEW domain — ## ADDED Requirements copied into canonical as a new spec |
- Canonical file created:
openspec/specs/service-storage/spec.md(28 requirements). - Change-side delta created:
openspec/changes/service-storage-harness/specs/service-storage/spec.md(28 requirements, all## ADDED Requirements).
4. Requirement delta (ADDED / MODIFIED / REMOVED)
- ADDED (28) — all to the new
service-storagedomain (canonical did not exist pre-change). IDs and text preserved verbatim from the verified flatspec.md. Grouped logically:- ServiceDataHarness (lifecycle layer) — SS-101, SS-102, SS-103, SS-104
- QbittorrentSampleStore — SS-105, SS-106, SS-107
- QbittorrentClient — SS-108, SS-109, SS-110
- qBittorrent widget source adapter — SS-111, SS-112, SS-113, SS-114, SS-115
- qBittorrent frontend widgets — SS-116, SS-117, SS-118
- MediaIndex migration onto harness — SS-119, SS-120, SS-121, SS-122, SS-123, SS-124
- Cascade-delete wiring — SS-125, SS-126
- Test and build greenness — SS-127, SS-128
- MODIFIED (0) — none (new domain; no pre-existing canonical requirements to replace).
- REMOVED (0) — none.
- RENAMED (0) — none (RENAMED is intentionally unsupported by the native delta helper; not used).
5. Guardrails, approvals & destructive-sync assessment
- Same-domain collisions: none (
sameDomainActiveChanges: [],collisions: []). The newservice-storagedomain does not overlap the existingweb-uiorprometheus-chartingcanonical domains. No ordering decision was needed. - Destructive sync: not applicable. There are zero REMOVED requirements and zero large MODIFIED blocks (new domain; everything is ADDED). No destructive-sync parent approval was required beyond the explicit reconciliation instruction in the task.
- Legacy flat spec: detected pre-sync; resolved by adding the domain delta spec alongside it (the block condition is specifically "flat spec without domain specs"). The flat spec was left in place as a planning artifact.
web-ui/prometheus-chartingcanonical isolation: the existingopenspec/specs/web-ui/spec.md(MUI→shadcn rework) andopenspec/specs/prometheus-charting/spec.md(direct Prometheus charting) were not modified — verified untouched bygit status. The three domains are independent.
6. Validation / checks performed (file-backed, read-only)
Run from /home/user/manage (no source edits, no test re-runs — those are owned by verify and were
already green at c9404f0):
| Check | Command | Result |
|---|---|---|
| Canonical store populated | ls openspec/specs/service-storage/spec.md |
present ✓ |
| Change-side domain spec present | ls openspec/changes/service-storage-harness/specs/service-storage/spec.md |
present ✓ |
| Requirement-ID parity (flat ↔ delta ↔ canonical) | grep -oE 'SS-[0-9]+' all three files, sort -u |
28 == 28 == 28, identical IDs SS-101…SS-128 ✓ |
| Body-text parity (delta ↔ canonical) | diff of the ^### Requirement: region of both files |
identical ✓ |
| Delta is pure ADDED | count ## ADDED/MODIFIED/REMOVED/RENAMED Requirements |
ADDED=1, MODIFIED=0, REMOVED=0, RENAMED=0 ✓ (no destructive sync) |
| Other canonicals untouched | git status --porcelain openspec/specs/web-ui openspec/specs/prometheus-charting |
empty (not modified) ✓ |
| No edits outside openspec | git status --porcelain (filtered) |
only openspec/specs/service-storage/, openspec/changes/service-storage-harness/specs/, and this report added ✓ |
| Markdown validity | write-time lint | all three files "Markdown clean" ✓ |
7. Carry-over items for the archive summary
These verify-phase findings are non-blocking for sync and should land in the archive summary:
- [CRITICAL-process, archive-only] Unchecked task checkboxes. At verify time, 30
implementation/verification task checkboxes (§1.1–5.5) were unchecked and
apply-progress.mdwas missing.apply-progress.mdnow exists (created after the verify pass, reconciling all 35 tasks).sdd-archiveshould re-scan the native status engine to confirmtasks: done/applyProgress: presentbefore moving the change to archive, and tick any remaining unchecked boxes if needed. - [WARNING] Slice 2 over the 400-line review budget (~644 source insertions vs the 400-line
budget / ~350–400 forecast). Additive feature slice (3 widgets +
LineSeriesChartextraction + tests); boundary is exactly the qBit-widget feature, no scope creep. Nosize:exceptionrecorded; non-blocking — record the actual in the archive summary. - [INFO]
LineSeriesChart.test.tsxis smoke-only (asserts mount, not rendered<Line>series). Non-blocking coverage note. - [INFO] Stale generated
.pi-map.mdfiles predate the new modules (service_data.py,qbittorrent_store.py,clients/qbittorrent.py,Qbittorrent*.tsx,LineSeriesChart.tsx); not deliverable source. Regenerate viaproject_map_patch/project_map_validate.
8. Next recommended phase
→ sdd-archive (clean). Confirm the native status re-scan reports specs: done / sync: ready
/ archive: ready, then move the change to
openspec/changes/archive/2026-07-09-service-storage-harness, carrying over the items in §7 into
the archive summary. Do not commit or push — the parent owns the commit with explicit paths.
Appendix — Files written by this sync (OpenSpec only; no source code)
openspec/changes/service-storage-harness/specs/service-storage/spec.md— change-side domain delta (## ADDED Requirements), 28 requirements SS-101…SS-128.openspec/specs/service-storage/spec.md— canonical spec (new domain), 28 requirements.openspec/changes/service-storage-harness/sync-report.md— this report.