Phase 7 of the M8 consolidation plan — finishes the runLogged orchestration adoption, Notice consolidation, and ProcessLogView unification across the wizard stages.
runLogged adoption
ProcessRunSupport.runLogged now owns every running-flag transition (false → true → false) and log-reset decision; no caller pre-sets or manually resets its flag.
TargetWorkflowViewModel — removed the duplicate targenRunning/targenLog/printtargRunning/printtargLog pre-run assignments and the targen catch-block reset around the already-adopted helper.
CalibrationViewModel — generateTarget/computeCurves now use runLogged; the outer Task keeps its strong lifetime, and the original-basename restore on failure is unchanged.
ProfileWorkflowViewModel — createProfile/verifyProfile use runLogged; work closures return structured results ((profileURL, gamutURL) / (report, history)) so gating, navigation, and history/drift assignment stay outside. The running flag spans colprof + applycal + best-effort iccgamut, and profcheck report/history handling, matching prior UI behavior.
MeasurementWorkflowViewModel — finishAndAverage uses runLogged with a no-op resetLog so prior chartread logs are preserved; single-pass promotion and first-pass fallback semantics are unchanged.
Deleted duplicate raw lastError: String? channels on Profile and Calibration; process failures route through the wizard notice only (removed colprofLastError and the CalibrationView error section).
Measurement chartread error state is now chartreadNotice: Notice?, still rendered as chartreadLastError via notice.text/notice.kind.
Notice.Kind.accessibilityValue exposes info/warning/error; printNotificationIcon reports the print notice kind as its accessibility value (cancel = info, spool failure = error), and Stage 3's sticky finish notice gained the stable chartreadFinishNotice identifier/value.
ProcessLogView unification
Stage 3 and Stage 4 disclosures were replaced with ProcessLogView, preserving chartreadLogContainer/colprofLogContainer and adding inner chartreadLog/colprofLog IDs. Stage 1/2 copy is untouched.
Dataset import seam
TargetWorkflowViewModel.importMeasurementDataset(from:) is the new internal seam — the parameterless UI action still prompts via the open panel (or UI-test hook) and delegates. Unit tests now cover malformed (CGATSParseError) and missing-file (CocoaError) inputs without global environment mutation, reusing TestAppEnvironment from #82.
New coverage: runLogged success/failure contracts; two-pass MOCK_AVERAGE_FAIL=1 run asserting pass-1 promotion and the sticky chartreadFinishNotice error; printNotificationIcon kind values on cancel and spool failure; profile and calibration failure visibility through the wizard notice (with basename restore persisted to wizard_state.json).
Static checks clean: no printNoticeIsError/finishNoticeIsError, no ProcessRunSupport.logSink in view models, no Task { @MainActor } hops for log lines.
## Summary
Phase 7 of the M8 consolidation plan — finishes the `runLogged` orchestration adoption, Notice consolidation, and `ProcessLogView` unification across the wizard stages.
### `runLogged` adoption
`ProcessRunSupport.runLogged` now owns every running-flag transition (`false → true → false`) and log-reset decision; no caller pre-sets or manually resets its flag.
- **TargetWorkflowViewModel** — removed the duplicate `targenRunning`/`targenLog`/`printtargRunning`/`printtargLog` pre-run assignments and the targen catch-block reset around the already-adopted helper.
- **CalibrationViewModel** — `generateTarget`/`computeCurves` now use `runLogged`; the outer `Task` keeps its strong lifetime, and the original-basename restore on failure is unchanged.
- **ProfileWorkflowViewModel** — `createProfile`/`verifyProfile` use `runLogged`; work closures return structured results (`(profileURL, gamutURL)` / `(report, history)`) so gating, navigation, and history/drift assignment stay outside. The running flag spans colprof + applycal + best-effort iccgamut, and profcheck report/history handling, matching prior UI behavior.
- **MeasurementWorkflowViewModel** — `finishAndAverage` uses `runLogged` with a no-op `resetLog` so prior chartread logs are preserved; single-pass promotion and first-pass fallback semantics are unchanged.
### Notice consolidation
- `WizardViewModel.notice` remains the session-wide banner; print/finish notices stay sticky stage-local `Notice?` values.
- Deleted duplicate raw `lastError: String?` channels on Profile and Calibration; process failures route through the wizard notice only (removed `colprofLastError` and the CalibrationView error section).
- Measurement chartread error state is now `chartreadNotice: Notice?`, still rendered as `chartreadLastError` via `notice.text`/`notice.kind`.
- `Notice.Kind.accessibilityValue` exposes `info`/`warning`/`error`; `printNotificationIcon` reports the print notice kind as its accessibility value (cancel = `info`, spool failure = `error`), and Stage 3's sticky finish notice gained the stable `chartreadFinishNotice` identifier/value.
### ProcessLogView unification
Stage 3 and Stage 4 disclosures were replaced with `ProcessLogView`, preserving `chartreadLogContainer`/`colprofLogContainer` and adding inner `chartreadLog`/`colprofLog` IDs. Stage 1/2 copy is untouched.
### Dataset import seam
`TargetWorkflowViewModel.importMeasurementDataset(from:)` is the new internal seam — the parameterless UI action still prompts via the open panel (or UI-test hook) and delegates. Unit tests now cover malformed (`CGATSParseError`) and missing-file (`CocoaError`) inputs without global environment mutation, reusing `TestAppEnvironment` from #82.
### Gate
```
xcodegen generate --spec project.yml && xcodebuild test -scheme ICCery -destination 'platform=macOS' -derivedDataPath build/DerivedData-feat-80-process-run-notice-consolidation ARCHS='arm64 x86_64' ONLY_ACTIVE_ARCH=NO CODE_SIGNING_ALLOWED=YES CODE_SIGN_IDENTITY='-' -only-testing:ICCeryCoreTests/ProcessRunSupportTests -only-testing:ICCeryCoreTests/TargetWorkflowViewModelTests -only-testing:ICCeryUITests/Milestone2UITests -only-testing:ICCeryUITests/Milestone3UITests -only-testing:ICCeryUITests/Milestone4UITests -only-testing:ICCeryUITests/Milestone5UITests -only-testing:ICCeryUITests/Milestone6CalibrationUITests
```
**TEST SUCCEEDED** — 29 tests, 0 failures: ProcessRunSupportTests (2), TargetWorkflowViewModelTests (2), Milestone2UITests (12), Milestone3UITests (6), Milestone4UITests (3), Milestone5UITests (2), Milestone6CalibrationUITests (2).
New coverage: `runLogged` success/failure contracts; two-pass `MOCK_AVERAGE_FAIL=1` run asserting pass-1 promotion and the sticky `chartreadFinishNotice` error; `printNotificationIcon` kind values on cancel and spool failure; profile and calibration failure visibility through the wizard notice (with basename restore persisted to `wizard_state.json`).
Static checks clean: no `printNoticeIsError`/`finishNoticeIsError`, no `ProcessRunSupport.logSink` in view models, no `Task { @MainActor }` hops for log lines.
Refs #80
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Phase 7 of the M8 consolidation plan — finishes the
runLoggedorchestration adoption, Notice consolidation, andProcessLogViewunification across the wizard stages.runLoggedadoptionProcessRunSupport.runLoggednow owns every running-flag transition (false → true → false) and log-reset decision; no caller pre-sets or manually resets its flag.targenRunning/targenLog/printtargRunning/printtargLogpre-run assignments and the targen catch-block reset around the already-adopted helper.generateTarget/computeCurvesnow userunLogged; the outerTaskkeeps its strong lifetime, and the original-basename restore on failure is unchanged.createProfile/verifyProfileuserunLogged; work closures return structured results ((profileURL, gamutURL)/(report, history)) so gating, navigation, and history/drift assignment stay outside. The running flag spans colprof + applycal + best-effort iccgamut, and profcheck report/history handling, matching prior UI behavior.finishAndAverageusesrunLoggedwith a no-opresetLogso prior chartread logs are preserved; single-pass promotion and first-pass fallback semantics are unchanged.Notice consolidation
WizardViewModel.noticeremains the session-wide banner; print/finish notices stay sticky stage-localNotice?values.lastError: String?channels on Profile and Calibration; process failures route through the wizard notice only (removedcolprofLastErrorand the CalibrationView error section).chartreadNotice: Notice?, still rendered aschartreadLastErrorvianotice.text/notice.kind.Notice.Kind.accessibilityValueexposesinfo/warning/error;printNotificationIconreports the print notice kind as its accessibility value (cancel =info, spool failure =error), and Stage 3's sticky finish notice gained the stablechartreadFinishNoticeidentifier/value.ProcessLogView unification
Stage 3 and Stage 4 disclosures were replaced with
ProcessLogView, preservingchartreadLogContainer/colprofLogContainerand adding innerchartreadLog/colprofLogIDs. Stage 1/2 copy is untouched.Dataset import seam
TargetWorkflowViewModel.importMeasurementDataset(from:)is the new internal seam — the parameterless UI action still prompts via the open panel (or UI-test hook) and delegates. Unit tests now cover malformed (CGATSParseError) and missing-file (CocoaError) inputs without global environment mutation, reusingTestAppEnvironmentfrom #82.Gate
TEST SUCCEEDED — 29 tests, 0 failures: ProcessRunSupportTests (2), TargetWorkflowViewModelTests (2), Milestone2UITests (12), Milestone3UITests (6), Milestone4UITests (3), Milestone5UITests (2), Milestone6CalibrationUITests (2).
New coverage:
runLoggedsuccess/failure contracts; two-passMOCK_AVERAGE_FAIL=1run asserting pass-1 promotion and the stickychartreadFinishNoticeerror;printNotificationIconkind values on cancel and spool failure; profile and calibration failure visibility through the wizard notice (with basename restore persisted towizard_state.json).Static checks clean: no
printNoticeIsError/finishNoticeIsError, noProcessRunSupport.logSinkin view models, noTask { @MainActor }hops for log lines.Refs #80