New canonical openspec/specs/service-instance-scoping/spec.md (21 reqs PI-101..121). Change-side delta + sync-report. web-ui/prometheus-charting/ service-storage/service-credential-testing canonicals untouched.
12 KiB
Sync Report — per-instance-hook-scoping
Phase: sync · Change:
per-instance-hook-scoping· 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). The flatspec.mdwas left in place as the authoritative planning artifact.
Status: SYNCED. A new canonical domain openspec/specs/service-instance-scoping/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 per-instance-hook-scoping change shipped a complete but flat openspec/changes/per-instance-hook-scoping/spec.md
(21 requirements, PI-101 … PI-121) with no per-domain delta spec under
openspec/changes/per-instance-hook-scoping/specs/<domain>/. sdd-sync requires a domain delta
spec; the flat spec alone does not satisfy the canonical-merge contract (native status engine
reported specs: partial, blockedReasons: "domain specs are missing or partial" + "Legacy flat spec
is present without domain specs").
Verify already returned PASS (verdict in verify-report.md; all five gates green — backend
pytest 368 passed, ruff clean, frontend npm run build exit 0, npm run lint 0 errors,
npx vitest run 46 files / 165 tests passed). Functional coverage was 21/21 requirements satisfied
against source. The verify report's single CRITICAL was an archive blocker (17 unchecked task
checkboxes + missing apply-progress.md); per the dispatch brief, apply-progress.md has since been
reconciled and that 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/per-instance-hook-scoping/specs/service-instance-scoping/spec.md— using a pure## ADDED Requirementsstructure that preserves the exact requirement IDs (PI-101 … PI-121) and body text (including the per-requirement GIVEN/WHEN/THEN scenarios) 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-instance-scoping/spec.md— the actual sync target. Because the canonicalservice-instance-scopingdomain 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 carry identical requirement bodies (delta under## ADDED Requirements; canonical under## Requirements), verified identical for the requirement region.
Domain name service-instance-scoping was chosen (per the dispatch brief) because it names the
cross-cutting concern the change establishes: observability and backup service-type tabs/hooks must
scope to the operator-selected instance. It is distinct from the existing canonical domains
(web-ui, prometheus-charting, service-storage, service-credential-testing), none of which
were touched.
2. Structured status & actionContext findings
The native gentle-pi.sdd-status reports state: blocked, artifactStore: openspec,
taskProgress: 17/17 complete, applyState: blocked, and blockedReasons citing missing domain
specs + legacy flat spec present without domain specs. These blockers are artifact-hygiene, not
implementation gaps: the code is committed (3bc7ce5), all five gates are green, and 21/21
requirements pass against source. This sync resolves the missing-domain-spec condition; the
remaining applyState/checkbox hygiene is an archive-phase concern.
artifactStore: openspec; change rootopenspec/changes/per-instance-hook-scoping/.- Artifacts present:
proposal.md,spec.md(flat),design.md,tasks.md,verify-report.md,apply-progress.md. verify: PASS(verify-report verdict; gates green at3bc7ce5).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-instance-scopingdomain is distinct from the existingweb-ui,prometheus-charting,service-storage, andservice-credential-testingcanonical domains; all four were left untouched.
Post-sync structural change: openspec/changes/per-instance-hook-scoping/specs/service-instance-scoping/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-instance-scoping |
openspec/changes/per-instance-hook-scoping/specs/service-instance-scoping/spec.md |
openspec/specs/service-instance-scoping/spec.md |
NEW domain — ## ADDED Requirements copied into canonical as a new spec |
- Canonical file created:
openspec/specs/service-instance-scoping/spec.md(21 requirements). - Change-side delta created:
openspec/changes/per-instance-hook-scoping/specs/service-instance-scoping/spec.md(21 requirements, all## ADDED Requirements).
4. Requirement delta (ADDED / MODIFIED / REMOVED)
- ADDED (21) — all to the new
service-instance-scopingdomain (canonical did not exist pre-change). IDs and text preserved verbatim from the verified flatspec.md. Grouped logically:- Frontend hooks (serviceId param + queryKey) — PI-101, PI-102, PI-103, PI-104, PI-105, PI-106, PI-107
- API client functions (serviceId → query param) — PI-108, PI-109
- Backend backup endpoints (service_id filter) — PI-110, PI-111, PI-112
- Tabs pass instance.id (TODO comments removed) — PI-113, PI-114, PI-115, PI-116
- Non-regression (dashboard widgets, global hooks untouched) — PI-117
- Backward compatibility — PI-118
- Test + build greenness — PI-119, PI-120, PI-121
- 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-instance-scopingdomain does not overlap the existingweb-ui,prometheus-charting,service-storage, orservice-credential-testingcanonical 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 for this sync beyond the explicit reconciliation instruction in the dispatch brief.
- 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.
- Canonical isolation: the existing
openspec/specs/web-ui/spec.md,openspec/specs/prometheus-charting/spec.md,openspec/specs/service-storage/spec.md, andopenspec/specs/service-credential-testing/spec.mdwere not modified — verified untouched (see §6).
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 3bc7ce5):
| Check | Command | Result |
|---|---|---|
| Canonical store populated | ls openspec/specs/service-instance-scoping/spec.md |
present ✓ |
| Change-side domain spec present | ls openspec/changes/per-instance-hook-scoping/specs/service-instance-scoping/spec.md |
present ✓ |
| Requirement-ID parity (flat ↔ delta ↔ canonical) | grep -oE 'PI-[0-9]+' all three files, sort -u |
21 == 21 == 21, identical IDs PI-101…PI-121 ✓ |
| 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,prometheus-charting,service-storage,service-credential-testing}/ |
empty (not modified) ✓ |
| No edits outside openspec | git status --porcelain (filtered) |
only the three new OpenSpec files added; no source files touched ✓ |
| 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] Task-checkbox / apply-progress hygiene. At verify time, 17
implementation task checkboxes were unchecked and
apply-progress.mdwas missing. Per the dispatch brief,apply-progress.mdhas been reconciled (native status now reports 17/17 complete);sdd-archiveshould re-scan the native status engine to confirmapply: done/applyProgress: presentand tick any remaining unchecked boxes before moving the change to archive. - [INFO, NB-1] Spec↔design wording mismatch on PI-109 / PI-110. The flat spec literally lists
fetchBackupDashboard/get_backup_dashboardas in-scope for a new service param, while design decision 5 and tasks 1.5/1.9 deliberately exclude them (dashboard widget path; PI-117 risk). The implementation correctly follows the design. This delta/canonical preserved the flat spec text verbatim (PI-109 / PI-110 still mention the dashboard variants) per the sync fidelity rule (do not rewrite verified requirements during sync). Ifsdd-archivewants spec and design to agree, it can amend in a follow-up change; no functional defect. - [INFO, NB-2] Weak hook-test assertion (PI-121). The
useBackups.test.ts"different keys" assertion (expect(a).not.toBe(b)onrenderHookresult refs) is tautology-prone. The wiring is correct in source and the tab test is strong; recommend strengthening the hook test in a future pass. Non-blocking. - [INFO] Stale generated
.pi-map.mdfiles still reference the pre-change signatures (e.g.list_backup_jobs(self)withoutservice_id). Generated artifacts, not deliverable source; reconcile viaproject_map_patch/project_map_validatewhen convenient.
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/YYYY-MM-DD-per-instance-hook-scoping, 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/per-instance-hook-scoping/specs/service-instance-scoping/spec.md— change-side domain delta (## ADDED Requirements), 21 requirements PI-101…PI-121.openspec/specs/service-instance-scoping/spec.md— canonical spec (new domain), 21 requirements.openspec/changes/per-instance-hook-scoping/sync-report.md— this report.