Implemented sync capture backup operation semantics as requested. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #433
39 KiB
Feature Specification: Spec 362 - Sync, Capture, and Backup Operation Semantics
Feature Branch: 362-sync-capture-backup-operation-semantics
Created: 2026-06-07
Status: Draft
Type: OperationRun semantic hardening / operator-truth follow-through / no new persistence
Runtime posture: Extend the current OperationRun reconciliation path only for selected repo-real sync, capture, and backup run families. Reuse existing artifact or result truth. Do not introduce a new lifecycle table, queue family, or UI framework.
Input: User-provided draft in /Users/ahmeddarrazi/.codex/attachments/c6e1919f-3e04-4f47-b6a8-58c0fdc2ab82/pasted-text.txt plus repo inspection of Specs 358-361 and the current apps/platform runtime seams.
Dependencies And Historical Context
This package continues the current OperationRun truth line:
- Spec 358 - OperationRun Queue Truth Foundation established honest queued/running stale handling and explicitly deferred business-success reconciliation for sync, capture, backup, restore, and export families.
- Spec 359 - OperationRun Reconciliation Adapter Framework & Review Compose Adapter introduced one bounded adapter seam and review-compose-specific reconciliation while explicitly excluding report, evidence, sync, and backup adapters.
- Spec 360 - OperationRun Canonical Cutover Cleanup remains the canonical cutover context for dispatch/correlation and read-side cleanup. Its artifacts are context only here and must not be rewritten.
- Spec 361 - Report and Evidence Reconciliation Adapters added registry-backed reconciliation for
tenant.evidence.snapshot.generateandenvironment.review_pack.generatewhile explicitly keeping sync, backup, and restore families out of scope.
Current repo truth already supports this next slice:
App\Support\Operations\Reconciliation\OperationRunReconciliationRegistryexists and already hosts multiple real adapters.App\Support\OperationRunOutcomealready containspartially_succeededandblocked.App\Services\Inventory\InventorySyncServicealready records canonical coverage and result context forinventory.sync.App\Jobs\CaptureBaselineSnapshotJoband related baseline services already recordbaseline_snapshot_id, gap summaries, and summary counts forbaseline.capture.App\Jobs\RunBackupScheduleJobalready recordsbackup_schedule_id,backup_set_id, summary counts, and terminal backup outcomes forbackup.schedule.execute.
This spec therefore continues an active repo-real line instead of inventing a new planning direction.
Spec Candidate Check (mandatory - SPEC-GATE-001)
- Problem: Selected sync, capture, and backup run families still depend too heavily on technical completion or generic stale-run failure. When a job dies late, partially finishes, or never writes its final lifecycle update, operators can be left with a stale run that hides whether the system already captured usable truth, only partial truth, or a real blocked state.
- Today's failure:
inventory.syncalready persists coverage and error summaries, but stale or interrupted runs can still end as generic failed/stale truth instead of a truthful succeeded, partially succeeded, or blocked result backed by current coverage.baseline.capturealready records snapshot IDs, eligibility context, gap summaries, and summary counts, but the current reconciliation path does not promote those signals into a calm terminal outcome when the run itself becomes ambiguous.backup.schedule.executealready records schedule context, backup-set context, and terminal counters in the normal job path, but the stale-run reconciliation path still lacks a proof-based backup-specific truth contract.
- User-visible improvement: Operators can trust that the Operations hub and run detail pages say what actually happened for the selected families:
Succeededonly when completeness is proven.Partially succeededwhen usable output exists but some work failed or gaps remain.Blockedwhen configuration, eligibility, or capability truth prevented a meaningful run.Failedwhen no safe success or partial proof exists.
- Smallest enterprise-capable version:
- add bounded reconciliation for exactly three canonical families:
inventory.syncbaseline.capturebackup.schedule.execute
- extend the existing reconciliation-result contract to express
partially_succeededusing the existingOperationRunOutcomeenum - reuse only current repo-real proof paths and current operations/detail surfaces
- keep
policy.sync,backup_set.update, restore, and generic report families out of scope
- add bounded reconciliation for exactly three canonical families:
- Explicit non-goals:
- no new
OperationRunstatus or outcome family - no new table, artifact, queue family, or background worker contract
- no
policy.syncdirect adapter in this slice - no restore, review-compose, evidence-snapshot, or review-pack expansion
- no provider/onboarding redesign
- no dashboard or product-wide operations UX rewrite
- no customer portal or AI follow-through
- no new
- Permanent complexity imported: three bounded adapters, one bounded partial-success helper on the current reconciliation result if needed, focused Unit/Feature coverage, and one bounded Browser smoke. No new persistence, global framework, or semantic taxonomy is introduced.
- Why now: Specs 358, 359, and 361 explicitly deferred sync/capture/backup business semantics. The current runtime now exposes the registry, proof, and outcome seams needed to finish the next narrow slice without inventing new platform machinery.
- Why not local: A local fix in one job or one page would keep outcome truth inconsistent across the registry, scheduled reconciliation, notifications, and current operations surfaces. This must be expressed once in the canonical reconciliation path.
- Approval class: Core Enterprise.
- Red flags triggered: cross-surface monitoring truth and bounded adapter growth. Defense: scope stays on three existing families, uses existing
OperationRunOutcomevalues, forbids new persistence, and explicitly keeps weaker families fail-closed. - Score: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | Gesamt: 11/12
- Decision: approve.
Candidate Source And Completed-Spec Guardrail
- Candidate source:
- direct user-provided Spec 362 draft in
pasted-text.txt - repo-real follow-through after Specs 358, 359, and 361
- roadmap relationship: execution-truth maturity over the existing
OperationRunline, especially before broader counted-progress or fan-out UX expansion
- direct user-provided Spec 362 draft in
- Queue boundary:
docs/product/spec-candidates.mdstill marks the active queue as empty for auto-selection. This package is an intentional manual promotion from direct user input, not an automatic queue pick. - Completed-spec check result:
- no
specs/362-*package existed before this prep - Specs 358, 359, and 361 are treated as historical implementation context
- Spec 360 remains dependency context only; its package must not be rewritten or normalized here
- earlier manual-promotion product lanes such as Specs 264, 267, 274-277, 339, 341, 342, and 346 are already specced and therefore excluded from next-best-prep selection
- no
- Close alternatives deferred:
First Governed AI Runtime Consumer v1remains unspecced but is later-stage productization and less directly enabled by the current branch/runtime linepolicy.syncdirect reconciliation is deferred because current repo proof is weaker thaninventory.sync- broader counted-progress, phase, or activity-center work remains separate from terminal-outcome truth
- Smallest viable implementation slice: selected repo-real proof for
inventory.sync,baseline.capture, andbackup.schedule.executeonly, plus calm operations-surface fallout and explicit unsupported-family handling.
Summary
This feature makes selected sync, capture, and backup runs honest when technical lifecycle and business truth drift apart.
It does not claim that every long-running job can now auto-complete. It only allows current repo-backed proof to finalize selected families:
inventory.syncfrom coverage and result truthbaseline.capturefrom snapshot and gap truthbackup.schedule.executefrom backup-set and backup-summary truth
Where proof is incomplete or ambiguous, the feature must fail closed as partially_succeeded, blocked, failed, or not_reconciled instead of pretending success.
Roadmap Relationship
This slice belongs to the execution-truth line rather than the customer-review or productization backlog.
It sharpens terminal outcome semantics before any broader rollout of counted progress, fan-out progress, or calmer activity-center UX:
- it complements the repo's current progress and activity-truth candidate line
- it keeps terminal outcome semantics separate from progress semantics
- it avoids turning backup or sync product surfaces into false green states just because some artifact exists
Spec Scope Fields (mandatory)
- Scope: canonical-view plus environment-bound execution truth
- Primary Routes:
/admin/workspaces/{workspace}/operations/admin/workspaces/{workspace}/operations/{run}- current repo-real related detail surfaces only when a safe link already exists:
- inventory coverage and inventory-related detail routes
- baseline profile, baseline snapshot, and current baseline-related detail routes
- backup schedule, backup set, and backup-item detail routes
- Data Ownership:
operation_runsremain the only execution and reconciliation truthinventory_items.last_seen_operation_run_idandcontext.inventory.coverageremain inventory observation proofbaseline_snapshots, policy-version evidence, andcontext.baseline_capture.*remain baseline capture proofbackup_sets,backup_items, andcontext.backup_schedule_id/context.backup_set_idremain backup proof- no new persistence is introduced
- RBAC:
- existing workspace-first
OperationRunaccess remains authoritative - existing inventory, baseline, and backup detail/resource policies remain authoritative
- non-members and out-of-scope actors remain
404 - no new capability strings are introduced
- existing workspace-first
For canonical-view specs:
- Default filter behavior when tenant-context is active: the Operations hub remains workspace-scoped with explicit environment filters only; reconciliation must rely on the run's recorded scope, not remembered environment state or current page filters.
- Explicit entitlement checks preventing cross-tenant leakage: no adapter may reconcile to inventory, snapshot, or backup artifacts outside the run's workspace and managed environment, and no related-artifact link may bypass current scope-safe routes.
UI Surface Impact (mandatory - UI-COV-001)
- No UI surface impact
- Existing page changed
- New page/route added
- Navigation changed
- Filament panel/provider surface changed
- New modal/drawer/wizard/action added
- New table/form/state added
- Customer-facing surface changed
- Dangerous action changed
- Status/evidence/review presentation changed
- Workspace/environment context presentation changed
UI/Productization Coverage (mandatory when UI Surface Impact is not "No UI surface impact")
- Route/page/surface:
App\Filament\Pages\Monitoring\OperationsApp\Filament\Pages\Operations\TenantlessOperationRunViewer- current repo-real inventory, baseline, and backup detail surfaces only if outcome copy or related links change there
- Current or new page archetype: existing monitoring/detail family plus current artifact/detail families
- Design depth: Domain Pattern Surface
- Repo-truth level: repo-verified
- Existing pattern reused: current
OperationRunmonitoring family, current related-artifact links, current inventory/baseline/backup detail families - New pattern required: none; this is a truthful-outcome follow-through inside current families
- Screenshot required: no by default; one bounded Browser smoke is sufficient unless implementation proves a material first-screen hierarchy change
- Page audit required: no new page-report identity is required by default
- Customer-safe review required: no; touched copy remains operator-facing and diagnostic
- Dangerous-action review required: no; no new mutation surface is added
- Coverage files updated or explicitly not needed:
docs/ui-ux-enterprise-audit/route-inventory.mddocs/ui-ux-enterprise-audit/design-coverage-matrix.mddocs/ui-ux-enterprise-audit/page-reports/...docs/ui-ux-enterprise-audit/strategic-surfaces.mddocs/ui-ux-enterprise-audit/grouped-follow-up-candidates.mddocs/ui-ux-enterprise-audit/unresolved-pages.mdN/A - existing operations, inventory, baseline, and backup surface families already cover the reachable routes
- No-impact rationale when applicable: no new page family, navigation entry, or route family is added; the feature only adjusts terminal truth within current surfaces
Cross-Cutting / Shared Pattern Reuse (mandatory)
- Cross-cutting feature?: yes
- Interaction class(es): status messaging, action links, monitoring/detail explanation, related-artifact linkage
- Systems touched:
App\Services\OperationRunServiceApp\Services\Operations\OperationLifecycleReconcilerApp\Services\AdapterRunReconcilerApp\Support\Operations\Reconciliation\OperationRunReconciliationRegistryApp\Support\Operations\Reconciliation\ReconciliationResultApp\Support\OperationRunLinksApp\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter- current inventory, baseline, and backup proof helpers
- Existing pattern(s) to extend: current registry-backed reconciliation, current service-owned lifecycle writes, current operations/detail presenters, and current scope-safe related-artifact links
- Shared contract / presenter / builder / renderer to reuse:
OperationRunService::applyReconciliationResult(),OperationRun::reconciliation(),OperationRunLinks,ArtifactTruthPresenter,GovernanceRunDiagnosticSummaryBuilder, and current inventory/baseline/backup detail presenters - Why the existing shared path is sufficient or insufficient: the registry and write seam already exist, but they do not yet cover selected sync/capture/backup proof families or partial-success finalization.
- Allowed deviation and why: one small proof helper is allowed only if duplicated completeness checks across the three selected adapters become noisy. It must remain derived-only and local to
App\Support\Operations\Reconciliation\. - Consistency impact: outcome wording, summary counts, related links, and supported/unsupported-family boundaries must stay consistent across jobs, reconciliation commands, monitoring/detail surfaces, notifications, and current detail pages.
- Review focus: no second reconciliation write path, no generic "latest artifact exists" heuristics, no policy-sync widening, and no new persistence.
OperationRun UX Impact (mandatory)
- Touches OperationRun start/completion/link UX?: yes
- Shared OperationRun UX contract/layer reused: current
OperationRunService,OperationLifecycleReconciler, registry-backed reconciliation,OperationRunLinks, and existing monitoring/detail presenters - Delegated start/completion UX behaviors: existing queued toasts, run links, terminal notifications, and run-enqueued browser events remain unchanged
- Local surface-owned behavior that remains: wording and placement only
- Queued DB-notification policy: unchanged
- Terminal notification path: unchanged central lifecycle mechanism
- Exception required?: none
Provider Boundary / Platform Core Check (mandatory)
- Shared provider/platform boundary touched?: no new provider boundary is introduced
- Boundary classification: platform-core execution truth over current provider-backed data
- Seams affected: run lifecycle, current artifact/result truth, current scope-safe links
- Neutral platform terms preserved or introduced:
operation,reconciliation,coverage,snapshot,backup set,blocked,partially succeeded - Provider-specific semantics retained and why: only existing provider error codes or readiness reasons already recorded in current context remain visible secondarily
- Why this does not deepen provider coupling accidentally: the feature uses platform-owned outcome and artifact/result truth only; it does not add provider-specific persistence, provider-routing rules, or Graph render calls
- Follow-up path:
policy.syncdirect semantics, broader counted progress, and provider/onboarding guidance remain separate follow-ups
UI / Surface Guardrail Impact
| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / N/A Note |
|---|---|---|---|---|---|---|
| Operations hub selected run outcomes | yes | Native Filament + shared presenters | OperationRun monitoring family |
page, detail, URL-query | no | no new action family |
| Run detail selected family explanation | yes | Native Filament + shared presenters | OperationRun monitoring family |
detail | no | existing link model stays canonical |
| Inventory, baseline, and backup proof/detail surfaces | yes | Native Filament + shared detail helpers | related artifact/detail families | detail | no | only if outcome copy or links need alignment |
Decision-First Surface Role
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| Operations hub | Primary Decision Surface | Decide whether the selected run still needs follow-up | lifecycle, selected-family outcome, safe related proof, next action | raw failures, deep proof detail, timestamps | primary because operators clear run state from here | stays aligned to monitoring workflow | removes manual cross-checking across run and artifact pages |
| Run detail | Secondary Context Surface | Verify why the run ended as succeeded, partially succeeded, blocked, or failed | one calm explanation plus safe related proof link | full context payload and existing diagnostics | secondary because the run is already selected | stays aligned to detail workflow | keeps proof in one canonical place |
| Inventory/baseline/backup detail | Tertiary Evidence / Diagnostics | Inspect the artifact or result that justified the run outcome | current proof state | full detail, payloads, counters, existing diagnostics | tertiary because detail pages prove or explain the selected run | stays aligned to current detail workflows | avoids duplicating full proof truth in run rows |
Audience-Aware Disclosure
| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| Operations hub | operator-MSP, support-platform | run status, selected-family outcome, safe reason, one next action | counts, failure categories, timestamps after explicit reveal | raw context remains diagnostic-only on current host surfaces | Open operation or safe related proof link |
raw context and low-level provider detail | list row states the outcome once; later sections add proof only |
| Run detail | operator-MSP, support-platform | calm outcome explanation and safe proof summary | full reconciliation metadata and failures after explicit reveal | raw payloads stay secondary and host-gated | Open related proof when safe |
low-level payloads and support-only detail | no second conflicting default-visible summary |
| Inventory/baseline/backup detail | operator-MSP, support-platform | current proof truth that supports or limits the outcome | existing detail diagnostics after explicit reveal | raw provider or payload detail remains behind existing gates | Open related operation when safe |
payloads, fingerprints, and raw support context | detail pages add proof; they do not restate a competing run summary |
UI/UX Surface Classification
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Operations hub | Monitoring / Queue / Workbench | Read-only Registry / Report Surface | Open the run or its safe proof | row click to run detail | required | existing filters and contextual links only | unchanged | /admin/workspaces/{workspace}/operations |
/admin/workspaces/{workspace}/operations/{run} |
workspace route plus explicit environment filter | Operations / Operation | honest selected-family outcome | none |
| Run detail | Record / Detail / Monitoring | Diagnostics-first detail surface | Inspect safe proof and deeper diagnostics | canonical detail page | N/A | existing navigation and related links only | unchanged | /admin/workspaces/{workspace}/operations |
/admin/workspaces/{workspace}/operations/{run} |
run-owned workspace/environment scope | Operation | calm outcome plus proof summary | none |
| Inventory/baseline/backup detail | Record / Detail / Monitoring | Detail-first proof surface | Confirm whether the current proof really supports the outcome | canonical detail page | N/A | existing related links only | unchanged | existing family collection routes | existing family detail routes | current workspace/environment scope on host surface | Inventory / Baseline Snapshot / Backup Set | current proof truth | none |
Operator Surface Contract
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| Operations hub | MSP operator | Decide whether the run still needs attention | list/workbench | Did this selected sync/capture/backup run finish successfully, partially, get blocked, or truly fail? | lifecycle state, selected-family outcome, safe proof hint, next step | raw failures, timestamps, detailed summary counts | lifecycle, proof completeness, scope safety | none | existing inspect/open actions only | none |
| Run detail | MSP operator or support | Confirm why the run resolved that way | detail | What exact proof or missing proof drove the final outcome? | calm outcome explanation, proof summary, safe related link | raw reconciliation context, low-level failure detail | lifecycle, proof completeness, support state | none | open related proof when safe | none |
| Inventory/baseline/backup detail | MSP operator or support | Confirm the supporting proof | detail | Does the current proof really justify or limit the selected run outcome? | proof readiness, counts, gaps or failures summary | payloads, fingerprints, deeper host diagnostics | proof completeness, expiration or gaps, scope safety | none | open related operation when safe | none |
Proportionality Review (mandatory when structural complexity is introduced)
- New source of truth?: no
- New persisted entity/table/artifact?: no
- New abstraction?: yes, bounded adapters and possibly one small proof helper
- New enum/state/reason family?: no; reuse the existing
OperationRunOutcome::PartiallySucceededand current blocked/failed semantics - New cross-domain UI framework/taxonomy?: no
- Current operator problem: selected sync/capture/backup runs can remain stale or end with generic failure even when repo-real proof already shows success, partial success, or a blocked precondition.
- Existing structure is insufficient because: the current registry covers restore, review-compose, evidence snapshot, and review-pack truth, but not the selected families that already emit usable proof through current context and artifact models.
- Narrowest correct implementation: add exactly three bounded proof adapters plus a bounded partial-success helper if the current reconciliation result cannot express the existing enum value cleanly.
- Ownership cost: adapter maintenance, focused tests, and some monitoring/detail copy review. No migration, new artifact family, or new operator workflow is introduced.
- Alternative intentionally rejected: a generic "latest artifact exists" rule or a new lifecycle table was rejected because it would overclaim success, weaken scope safety, and import permanent complexity unrelated to the current release.
- Release truth: current-release truth
Compatibility posture
This feature assumes a pre-production environment.
Backward compatibility, legacy aliases, migration shims, historical fixture preservation, and compatibility-specific tests are out of scope unless explicitly required by the spec. Canonical current-release truth is preferred over preservation.
Testing / Lane / Runtime Impact (mandatory for runtime behavior changes)
- Test purpose / classification: Unit, Feature, Browser
- Validation lane(s): fast-feedback, confidence, browser
- Why this classification and these lanes are sufficient: proof and decision logic are cheapest in Unit coverage; run finalization, scope-safe related links, and current-family fallout require Feature coverage; one bounded Browser smoke is enough for changed operator wording on the existing Operations surfaces
- New or expanded test families: one explicit Spec 362 Unit/Feature family and one bounded Browser smoke
- Fixture / helper cost impact: moderate existing factory usage for
OperationRun,InventoryItem,BaselineSnapshot,BackupSet,BackupItem, and workspace/environment membership; no new expensive default fixtures should be introduced - Heavy-family visibility / justification: no heavy-governance family is added
- Special surface test profile: monitoring-state-page
- Standard-native relief or required special coverage: ordinary Feature coverage for existing Filament surfaces plus one bounded Browser smoke if visible copy changes
- Reviewer handoff: reviewers must confirm that partial success only lands when current proof is genuinely incomplete but usable, that blocked remains distinct from failed, that unsupported families stay out of scope, and that no new persistence or operation type slips into the implementation
- Budget / baseline / trend impact: none expected
- Escalation needed: document-in-feature if a weaker family such as
policy.syncstill needs a named follow-up; reject-or-split if implementation tries to widen into generic sync or backup taxonomy work - Active feature PR close-out entry: Guardrail / Smoke Coverage
- Planned validation commands:
cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Unit/Support/Operations/Reconciliation/Spec362SelectedFamilyRegistryResolutionTest.php tests/Unit/Support/Operations/Reconciliation/Spec362SelectedFamilyProofRulesTest.php tests/Unit/Support/Operations/Reconciliation/Spec359ReconciliationResultTest.php tests/Feature/Operations/Spec362*cd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Feature/MonitoringOperationsTest.php tests/Feature/Inventory/InventorySyncServiceTest.php tests/Feature/Inventory/RunInventorySyncJobTest.php tests/Feature/Baselines/BaselineCaptureTest.php tests/Feature/Baselines/BaselineCaptureGapClassificationTest.php tests/Feature/Baselines/BaselineCaptureAmbiguousMatchGapTest.php tests/Feature/BackupScheduling/RunBackupScheduleJobTest.php tests/Feature/Console/ReconcileBackupScheduleOperationRunsCommandTest.phpcd apps/platform && ./vendor/bin/sail php vendor/bin/pest tests/Browser/Spec362SyncCaptureBackupSemanticsSmokeTest.phpcd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
User Stories & Acceptance Scenarios
User Story 1 - Trust inventory sync outcomes (Priority: P1)
As an operator, I need inventory.sync runs to end with truthful terminal outcomes that match current coverage and error proof so I do not mistake a partial or blocked sync for a full success.
Independent Test: a queued/running/stale inventory.sync run finalizes to succeeded only when all attempted types are covered successfully, to partially succeeded when some types failed but usable coverage exists, and to blocked or failed when current repo proof shows a full precondition or execution failure.
Acceptance Scenarios:
- Given a stale
inventory.syncrun with current-scope coverage for every attempted type and no failure categories, When reconciliation evaluates it, Then the run endscompleted/succeeded. - Given a stale
inventory.syncrun with mixed coverage and recorded failed categories, When reconciliation evaluates it, Then the run endscompleted/partially_succeeded. - Given a stale
inventory.syncrun whose current proof shows only blocked or skipped execution reasons, When reconciliation evaluates it, Then the run endscompleted/blocked. - Given a stale
inventory.syncrun without trustworthy current-scope coverage or with wrong-scope evidence only, When reconciliation evaluates it, Then it must not auto-succeed.
User Story 2 - Trust baseline capture outcomes (Priority: P1)
As an operator, I need baseline.capture runs to distinguish complete capture, gap-limited capture, and blocked capture so baseline truth does not overclaim fidelity.
Independent Test: a queued/running/stale baseline.capture run finalizes to succeeded only when a current-scope snapshot exists with no capture gaps, to partially succeeded when a snapshot exists but capture gaps or fallback evidence remain, and to blocked or failed when no safe proof exists.
Acceptance Scenarios:
- Given a stale
baseline.capturerun with a current-scopebaseline_snapshot_idand zero gap count, When reconciliation evaluates it, Then the run endscompleted/succeeded. - Given a stale
baseline.capturerun with a current-scope snapshot but recorded capture gaps or meta fallback, When reconciliation evaluates it, Then the run endscompleted/partially_succeeded. - Given a stale
baseline.capturerun whose current context still proves inventory or scope eligibility was blocked, When reconciliation evaluates it, Then the run endscompleted/blocked. - Given a stale
baseline.capturerun without a current-scope snapshot and without safe blocked proof, When reconciliation evaluates it, Then it must end failed or remain unreconciled instead of succeeding.
User Story 3 - Trust backup schedule execution outcomes (Priority: P1)
As an operator, I need backup.schedule.execute runs to distinguish complete backup, partial backup, and blocked backup from current backup-set proof so backup history stays honest.
Independent Test: a queued/running/stale backup.schedule.execute run finalizes to succeeded only when the current backup set proves complete capture, to partially succeeded when usable backup artifacts exist with recorded failures, and to blocked or failed when current schedule or backup proof shows no meaningful successful backup.
Acceptance Scenarios:
- Given a stale
backup.schedule.executerun with a current-scope backup set and full successful counts, When reconciliation evaluates it, Then the run endscompleted/succeeded. - Given a stale
backup.schedule.executerun with a backup set plus recorded failed families or missing assignment capture, When reconciliation evaluates it, Then the run endscompleted/partially_succeeded. - Given a stale
backup.schedule.executerun whose current context proves the schedule was skipped or blocked before meaningful backup work, When reconciliation evaluates it, Then the run endscompleted/blocked. - Given a stale
backup.schedule.executerun with no usable backup set or wrong-scope backup proof, When reconciliation evaluates it, Then it must not auto-succeed.
User Story 4 - Keep weaker families honest (Priority: P2)
As an operator, I need weaker or more ambiguous families such as policy.sync and backup_set.update to stay unsupported in this slice so the system does not overclaim semantics it cannot yet prove.
Independent Test: unsupported families remain out of the adapter registry and continue to follow the current lifecycle paths unless a future spec adds stronger causal proof.
Functional Requirements
- FR-362-001: The reconciliation path MUST support only these canonical families in this slice:
inventory.syncbaseline.capturebackup.schedule.execute
- FR-362-002: The feature MUST NOT add a new
OperationRunoutcome family. If partial success is needed, it MUST reuseOperationRunOutcome::PartiallySucceeded. - FR-362-003:
inventory.syncmay auto-finalize as succeeded only when current repo proof shows full current-scope coverage of attempted types without failure categories. - FR-362-004:
inventory.syncmay auto-finalize as partially succeeded only when current repo proof shows usable coverage plus explicit failed or gap-like categories for some attempted types. - FR-362-005:
baseline.capturemay auto-finalize as succeeded only when a current-scope baseline snapshot exists and the current gap summary proves no capture gaps remain. - FR-362-006:
baseline.capturemay auto-finalize as partially succeeded only when a current-scope snapshot exists but the current gap summary or fallback proof shows incomplete capture. - FR-362-007:
backup.schedule.executemay auto-finalize as succeeded only when a current-scope backup set and its current summary counts prove complete backup work. - FR-362-008:
backup.schedule.executemay auto-finalize as partially succeeded only when a current-scope backup set exists and the current summary counts or failure proof show usable but incomplete backup output. - FR-362-009: Selected families may auto-finalize as blocked only when current repo proof shows a meaningful precondition stop before successful work was produced, such as eligibility, capability, configuration, scope, or lock failure. If usable success or partial-success proof exists,
succeededorpartially_succeededMUST take precedence overblocked. - FR-362-010: Ambiguous, wrong-scope, or missing proof MUST fail closed as
not_reconciled,blocked, orfaileddepending on what the current repo can safely prove. They MUST NOT become success. - FR-362-011: Selected-family reconciliation MUST continue to write lifecycle truth only through
OperationRunService. - FR-362-012: Current operator-facing monitoring/detail surfaces MUST explain selected-family outcomes calmly and keep raw diagnostics secondary.
- FR-362-013:
policy.sync,backup_set.update, restore, review-compose, evidence snapshot, review-pack, and generic report families MUST remain unchanged in this slice unless current repo truth proves they are already covered elsewhere.
Non-Functional Requirements
- NFR-362-001: No new schema, table, or persisted artifact may be introduced.
- NFR-362-002: No new panel, provider registration, global-search contract, or Filament asset strategy may be introduced.
- NFR-362-003: Reconciliation must stay scope-safe by workspace and managed environment and must not link to foreign artifacts.
- NFR-362-004: No Graph or provider HTTP calls may be introduced during page render.
- NFR-362-005: Tests must remain the narrowest honest proof: Unit plus Feature plus one bounded Browser smoke only if visible wording changes.
Edge Cases
- Legacy alias values must not reintroduce provider-prefixed or legacy-named types as separate semantic families.
- Current proof may exist but belong to a different workspace or environment; that case must fail closed.
- Multiple candidate artifacts or result records for the same run must not silently choose a winner without safe deterministic proof.
partially_succeededmust remain a terminal outcome distinct fromblockedandfailed; the UI must not flatten them into one generic caution state.- Existing direct job completion paths remain authoritative. The new adapters must not double-finalize already completed runs.
Risks
- A proof rule that is too permissive could overclaim success for incomplete backup or baseline output.
- A proof rule that is too strict could keep obviously completed runs stuck in generic failure or attention states.
- Selected-family proof may duplicate some existing job-local decisions if the adapter boundaries are not kept narrow.
Assumptions
- The current registry and correlation seams visible in
platform-devare authoritative enough for a bounded follow-through even though Spec 360 artifacts still exist as context. inventory.sync,baseline.capture, andbackup.schedule.executeremain the strongest current proof families among the sync/capture/backup line.policy.syncstill lacks a safe proof contract equal toinventory.sync, so it is intentionally excluded from the first slice.
Open Questions
No open question blocks preparation.
Implementation must still verify whether any remaining Spec 360 cutover delta is required for these adapters. If runtime inspection proves a missing canonical seam is still blocking, implementation must stop and split that prerequisite explicitly instead of widening Spec 362 silently.
Success Criteria
- Selected-family stale or interrupted runs no longer overclaim success or collapse into generic stale failure when stronger current proof exists.
- Operators can distinguish complete, partial, blocked, and failed outcomes on current operations surfaces without reading raw diagnostics first.
- Unsupported families remain explicit and fail-closed instead of silently drifting into heuristic success.
Acceptance Criteria
- AC-362-001:
inventory.sync,baseline.capture, andbackup.schedule.executeeach have a bounded proof-based reconciliation path. - AC-362-002: Partial success uses the existing
OperationRunOutcome::PartiallySucceededinstead of a new outcome family. - AC-362-003:
policy.sync,backup_set.update, restore, and generic report families remain out of scope and explicit. - AC-362-004: Existing operations/detail surfaces show calm, scope-safe outcome wording with diagnostics secondary.
- AC-362-005: Focused Unit, Feature, and bounded Browser coverage are defined in
tasks.mdand are sufficient to prove the slice.
Follow-Up Spec Candidates
policy.syncdirect operator-truth semantics after a stable proof contract exists- broader counted-progress and fan-out semantics over the current execution-truth line
- broader backup or restore outcome taxonomy only if current release truth proves that a shared family is needed