@dailephd/my-frontend-observer 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +490 -479
  2. package/LICENSE +21 -21
  3. package/README.md +375 -365
  4. package/dist/application/projectCheckService.d.ts +6 -0
  5. package/dist/application/projectCheckService.js +8 -1
  6. package/dist/application/projectCheckService.js.map +1 -1
  7. package/dist/application/projectWorkflowService.d.ts +7 -2
  8. package/dist/application/projectWorkflowService.js +10 -3
  9. package/dist/application/projectWorkflowService.js.map +1 -1
  10. package/dist/cli.js +510 -510
  11. package/dist/viewer/index.html +13 -13
  12. package/dist/viewer/sw.js +1 -1
  13. package/docs/ARCHITECTURE.md +1394 -1385
  14. package/docs/CI_CD.md +349 -338
  15. package/docs/COMMANDS.md +1035 -1026
  16. package/docs/CONTRACTS.md +1971 -1960
  17. package/docs/CURRENT_STATE.md +1277 -1252
  18. package/docs/DEVELOPMENT.md +240 -237
  19. package/docs/DOCUMENTATION_PRESERVATION_POLICY.md +50 -50
  20. package/docs/PROJECT_DESCRIPTION.md +2248 -2224
  21. package/docs/PROJECT_MILESTONES.md +2681 -2558
  22. package/docs/PROJECT_OVERVIEW.md +200 -196
  23. package/docs/QUICKSTART.md +100 -100
  24. package/docs/RELEASE.md +37 -36
  25. package/docs/ROADMAP.md +1105 -1034
  26. package/docs/SECURITY.md +297 -297
  27. package/docs/WORKFLOWS.md +806 -796
  28. package/docs/plans/v0.10-implementation-plan.md +1509 -1509
  29. package/docs/plans/v0.8-implementation-plan.md +655 -655
  30. package/docs/plans/v0.8.1-cli-usability-patch-plan.md +505 -505
  31. package/docs/plans/v0.9-implementation-plan.md +1529 -1529
  32. package/docs/plans/v0.9.1-implementation-plan.md +468 -468
  33. package/docs/reports/v0.10-batch1-visual-change-workflow-foundation.md +102 -102
  34. package/docs/reports/v0.10-batch2-project-composition-check-recording.md +103 -103
  35. package/docs/reports/v0.10-batch3-viewer-visual-change-workspace.md +93 -93
  36. package/docs/reports/v0.10-batch4-actual-frontend-entry.md +59 -59
  37. package/docs/reports/v0.10-batch5-reference-driven-entry.md +238 -238
  38. package/docs/reports/v0.10-batch6-coding-agent-handoff.md +85 -85
  39. package/docs/reports/v0.10-batch7-correction-review-acceptance.md +145 -145
  40. package/docs/reports/v0.10-batch8-integrated-acceptance.md +109 -109
  41. package/docs/reports/v0.10-implementation-completeness-documentation-reconciliation.md +344 -344
  42. package/docs/reports/v0.10-pre-release-readiness.md +120 -120
  43. package/docs/reports/v0.10-release-preparation.md +70 -70
  44. package/docs/reports/v0.10.1-project-check-baseline-context-implementation.md +86 -0
  45. package/docs/reports/v0.7-bounded-fidelity-context-prompt7.md +243 -243
  46. package/docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md +497 -497
  47. package/docs/reports/v0.7-pre-release-readiness.md +337 -337
  48. package/docs/reports/v0.7-reference-binding-prompt5.md +223 -223
  49. package/docs/reports/v0.7-reference-compatibility-prompt4.md +234 -234
  50. package/docs/reports/v0.7-reference-correction-workflow-prompt8.md +222 -222
  51. package/docs/reports/v0.7-reference-fidelity-prompt6.md +216 -216
  52. package/docs/reports/v0.7-reference-foundation-prompt1.md +151 -151
  53. package/docs/reports/v0.7-reference-regions-prompt2.md +195 -195
  54. package/docs/reports/v0.7-reference-requirements-prompt3.md +217 -217
  55. package/docs/reports/v0.7-release-prep.md +423 -423
  56. package/docs/reports/v0.8-binding-fidelity-interaction-batch6.md +279 -279
  57. package/docs/reports/v0.8-bounded-context-correlation-batch7.md +233 -233
  58. package/docs/reports/v0.8-comparison-contract-inspection-batch4.md +279 -279
  59. package/docs/reports/v0.8-evidence-index-readers-batch2.md +247 -247
  60. package/docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md +741 -741
  61. package/docs/reports/v0.8-integrated-viewer-acceptance-batch8.md +128 -128
  62. package/docs/reports/v0.8-observation-svg-inspection-batch3.md +223 -223
  63. package/docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md +687 -687
  64. package/docs/reports/v0.8-reference-candidate-inspection-batch5.md +232 -232
  65. package/docs/reports/v0.8-viewer-runtime-pwa-batch1.md +278 -278
  66. package/docs/reports/v0.8.1-implementation-completeness-documentation-reconciliation.md +114 -114
  67. package/docs/reports/v0.8.1-prerelease-readiness-cross-platform-security-code-rot.md +170 -170
  68. package/docs/reports/v0.9-architecture-retrieval.md +14 -37
  69. package/docs/reports/v0.9-final-pre-release-readiness.md +209 -209
  70. package/docs/reports/v0.9-final-readiness-corrections.md +530 -530
  71. package/docs/reports/v0.9-pre-release-readiness.md +169 -169
  72. package/docs/reports/v0.9.1-batch1-pwa-hard-gate-isolation.md +359 -359
  73. package/docs/reports/v0.9.1-batch2-hard-gate-validation-integration.md +262 -262
  74. package/docs/reports/v0.9.1-pre-release-readiness.md +206 -206
  75. package/package.json +59 -59
package/docs/CI_CD.md CHANGED
@@ -1,338 +1,349 @@
1
- # CI/CD
2
-
3
- CI interprets `check` as PASS `0`, FAIL `1`, REVIEW_REQUIRED `2`, or BLOCKED `3`. The current package is `@dailephd/my-frontend-observer@0.10.0`; its CLI remains `my-frontend-observer`. Packed readiness installs one exact tarball and runs `runPackedViewerSmoke.mjs` as the single project/viewer smoke owner for `init`, `capture`, bounded `check --json` REVIEW_REQUIRED and unchanged-contract FAIL-to-PASS, alias-aware project `view`, and viewer security. `runPackedObservationSmoke.mjs` remains the lower-level legacy observation smoke.
4
-
5
- The same matrix now also runs `runPackedV010WorkflowSmoke.mjs`. It installs the
6
- same SHA-verified candidate into a clean consumer and exercises installed
7
- actual/reference workflow creation, activation, handoff, immutable correction
8
- attempts, PASS-only acceptance, project-aware Viewer discovery, and standalone
9
- read-only behavior. Its bounded summary is uploaded with the existing matrix
10
- summary artifact. The candidate job still owns exactly one `npm pack`; no
11
- second v0.10 candidate or matrix exists. Formal v0.10 exact-candidate readiness
12
- passed on Windows, Linux, and macOS.
13
- All four packed smokes, security checks, and PWA gates passed against the same
14
- candidate. Run 35789033295 records that readiness result.
15
-
16
- ## Gate isolation invariant
17
-
18
- Cross-platform/full-suite success does not by itself prove that a security or
19
- acceptance gate is independent. Any test explicitly labeled `HARD GATE`,
20
- `SECURITY GATE`, or `ACCEPTANCE GATE` must also be able to run from fresh
21
- state without relying on earlier test order, a previously warmed service-worker
22
- cache, a persistent browser profile from an earlier run, or another test's
23
- server/evidence setup.
24
-
25
- v0.9.1 applies this rule to the PWA server-down
26
- hard gate. `npm run test:pwa-hard-gate` runs that gate by itself. It is a
27
- separate required proof in addition to the normal full-file execution in
28
- `npm run test:browser` and `npm run test:security`.
29
-
30
- `npm run test:security` now ends with `npm run test:pwa-hard-gate`. The
31
- `candidate` job in `.github/workflows/pre-release-readiness.yml` already runs
32
- `npm run test:security`, so release-readiness candidate validation receives
33
- the isolated gate automatically. The workflow YAML did not need to change. The
34
- released v0.9.1 suite contains the corrected isolated gate. No production PWA
35
- regression was found.
36
-
37
- A GitHub Actions pre-release readiness workflow exists at
38
- `.github/workflows/pre-release-readiness.yml` (triggered manually via
39
- `workflow_dispatch`, by pushing a `validation/**` or `release/**` branch, or
40
- by a pull request into `master`). It has two phases:
41
-
42
- 1. **candidate** (Linux, Node 24): `npm ci`, install Chromium, typecheck,
43
- lint, `npm test`, `npm run test:browser`, `npm run test:security`,
44
- build, `npm run check:docs`, then `npm pack` to produce exactly one
45
- candidate tarball and its SHA-256, uploaded as build artifacts.
46
- 2. **matrix-smoke** (`windows-latest`, `ubuntu-latest`, `macos-latest`, all
47
- Node 24): each job downloads the *same* candidate tarball produced by the
48
- candidate job, independently recomputes and verifies its SHA-256 against
49
- the candidate job's hash (failing immediately on any mismatch - no job
50
- ever builds its own tarball), installs Chromium via the installed
51
- package's own Playwright dependency, and runs
52
- `scripts/ci/runPackedObservationSmoke.mjs` against the installed
53
- tarball: four real Chromium observations against a disposable local HTTP
54
- target - the legacy `--target` CSS shorthand, the structured
55
- `--targets-file` semantic-target path (`role`+accessible-name and `text`
56
- locators, landmark evidence), a `--scroll-scenario-file` `window-scroll-by`
57
- scenario, and a combined `--targets-file` + `--scroll-scenario-file`
58
- `target-scroll-by` scenario against a nested scrollable container - all
59
- asserting schema `1.2.0`, real scroll-position movement, derived
60
- scroll-owner evidence (`document`/`target:<name>`), scenario transition
61
- evidence, targets-file/scroll-scenario-file path privacy, and target
62
- immutability.
63
-
64
- This proves the same packaged candidate installs and performs a real
65
- observation - CSS-shorthand, semantic-target, and v0.3 scroll-scenario alike
66
- (both `window-scroll-by` and `target-scroll-by`) - on Windows, Linux, and
67
- macOS, not just in the source checkout.
68
-
69
- There is no automated npm publication and no automated GitHub Release
70
- creation - this workflow is readiness validation only. Package publication
71
- remains a separate, later, explicit release decision.
72
-
73
- ## v0.2 readiness coverage
74
-
75
- The packed-candidate readiness gap that previously existed for
76
- `--targets-file` has been closed: `scripts/ci/runPackedObservationSmoke.mjs`
77
- now exercises both the legacy CSS-shorthand path and the structured
78
- semantic `--targets-file` path in the same run, on every platform in the
79
- matrix. This was proven on `validation/v0.2-pre-release`
80
- (`2a0718c37cfe6988fc5d9852db455b99aa8238af`), GitHub Actions run
81
- `31537578062`, which passed on Windows, Linux, and macOS using one
82
- hash-verified candidate tarball.
83
-
84
- ## v0.3 readiness coverage
85
-
86
- The packed-candidate readiness gap that previously existed for the v0.3
87
- `--scroll-scenario-file` public interface - identified during the v0.3
88
- implementation-completeness audit as `V0_3_READINESS_VALIDATION_GAP_EXISTS`
89
- - has been closed: `scripts/ci/runPackedObservationSmoke.mjs` now also
90
- performs a real `window-scroll-by` observation and a real `target-scroll-by`
91
- observation (against a nested scrollable fixture container, combined with
92
- `--targets-file`) through the installed tarball, asserting schema `1.2.0`,
93
- actual scroll movement, `document`/`target:<name>` scroll-owner evidence
94
- with `derivedFrom` provenance, scenario transition evidence, and that
95
- neither the `--targets-file` nor the `--scroll-scenario-file` local path is
96
- ever persisted into the manifest - on every platform in the matrix, using
97
- the same single hash-verified candidate tarball as the legacy/semantic
98
- observations. This was proven on `validation/v0.3-pre-release`
99
- (`e59621c2fb5a6d74f491a63dc79ebe6e8b62c175`), GitHub Actions run
100
- `31591920744`, which passed on Windows, Linux, and macOS using one
101
- hash-verified candidate tarball (SHA-256
102
- `da6cbc18a98d005b84a2f12c06f5c01d390006b53c02176a6c9cdc6d9b9d24d0`) - the
103
- release candidate for `v0.3.0`.
104
-
105
- ## v0.4 readiness coverage
106
-
107
- The packed-candidate readiness gap that previously existed for the v0.4
108
- `compare` public command - identified during the v0.4 implementation/
109
- documentation audit as `V0_4_READINESS_VALIDATION_GAP_EXISTS` - has been
110
- closed: `scripts/ci/runPackedObservationSmoke.mjs` now also installs the
111
- candidate tarball, observes a deterministic before/after fixture through
112
- the installed `observe`, and runs the installed `compare` against both
113
- resulting artifacts, asserting (through the *installed package's own*
114
- exported `isValidComparisonArtifact`/`isValidObservationArtifact`, resolved
115
- from the consumer's own `node_modules` rather than the source checkout):
116
- comparison artifact kind/schema `1.0.0`, a `comparable` result with a real
117
- `moved`+`resized` target difference and a real relationship-family
118
- transition (`does-not-overlap`→`overlaps` and `left-of`→
119
- `horizontally-overlapping` simultaneously - the same pair the v0.4
120
- relationship-family matching regression concerns), an explicit
121
- `--config-file` non-causal dependency-evidence result, an `incomparable`
122
- result (differing viewport) with the expected blocking comparability
123
- reason and no fabricated ordinary differences, comparison-manifest path
124
- privacy (no absolute operational path leakage), retained (never copied)
125
- before/after screenshot references, a `manifest.json`-only comparison
126
- directory, and byte-identical source-observation manifests/screenshots
127
- before and after comparing - on every platform in the matrix, using the
128
- same single hash-verified candidate tarball as the legacy/semantic/scroll
129
- observations. This preserves every pre-existing v0.1-v0.3 packed
130
- observation proof unchanged and adds the v0.4 proof additively, in the same
131
- script and the same candidate, per the established same-candidate
132
- architecture (no second `npm pack`, no per-platform rebuild).
133
-
134
- ## v0.5 readiness coverage
135
-
136
- The packed-readiness coverage gap identified during the v0.5 implementation-
137
- completeness audit as `V0_5_READINESS_VALIDATION_GAP_EXISTS` - the packed
138
- candidate smoke exercised `observe`/`compare` but not `approve-baseline`/
139
- `save-change-contract`/`evaluate-contract` - has been **corrected locally**:
140
- `scripts/ci/runPackedObservationSmoke.mjs` now also installs the same
141
- candidate tarball, observes a deterministic navigation/workspace/rail
142
- fixture through the installed `observe`, and drives the complete installed
143
- `approve-baseline` → `save-change-contract` → `observe` (candidate) →
144
- `compare` → `evaluate-contract` sequence, proving both a fully successful
145
- contract change (overall `PASS`, `--enforce` still exits `0`) and the
146
- milestone-signature failure (a locally successful requested/expected-
147
- dependent change alongside a real protected right-rail regression and a
148
- real preserved navigation-clipping regression, overall `FAIL`) - including
149
- `--enforce` producing a nonzero exit for the identical `FAIL` evidence
150
- (`evaluationRequestId` and `clauseResults` unchanged), full source
151
- observation/comparison/contract-artifact immutability, no copied
152
- screenshots, and no repository-root artifact leakage. All product behavior
153
- under test is invoked through the installed tarball's own executable, never
154
- imported from the source checkout. This addition is exercised in every
155
- existing matrix lane (`windows-latest`, `ubuntu-latest`, `macos-latest`)
156
- because all three already invoke this same script against the same
157
- candidate tarball - no workflow YAML change was required.
158
-
159
- This correction has since been proven cross-platform on the validation
160
- branch `validation/v0.5-pre-release`, first tested at commit
161
- `90255a9175503664f3e65d4114ee205176b7040a`: GitHub Actions run
162
- [`31727856546`](https://github.com/dailephd/my-frontend-observer/actions/runs/31727856546)
163
- passed completely - the candidate job (Linux, Node 24) and all three
164
- `matrix-smoke` lanes (`windows-latest` Node v24.18.1, `ubuntu-latest` Node
165
- v24.19.0, `macos-latest` Node v24.18.0) - using one shared candidate
166
- tarball, `my-frontend-observer-0.4.0.tgz`, SHA-256
167
- `9533a53e475614cd80a29dfa8b0f85e533e3ad736596579f559479e90e78941a`,
168
- independently hash-verified by each of the three matrix lanes before any of
169
- them ran the smoke (no lane built its own tarball). Every lane's
170
- `smoke-summary.json` reported byte-identical v0.5 evidence: the installed
171
- candidate's `approve-baseline`/`save-change-contract`/`evaluate-contract`
172
- `--help` all present, a real successful contract change (overall `PASS`,
173
- `--enforce` exits `0`), and the real milestone-signature failure (requested/
174
- expected-dependent `pass`, protected/preserved `fail`, overall `FAIL`,
175
- identical `evaluationRequestId`/`clauseResults` with `--enforce` exiting `1`
176
- and without it exiting `0`), plus source-artifact immutability, no copied
177
- screenshot, no path leakage, and no repository-root leakage - alongside
178
- every pre-existing v0.1-v0.4 packed observe/compare/scroll assertion, still
179
- passing unchanged on all three platforms.
180
-
181
- ## v0.6 packed-candidate coverage (released as `0.6.0`)
182
-
183
- `.github/workflows/pre-release-readiness.yml`'s existing candidate-job steps
184
- (`npm test`, `npm run test:browser`, `npm run test:security`, `npm run
185
- build`, `npm run check:docs`) cover the v0.6 bounded-agent-context and
186
- correlation modules, since they are part of the same `src/`/`tests/unit/`
187
- tree exercised by `npm test`. `scripts/ci/runPackedObservationSmoke.mjs`
188
- (the matrix-smoke packed-candidate proof) now also exercises the installed
189
- package's bounded-agent-context and runtime/static correlation public
190
- export surface directly - bounded projection, adequacy, omission/
191
- truncation, deterministic request identity vs. fresh instance identity,
192
- `correlated`/`ambiguous`/`unavailable` correlation outcomes, v0.5
193
- scope-inheritance, schema validation, and input immutability - since v0.6
194
- adds no new CLI command and no disk artifact for the packed candidate to
195
- observe end-to-end; it is a programmatic export surface only (see
196
- `docs/CONTRACTS.md`). This closed the readiness gap identified during v0.6
197
- pre-release validation. The final pre-release candidate
198
- (`acd067247c447294a611f37f52eab301b6038ab1c6d493ae65e81c2f1279bfd7`) passed
199
- Windows, Linux, and macOS using that one hash-verified tarball (GitHub
200
- Actions run `32304059259`) before the `0.6.0` release below.
201
-
202
- ## v0.7 packed-candidate coverage (released as `0.7.0`)
203
-
204
- The v0.7 pre-release readiness stage identified the same class of gap
205
- `scripts/ci/runPackedObservationSmoke.mjs` had already closed for every
206
- prior version: the packed-candidate smoke exercised `observe`/`compare`/
207
- `approve-baseline`/`save-change-contract`/`evaluate-contract` and the v0.6
208
- bounded-agent-context/correlation exports, but none of v0.7's new surface.
209
- This was closed the same way as every prior version's gap - one narrow,
210
- additive extension to the existing script, never a second parallel
211
- framework: the installed candidate's `import-reference --help`/
212
- `approve-reference --help`/`evaluate-reference-fidelity --help`; a real
213
- external-reference image imported and approved through the installed CLI
214
- with explicit regions, three requirement kinds (`region-property`,
215
- `region-relationship`, and both `exact`/`absolute-reference-px` tolerance
216
- kinds), and a declared `applicability.viewport`; explicit region↔runtime-
217
- target bindings reusing the existing v0.5 contract-fixture geometry; a
218
- genuine fidelity `pass` and a genuine fidelity `fail` (each checked with and
219
- without `--enforce`, mirroring `evaluate-contract`'s own PASS/FAIL/
220
- `--enforce` proof pattern); an `observe --state-file` explicit-state
221
- round-trip; and the installed package's programmatic
222
- `evaluateReferenceCandidateFidelityFromArtifactRoots`/
223
- `prepareReferenceCorrection`/`reviewReferenceCorrectionAttempt` exports,
224
- including a `prepareReferenceCorrection` handoff carrying a bounded-agent-
225
- context artifact (exercising the v0.7 bounded fidelity projection and its
226
- v0.6 bounded-agent-context integration together) and both a `pass` and a
227
- `fail` `reviewReferenceCorrectionAttempt` outcome - all resolved from the
228
- installed package's own `node_modules`, never the source checkout, and all
229
- re-verified against a re-hash of the pre-existing source observation
230
- manifest to confirm none of the new calls mutated it.
231
-
232
- This was proven cross-platform on the validation branch
233
- `validation/v0.7-pre-release` at commit
234
- `b2286bdc9550d70fa1047a1f732968a8eca46a1e`: GitHub Actions run
235
- [`34054085344`](https://github.com/dailephd/my-frontend-observer/actions/runs/34054085344)
236
- passed completely - the candidate job (Linux, Node 24) and all three
237
- `matrix-smoke` lanes (`windows-latest` Node v24.19.0, `ubuntu-latest` Node
238
- v24.20.0, `macos-latest` Node v24.20.0) - using one shared **pre-version-
239
- bump implementation candidate** tarball, `my-frontend-observer-0.6.0.tgz`
240
- (package version still `0.6.0` at that point in the readiness stage - the
241
- version bump to `0.7.0` happened only afterward, during release
242
- preparation; this tarball itself was never version `0.7.0`), SHA-256
243
- `0347b1f3cfd5d311e13b405c0c2fbc2f507e250cb63223d58b4d2d31df029414`,
244
- independently hash-verified by each of the three matrix lanes before any of
245
- them ran the smoke (no lane built its own tarball). Every lane's
246
- `smoke-summary-<os>.json` reported the same v0.7 evidence described above,
247
- alongside every pre-existing v0.1-v0.6 packed assertion, still passing
248
- unchanged on all three platforms - see
249
- `docs/reports/v0.7-pre-release-readiness.md` for the complete readiness
250
- report.
251
-
252
- ## v0.8.1 packaging implications (released as `0.8.1`; formal cross-platform readiness passed)
253
-
254
- v0.8.1 is released as `@dailephd/my-frontend-observer@0.8.1` - see
255
- `docs/CURRENT_STATE.md`. `.github/workflows/pre-release-readiness.yml`'s
256
- matrix now covers it: alongside the pre-existing packed-observation smoke,
257
- each platform runner also installs the exact candidate tarball and runs
258
- `scripts/ci/runPackedViewerSmoke.mjs`, proving in real Chromium that the
259
- installed `view` command binds to loopback only, indexes real evidence,
260
- renders the SVG target overlay and a reference view, enforces its read-only
261
- API, rejects path traversal, registers its service worker, never caches
262
- `/api/` responses as authoritative, and never presents stale evidence once
263
- the server is stopped.
264
-
265
- `npm run build` builds both the Node/CLI output (`tsc -p tsconfig.json`) and
266
- the browser-side viewer application plus its PWA assets (`vite build
267
- --config viewer/vite.config.ts` into `dist/viewer` - service worker,
268
- manifest, precached app shell); the existing `files` package allowlist
269
- (`dist`, `README.md`, `CHANGELOG.md`, `docs`) already includes
270
- `dist/viewer`, so no separate publish boundary was created for the viewer;
271
- the existing CLI/library commands (`observe` through
272
- `evaluate-reference-fidelity`) remain packaged and unchanged; and package
273
- version stays independent of every schema version, as for every prior
274
- release.
275
-
276
- Formal Windows/Linux/macOS cross-platform validation - the same exact
277
- hash-verified candidate tarball on every platform - and a formal security
278
- audit (which found and fixed one real finding: a symlinked-media
279
- evidence-root escape in the viewer's media route) both passed before this
280
- release - see
281
- `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`
282
- for the complete readiness report.
283
-
284
- ## v0.9 packaging implications (released in 0.9.0; final cross-platform readiness passed)
285
-
286
- v0.9 visual annotation is released as `@dailephd/my-frontend-observer@0.9.0`.
287
- Final exact-candidate readiness passed on Windows, Linux and macOS - see
288
- `docs/reports/v0.9-final-pre-release-readiness.md`.
289
- `.github/workflows/pre-release-readiness.yml` keeps the same exact-candidate
290
- structure:
291
-
292
- 1. The `candidate` job runs once on Linux with Node 24. It runs every local
293
- validation command, builds the package, creates one tarball with
294
- `npm pack --json`, freezes its SHA-256, and uploads both.
295
- 2. The `matrix-smoke` job runs on `windows-latest`, `ubuntu-latest`, and
296
- `macos-latest` with Node 24. Each lane downloads that same tarball and
297
- fails if its SHA-256 differs.
298
- 3. Each lane installs the tarball into a clean consumer and runs three packed
299
- smokes in real Chromium:
300
- 1. `scripts/ci/runPackedObservationSmoke.mjs` (observation and low-level
301
- command behavior), writing `smoke-summary.json`;
302
- 2. `scripts/ci/runPackedViewerSmoke.mjs` (project workflow and
303
- project-aware viewer inspection), writing `viewer-smoke-summary.json`;
304
- 3. `scripts/ci/runPackedV09AnnotationSmoke.mjs` (v0.9 annotation), writing
305
- `v09-annotation-smoke-summary.json`.
306
- 4. All three summaries are uploaded as the `smoke-summary-<os>` artifact.
307
-
308
- The v0.9 annotation smoke uses only the installed package. It checks that the
309
- compiled v0.9 owners and the built viewer are in the tarball, that the bare
310
- package specifier and Playwright resolve inside the consumer's own
311
- `node_modules`, and that the public v0.9 exports resolve. It then runs
312
- `init`, `capture baseline`, and `check baseline --json`, and starts the
313
- project-aware `view` (viewer protocol `1.3.0`, authoring enabled). In real
314
- Chromium it saves and reloads a runtime annotation, promotes confirmed move
315
- intent into a canonical change contract, imports a reference with the
316
- installed `import-reference`, annotates it, and materializes a confirmed
317
- region into a new imported revision. That revision must supersede the source,
318
- reuse its exact image bytes, and not be approved. Finally it starts a
319
- standalone `view --root` session and proves it is read-only. The summary never
320
- contains the authoring token, absolute project paths, or note text.
321
-
322
- The standalone read-only proof for v0.9 authoring lives in the v0.9
323
- annotation smoke. The project-aware inspection and project workflow proof
324
- lives in the packed viewer smoke.
325
-
326
- A separate `tutorial-readiness` job runs on the same three operating systems.
327
- It builds Observer from the repository source and runs
328
- `scripts/run-v09-tutorial-readiness.mjs`, which validates and runs the four
329
- `examples/v09-demo/tutorials/` scenarios through the external tool
330
- `@dailephd/my-dev-kit-lab@0.4.9`, then reads the evidence each run wrote back
331
- through the canonical Observer readers. It fails unless every scenario passes
332
- with empty `cleanupErrors`, the tracked demo source is unchanged, and the
333
- repository status is unchanged. The demo and the lab are repository release
334
- support only. Neither is in the npm package or an Observer dependency.
335
-
336
- The v0.9 matrix wiring has not yet run in GitHub Actions for this candidate.
337
- The local Windows run of all three smokes against one exact tarball is
338
- recorded in `docs/reports/v0.9-batch7-integrated-acceptance.md`.
1
+ # CI/CD
2
+
3
+ CI interprets `check` as PASS `0`, FAIL `1`, REVIEW_REQUIRED `2`, or BLOCKED `3`. The current package is `@dailephd/my-frontend-observer@0.10.1`; its CLI remains `my-frontend-observer`. Packed readiness installs one exact tarball and runs `runPackedViewerSmoke.mjs` as the single project/viewer smoke owner for `init`, `capture`, bounded `check --json` REVIEW_REQUIRED and unchanged-contract FAIL-to-PASS, alias-aware project `view`, and viewer security. `runPackedObservationSmoke.mjs` remains the lower-level legacy observation smoke.
4
+
5
+ The Viewer/project smoke now also includes the v0.10.1 maintenance regression
6
+ against the installed candidate: it creates a canonical baseline with both
7
+ `scrollScenario` and caller-declared `explicitState`, keeps those fields out of
8
+ project configuration, and requires project `check <baseline> --json` to replay
9
+ them, execute the scroll, compare normally, and pass configured acceptance.
10
+ The v0.10.1 exact-candidate readiness passed in hosted run `37354455573`,
11
+ attempt 2 (7/7 jobs). Windows, Linux, and macOS consumed the same
12
+ SHA-verified candidate tarball, and the baseline-context replay passed on all
13
+ three matrix lanes.
14
+
15
+ The same matrix now also runs `runPackedV010WorkflowSmoke.mjs`. It installs the
16
+ same SHA-verified candidate into a clean consumer and exercises installed
17
+ actual/reference workflow creation, activation, handoff, immutable correction
18
+ attempts, PASS-only acceptance, project-aware Viewer discovery, and standalone
19
+ read-only behavior. Its bounded summary is uploaded with the existing matrix
20
+ summary artifact. The candidate job still owns exactly one `npm pack`; no
21
+ second v0.10 candidate or matrix exists. Formal v0.10 exact-candidate readiness
22
+ passed on Windows, Linux, and macOS.
23
+ All four packed smokes, security checks, and PWA gates passed against the same
24
+ candidate. Run 35789033295 records that readiness result.
25
+
26
+ ## Gate isolation invariant
27
+
28
+ Cross-platform/full-suite success does not by itself prove that a security or
29
+ acceptance gate is independent. Any test explicitly labeled `HARD GATE`,
30
+ `SECURITY GATE`, or `ACCEPTANCE GATE` must also be able to run from fresh
31
+ state without relying on earlier test order, a previously warmed service-worker
32
+ cache, a persistent browser profile from an earlier run, or another test's
33
+ server/evidence setup.
34
+
35
+ v0.9.1 applies this rule to the PWA server-down
36
+ hard gate. `npm run test:pwa-hard-gate` runs that gate by itself. It is a
37
+ separate required proof in addition to the normal full-file execution in
38
+ `npm run test:browser` and `npm run test:security`.
39
+
40
+ `npm run test:security` now ends with `npm run test:pwa-hard-gate`. The
41
+ `candidate` job in `.github/workflows/pre-release-readiness.yml` already runs
42
+ `npm run test:security`, so release-readiness candidate validation receives
43
+ the isolated gate automatically. The workflow YAML did not need to change. The
44
+ released v0.9.1 suite contains the corrected isolated gate. No production PWA
45
+ regression was found.
46
+
47
+ A GitHub Actions pre-release readiness workflow exists at
48
+ `.github/workflows/pre-release-readiness.yml` (triggered manually via
49
+ `workflow_dispatch`, by pushing a `validation/**` or `release/**` branch, or
50
+ by a pull request into `master`). It has two phases:
51
+
52
+ 1. **candidate** (Linux, Node 24): `npm ci`, install Chromium, typecheck,
53
+ lint, `npm test`, `npm run test:browser`, `npm run test:security`,
54
+ build, `npm run check:docs`, then `npm pack` to produce exactly one
55
+ candidate tarball and its SHA-256, uploaded as build artifacts.
56
+ 2. **matrix-smoke** (`windows-latest`, `ubuntu-latest`, `macos-latest`, all
57
+ Node 24): each job downloads the *same* candidate tarball produced by the
58
+ candidate job, independently recomputes and verifies its SHA-256 against
59
+ the candidate job's hash (failing immediately on any mismatch - no job
60
+ ever builds its own tarball), installs Chromium via the installed
61
+ package's own Playwright dependency, and runs
62
+ `scripts/ci/runPackedObservationSmoke.mjs` against the installed
63
+ tarball: four real Chromium observations against a disposable local HTTP
64
+ target - the legacy `--target` CSS shorthand, the structured
65
+ `--targets-file` semantic-target path (`role`+accessible-name and `text`
66
+ locators, landmark evidence), a `--scroll-scenario-file` `window-scroll-by`
67
+ scenario, and a combined `--targets-file` + `--scroll-scenario-file`
68
+ `target-scroll-by` scenario against a nested scrollable container - all
69
+ asserting schema `1.2.0`, real scroll-position movement, derived
70
+ scroll-owner evidence (`document`/`target:<name>`), scenario transition
71
+ evidence, targets-file/scroll-scenario-file path privacy, and target
72
+ immutability.
73
+
74
+ This proves the same packaged candidate installs and performs a real
75
+ observation - CSS-shorthand, semantic-target, and v0.3 scroll-scenario alike
76
+ (both `window-scroll-by` and `target-scroll-by`) - on Windows, Linux, and
77
+ macOS, not just in the source checkout.
78
+
79
+ There is no automated npm publication and no automated GitHub Release
80
+ creation - this workflow is readiness validation only. Package publication
81
+ remains a separate, later, explicit release decision.
82
+
83
+ ## v0.2 readiness coverage
84
+
85
+ The packed-candidate readiness gap that previously existed for
86
+ `--targets-file` has been closed: `scripts/ci/runPackedObservationSmoke.mjs`
87
+ now exercises both the legacy CSS-shorthand path and the structured
88
+ semantic `--targets-file` path in the same run, on every platform in the
89
+ matrix. This was proven on `validation/v0.2-pre-release`
90
+ (`2a0718c37cfe6988fc5d9852db455b99aa8238af`), GitHub Actions run
91
+ `31537578062`, which passed on Windows, Linux, and macOS using one
92
+ hash-verified candidate tarball.
93
+
94
+ ## v0.3 readiness coverage
95
+
96
+ The packed-candidate readiness gap that previously existed for the v0.3
97
+ `--scroll-scenario-file` public interface - identified during the v0.3
98
+ implementation-completeness audit as `V0_3_READINESS_VALIDATION_GAP_EXISTS`
99
+ - has been closed: `scripts/ci/runPackedObservationSmoke.mjs` now also
100
+ performs a real `window-scroll-by` observation and a real `target-scroll-by`
101
+ observation (against a nested scrollable fixture container, combined with
102
+ `--targets-file`) through the installed tarball, asserting schema `1.2.0`,
103
+ actual scroll movement, `document`/`target:<name>` scroll-owner evidence
104
+ with `derivedFrom` provenance, scenario transition evidence, and that
105
+ neither the `--targets-file` nor the `--scroll-scenario-file` local path is
106
+ ever persisted into the manifest - on every platform in the matrix, using
107
+ the same single hash-verified candidate tarball as the legacy/semantic
108
+ observations. This was proven on `validation/v0.3-pre-release`
109
+ (`e59621c2fb5a6d74f491a63dc79ebe6e8b62c175`), GitHub Actions run
110
+ `31591920744`, which passed on Windows, Linux, and macOS using one
111
+ hash-verified candidate tarball (SHA-256
112
+ `da6cbc18a98d005b84a2f12c06f5c01d390006b53c02176a6c9cdc6d9b9d24d0`) - the
113
+ release candidate for `v0.3.0`.
114
+
115
+ ## v0.4 readiness coverage
116
+
117
+ The packed-candidate readiness gap that previously existed for the v0.4
118
+ `compare` public command - identified during the v0.4 implementation/
119
+ documentation audit as `V0_4_READINESS_VALIDATION_GAP_EXISTS` - has been
120
+ closed: `scripts/ci/runPackedObservationSmoke.mjs` now also installs the
121
+ candidate tarball, observes a deterministic before/after fixture through
122
+ the installed `observe`, and runs the installed `compare` against both
123
+ resulting artifacts, asserting (through the *installed package's own*
124
+ exported `isValidComparisonArtifact`/`isValidObservationArtifact`, resolved
125
+ from the consumer's own `node_modules` rather than the source checkout):
126
+ comparison artifact kind/schema `1.0.0`, a `comparable` result with a real
127
+ `moved`+`resized` target difference and a real relationship-family
128
+ transition (`does-not-overlap`→`overlaps` and `left-of`→
129
+ `horizontally-overlapping` simultaneously - the same pair the v0.4
130
+ relationship-family matching regression concerns), an explicit
131
+ `--config-file` non-causal dependency-evidence result, an `incomparable`
132
+ result (differing viewport) with the expected blocking comparability
133
+ reason and no fabricated ordinary differences, comparison-manifest path
134
+ privacy (no absolute operational path leakage), retained (never copied)
135
+ before/after screenshot references, a `manifest.json`-only comparison
136
+ directory, and byte-identical source-observation manifests/screenshots
137
+ before and after comparing - on every platform in the matrix, using the
138
+ same single hash-verified candidate tarball as the legacy/semantic/scroll
139
+ observations. This preserves every pre-existing v0.1-v0.3 packed
140
+ observation proof unchanged and adds the v0.4 proof additively, in the same
141
+ script and the same candidate, per the established same-candidate
142
+ architecture (no second `npm pack`, no per-platform rebuild).
143
+
144
+ ## v0.5 readiness coverage
145
+
146
+ The packed-readiness coverage gap identified during the v0.5 implementation-
147
+ completeness audit as `V0_5_READINESS_VALIDATION_GAP_EXISTS` - the packed
148
+ candidate smoke exercised `observe`/`compare` but not `approve-baseline`/
149
+ `save-change-contract`/`evaluate-contract` - has been **corrected locally**:
150
+ `scripts/ci/runPackedObservationSmoke.mjs` now also installs the same
151
+ candidate tarball, observes a deterministic navigation/workspace/rail
152
+ fixture through the installed `observe`, and drives the complete installed
153
+ `approve-baseline` → `save-change-contract` → `observe` (candidate) →
154
+ `compare` → `evaluate-contract` sequence, proving both a fully successful
155
+ contract change (overall `PASS`, `--enforce` still exits `0`) and the
156
+ milestone-signature failure (a locally successful requested/expected-
157
+ dependent change alongside a real protected right-rail regression and a
158
+ real preserved navigation-clipping regression, overall `FAIL`) - including
159
+ `--enforce` producing a nonzero exit for the identical `FAIL` evidence
160
+ (`evaluationRequestId` and `clauseResults` unchanged), full source
161
+ observation/comparison/contract-artifact immutability, no copied
162
+ screenshots, and no repository-root artifact leakage. All product behavior
163
+ under test is invoked through the installed tarball's own executable, never
164
+ imported from the source checkout. This addition is exercised in every
165
+ existing matrix lane (`windows-latest`, `ubuntu-latest`, `macos-latest`)
166
+ because all three already invoke this same script against the same
167
+ candidate tarball - no workflow YAML change was required.
168
+
169
+ This correction has since been proven cross-platform on the validation
170
+ branch `validation/v0.5-pre-release`, first tested at commit
171
+ `90255a9175503664f3e65d4114ee205176b7040a`: GitHub Actions run
172
+ [`31727856546`](https://github.com/dailephd/my-frontend-observer/actions/runs/31727856546)
173
+ passed completely - the candidate job (Linux, Node 24) and all three
174
+ `matrix-smoke` lanes (`windows-latest` Node v24.18.1, `ubuntu-latest` Node
175
+ v24.19.0, `macos-latest` Node v24.18.0) - using one shared candidate
176
+ tarball, `my-frontend-observer-0.4.0.tgz`, SHA-256
177
+ `9533a53e475614cd80a29dfa8b0f85e533e3ad736596579f559479e90e78941a`,
178
+ independently hash-verified by each of the three matrix lanes before any of
179
+ them ran the smoke (no lane built its own tarball). Every lane's
180
+ `smoke-summary.json` reported byte-identical v0.5 evidence: the installed
181
+ candidate's `approve-baseline`/`save-change-contract`/`evaluate-contract`
182
+ `--help` all present, a real successful contract change (overall `PASS`,
183
+ `--enforce` exits `0`), and the real milestone-signature failure (requested/
184
+ expected-dependent `pass`, protected/preserved `fail`, overall `FAIL`,
185
+ identical `evaluationRequestId`/`clauseResults` with `--enforce` exiting `1`
186
+ and without it exiting `0`), plus source-artifact immutability, no copied
187
+ screenshot, no path leakage, and no repository-root leakage - alongside
188
+ every pre-existing v0.1-v0.4 packed observe/compare/scroll assertion, still
189
+ passing unchanged on all three platforms.
190
+
191
+ ## v0.6 packed-candidate coverage (released as `0.6.0`)
192
+
193
+ `.github/workflows/pre-release-readiness.yml`'s existing candidate-job steps
194
+ (`npm test`, `npm run test:browser`, `npm run test:security`, `npm run
195
+ build`, `npm run check:docs`) cover the v0.6 bounded-agent-context and
196
+ correlation modules, since they are part of the same `src/`/`tests/unit/`
197
+ tree exercised by `npm test`. `scripts/ci/runPackedObservationSmoke.mjs`
198
+ (the matrix-smoke packed-candidate proof) now also exercises the installed
199
+ package's bounded-agent-context and runtime/static correlation public
200
+ export surface directly - bounded projection, adequacy, omission/
201
+ truncation, deterministic request identity vs. fresh instance identity,
202
+ `correlated`/`ambiguous`/`unavailable` correlation outcomes, v0.5
203
+ scope-inheritance, schema validation, and input immutability - since v0.6
204
+ adds no new CLI command and no disk artifact for the packed candidate to
205
+ observe end-to-end; it is a programmatic export surface only (see
206
+ `docs/CONTRACTS.md`). This closed the readiness gap identified during v0.6
207
+ pre-release validation. The final pre-release candidate
208
+ (`acd067247c447294a611f37f52eab301b6038ab1c6d493ae65e81c2f1279bfd7`) passed
209
+ Windows, Linux, and macOS using that one hash-verified tarball (GitHub
210
+ Actions run `32304059259`) before the `0.6.0` release below.
211
+
212
+ ## v0.7 packed-candidate coverage (released as `0.7.0`)
213
+
214
+ The v0.7 pre-release readiness stage identified the same class of gap
215
+ `scripts/ci/runPackedObservationSmoke.mjs` had already closed for every
216
+ prior version: the packed-candidate smoke exercised `observe`/`compare`/
217
+ `approve-baseline`/`save-change-contract`/`evaluate-contract` and the v0.6
218
+ bounded-agent-context/correlation exports, but none of v0.7's new surface.
219
+ This was closed the same way as every prior version's gap - one narrow,
220
+ additive extension to the existing script, never a second parallel
221
+ framework: the installed candidate's `import-reference --help`/
222
+ `approve-reference --help`/`evaluate-reference-fidelity --help`; a real
223
+ external-reference image imported and approved through the installed CLI
224
+ with explicit regions, three requirement kinds (`region-property`,
225
+ `region-relationship`, and both `exact`/`absolute-reference-px` tolerance
226
+ kinds), and a declared `applicability.viewport`; explicit region↔runtime-
227
+ target bindings reusing the existing v0.5 contract-fixture geometry; a
228
+ genuine fidelity `pass` and a genuine fidelity `fail` (each checked with and
229
+ without `--enforce`, mirroring `evaluate-contract`'s own PASS/FAIL/
230
+ `--enforce` proof pattern); an `observe --state-file` explicit-state
231
+ round-trip; and the installed package's programmatic
232
+ `evaluateReferenceCandidateFidelityFromArtifactRoots`/
233
+ `prepareReferenceCorrection`/`reviewReferenceCorrectionAttempt` exports,
234
+ including a `prepareReferenceCorrection` handoff carrying a bounded-agent-
235
+ context artifact (exercising the v0.7 bounded fidelity projection and its
236
+ v0.6 bounded-agent-context integration together) and both a `pass` and a
237
+ `fail` `reviewReferenceCorrectionAttempt` outcome - all resolved from the
238
+ installed package's own `node_modules`, never the source checkout, and all
239
+ re-verified against a re-hash of the pre-existing source observation
240
+ manifest to confirm none of the new calls mutated it.
241
+
242
+ This was proven cross-platform on the validation branch
243
+ `validation/v0.7-pre-release` at commit
244
+ `b2286bdc9550d70fa1047a1f732968a8eca46a1e`: GitHub Actions run
245
+ [`34054085344`](https://github.com/dailephd/my-frontend-observer/actions/runs/34054085344)
246
+ passed completely - the candidate job (Linux, Node 24) and all three
247
+ `matrix-smoke` lanes (`windows-latest` Node v24.19.0, `ubuntu-latest` Node
248
+ v24.20.0, `macos-latest` Node v24.20.0) - using one shared **pre-version-
249
+ bump implementation candidate** tarball, `my-frontend-observer-0.6.0.tgz`
250
+ (package version still `0.6.0` at that point in the readiness stage - the
251
+ version bump to `0.7.0` happened only afterward, during release
252
+ preparation; this tarball itself was never version `0.7.0`), SHA-256
253
+ `0347b1f3cfd5d311e13b405c0c2fbc2f507e250cb63223d58b4d2d31df029414`,
254
+ independently hash-verified by each of the three matrix lanes before any of
255
+ them ran the smoke (no lane built its own tarball). Every lane's
256
+ `smoke-summary-<os>.json` reported the same v0.7 evidence described above,
257
+ alongside every pre-existing v0.1-v0.6 packed assertion, still passing
258
+ unchanged on all three platforms - see
259
+ `docs/reports/v0.7-pre-release-readiness.md` for the complete readiness
260
+ report.
261
+
262
+ ## v0.8.1 packaging implications (released as `0.8.1`; formal cross-platform readiness passed)
263
+
264
+ v0.8.1 is released as `@dailephd/my-frontend-observer@0.8.1` - see
265
+ `docs/CURRENT_STATE.md`. `.github/workflows/pre-release-readiness.yml`'s
266
+ matrix now covers it: alongside the pre-existing packed-observation smoke,
267
+ each platform runner also installs the exact candidate tarball and runs
268
+ `scripts/ci/runPackedViewerSmoke.mjs`, proving in real Chromium that the
269
+ installed `view` command binds to loopback only, indexes real evidence,
270
+ renders the SVG target overlay and a reference view, enforces its read-only
271
+ API, rejects path traversal, registers its service worker, never caches
272
+ `/api/` responses as authoritative, and never presents stale evidence once
273
+ the server is stopped.
274
+
275
+ `npm run build` builds both the Node/CLI output (`tsc -p tsconfig.json`) and
276
+ the browser-side viewer application plus its PWA assets (`vite build
277
+ --config viewer/vite.config.ts` into `dist/viewer` - service worker,
278
+ manifest, precached app shell); the existing `files` package allowlist
279
+ (`dist`, `README.md`, `CHANGELOG.md`, `docs`) already includes
280
+ `dist/viewer`, so no separate publish boundary was created for the viewer;
281
+ the existing CLI/library commands (`observe` through
282
+ `evaluate-reference-fidelity`) remain packaged and unchanged; and package
283
+ version stays independent of every schema version, as for every prior
284
+ release.
285
+
286
+ Formal Windows/Linux/macOS cross-platform validation - the same exact
287
+ hash-verified candidate tarball on every platform - and a formal security
288
+ audit (which found and fixed one real finding: a symlinked-media
289
+ evidence-root escape in the viewer's media route) both passed before this
290
+ release - see
291
+ `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`
292
+ for the complete readiness report.
293
+
294
+ ## v0.9 packaging implications (released in 0.9.0; final cross-platform readiness passed)
295
+
296
+ v0.9 visual annotation is released as `@dailephd/my-frontend-observer@0.9.0`.
297
+ Final exact-candidate readiness passed on Windows, Linux and macOS - see
298
+ `docs/reports/v0.9-final-pre-release-readiness.md`.
299
+ `.github/workflows/pre-release-readiness.yml` keeps the same exact-candidate
300
+ structure:
301
+
302
+ 1. The `candidate` job runs once on Linux with Node 24. It runs every local
303
+ validation command, builds the package, creates one tarball with
304
+ `npm pack --json`, freezes its SHA-256, and uploads both.
305
+ 2. The `matrix-smoke` job runs on `windows-latest`, `ubuntu-latest`, and
306
+ `macos-latest` with Node 24. Each lane downloads that same tarball and
307
+ fails if its SHA-256 differs.
308
+ 3. Each lane installs the tarball into a clean consumer and runs three packed
309
+ smokes in real Chromium:
310
+ 1. `scripts/ci/runPackedObservationSmoke.mjs` (observation and low-level
311
+ command behavior), writing `smoke-summary.json`;
312
+ 2. `scripts/ci/runPackedViewerSmoke.mjs` (project workflow and
313
+ project-aware viewer inspection), writing `viewer-smoke-summary.json`;
314
+ 3. `scripts/ci/runPackedV09AnnotationSmoke.mjs` (v0.9 annotation), writing
315
+ `v09-annotation-smoke-summary.json`.
316
+ 4. All three summaries are uploaded as the `smoke-summary-<os>` artifact.
317
+
318
+ The v0.9 annotation smoke uses only the installed package. It checks that the
319
+ compiled v0.9 owners and the built viewer are in the tarball, that the bare
320
+ package specifier and Playwright resolve inside the consumer's own
321
+ `node_modules`, and that the public v0.9 exports resolve. It then runs
322
+ `init`, `capture baseline`, and `check baseline --json`, and starts the
323
+ project-aware `view` (viewer protocol `1.3.0`, authoring enabled). In real
324
+ Chromium it saves and reloads a runtime annotation, promotes confirmed move
325
+ intent into a canonical change contract, imports a reference with the
326
+ installed `import-reference`, annotates it, and materializes a confirmed
327
+ region into a new imported revision. That revision must supersede the source,
328
+ reuse its exact image bytes, and not be approved. Finally it starts a
329
+ standalone `view --root` session and proves it is read-only. The summary never
330
+ contains the authoring token, absolute project paths, or note text.
331
+
332
+ The standalone read-only proof for v0.9 authoring lives in the v0.9
333
+ annotation smoke. The project-aware inspection and project workflow proof
334
+ lives in the packed viewer smoke.
335
+
336
+ A separate `tutorial-readiness` job runs on the same three operating systems.
337
+ It builds Observer from the repository source and runs
338
+ `scripts/run-v09-tutorial-readiness.mjs`, which validates and runs the four
339
+ `examples/v09-demo/tutorials/` scenarios through the external tool
340
+ `@dailephd/my-dev-kit-lab@0.4.9`, then reads the evidence each run wrote back
341
+ through the canonical Observer readers. It fails unless every scenario passes
342
+ with empty `cleanupErrors`, the tracked demo source is unchanged, and the
343
+ repository status is unchanged. The demo and the lab are repository release
344
+ support only. Neither is in the npm package or an Observer dependency.
345
+
346
+ The v0.9 matrix and tutorial readiness are recorded as completed in
347
+ `docs/reports/v0.9-final-readiness-corrections.md`; the earlier local Windows
348
+ integrated acceptance is recorded in
349
+ `docs/reports/v0.9-batch7-integrated-acceptance.md`.