@dailephd/my-frontend-observer 0.9.1 → 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 (150) hide show
  1. package/CHANGELOG.md +490 -471
  2. package/LICENSE +21 -21
  3. package/README.md +375 -357
  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/application/visualChangeAgentHandoffService.d.ts +28 -0
  11. package/dist/application/visualChangeAgentHandoffService.js +111 -0
  12. package/dist/application/visualChangeAgentHandoffService.js.map +1 -0
  13. package/dist/application/visualChangeProjectWorkflowService.d.ts +95 -0
  14. package/dist/application/visualChangeProjectWorkflowService.js +376 -0
  15. package/dist/application/visualChangeProjectWorkflowService.js.map +1 -0
  16. package/dist/application/visualChangeReviewService.d.ts +50 -0
  17. package/dist/application/visualChangeReviewService.js +69 -0
  18. package/dist/application/visualChangeReviewService.js.map +1 -0
  19. package/dist/application/visualChangeWorkflowPersistenceService.d.ts +26 -0
  20. package/dist/application/visualChangeWorkflowPersistenceService.js +15 -0
  21. package/dist/application/visualChangeWorkflowPersistenceService.js.map +1 -0
  22. package/dist/artifacts/visualChangeWorkflowArtifactReader.d.ts +9 -0
  23. package/dist/artifacts/visualChangeWorkflowArtifactReader.js +47 -0
  24. package/dist/artifacts/visualChangeWorkflowArtifactReader.js.map +1 -0
  25. package/dist/artifacts/visualChangeWorkflowArtifactWriter.d.ts +20 -0
  26. package/dist/artifacts/visualChangeWorkflowArtifactWriter.js +41 -0
  27. package/dist/artifacts/visualChangeWorkflowArtifactWriter.js.map +1 -0
  28. package/dist/cli.js +9 -7
  29. package/dist/cli.js.map +1 -1
  30. package/dist/domain/visualChangeAgentHandoff.d.ts +82 -0
  31. package/dist/domain/visualChangeAgentHandoff.js +80 -0
  32. package/dist/domain/visualChangeAgentHandoff.js.map +1 -0
  33. package/dist/domain/visualChangeAgentHandoffSerialization.d.ts +2 -0
  34. package/dist/domain/visualChangeAgentHandoffSerialization.js +11 -0
  35. package/dist/domain/visualChangeAgentHandoffSerialization.js.map +1 -0
  36. package/dist/domain/visualChangeCycle.d.ts +8 -0
  37. package/dist/domain/visualChangeCycle.js +7 -0
  38. package/dist/domain/visualChangeCycle.js.map +1 -0
  39. package/dist/domain/visualChangeWorkflow.d.ts +125 -0
  40. package/dist/domain/visualChangeWorkflow.js +109 -0
  41. package/dist/domain/visualChangeWorkflow.js.map +1 -0
  42. package/dist/domain/visualChangeWorkflowIdentity.d.ts +5 -0
  43. package/dist/domain/visualChangeWorkflowIdentity.js +24 -0
  44. package/dist/domain/visualChangeWorkflowIdentity.js.map +1 -0
  45. package/dist/index.d.ts +21 -1
  46. package/dist/index.js +12 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/projectWorkflow/projectPaths.d.ts +3 -0
  49. package/dist/projectWorkflow/projectPaths.js +7 -0
  50. package/dist/projectWorkflow/projectPaths.js.map +1 -1
  51. package/dist/viewer/assets/index-DglJ6f28.css +1 -0
  52. package/dist/viewer/assets/index-DsODREY5.js +9 -0
  53. package/dist/viewer/index.html +15 -15
  54. package/dist/viewer/sw.js +1 -1
  55. package/dist/viewerServer/evidence/classify.d.ts +3 -1
  56. package/dist/viewerServer/evidence/classify.js +10 -0
  57. package/dist/viewerServer/evidence/classify.js.map +1 -1
  58. package/dist/viewerServer/evidence/handles.js +1 -0
  59. package/dist/viewerServer/evidence/handles.js.map +1 -1
  60. package/dist/viewerServer/evidence/projection.d.ts +5 -0
  61. package/dist/viewerServer/evidence/projection.js +19 -0
  62. package/dist/viewerServer/evidence/projection.js.map +1 -1
  63. package/dist/viewerServer/evidence/visualChangeWorkflowView.d.ts +31 -0
  64. package/dist/viewerServer/evidence/visualChangeWorkflowView.js +36 -0
  65. package/dist/viewerServer/evidence/visualChangeWorkflowView.js.map +1 -0
  66. package/dist/viewerServer/httpServer.js +323 -1
  67. package/dist/viewerServer/httpServer.js.map +1 -1
  68. package/dist/viewerServer/referenceApproval.d.ts +22 -0
  69. package/dist/viewerServer/referenceApproval.js +42 -0
  70. package/dist/viewerServer/referenceApproval.js.map +1 -0
  71. package/dist/viewerServer/referenceVisualChangeAuthoring.d.ts +28 -0
  72. package/dist/viewerServer/referenceVisualChangeAuthoring.js +134 -0
  73. package/dist/viewerServer/referenceVisualChangeAuthoring.js.map +1 -0
  74. package/dist/viewerServer/runtimeVisualChangeAuthoring.d.ts +33 -0
  75. package/dist/viewerServer/runtimeVisualChangeAuthoring.js +81 -0
  76. package/dist/viewerServer/runtimeVisualChangeAuthoring.js.map +1 -0
  77. package/dist/viewerServer/visualChangeAuthoring.d.ts +46 -0
  78. package/dist/viewerServer/visualChangeAuthoring.js +63 -0
  79. package/dist/viewerServer/visualChangeAuthoring.js.map +1 -0
  80. package/dist/viewerServer/visualChangeHandoff.d.ts +23 -0
  81. package/dist/viewerServer/visualChangeHandoff.js +31 -0
  82. package/dist/viewerServer/visualChangeHandoff.js.map +1 -0
  83. package/dist/viewerServer/visualChangeReview.d.ts +30 -0
  84. package/dist/viewerServer/visualChangeReview.js +46 -0
  85. package/dist/viewerServer/visualChangeReview.js.map +1 -0
  86. package/docs/ARCHITECTURE.md +1394 -1373
  87. package/docs/CI_CD.md +349 -327
  88. package/docs/COMMANDS.md +1035 -1012
  89. package/docs/CONTRACTS.md +1971 -1926
  90. package/docs/CURRENT_STATE.md +1277 -1238
  91. package/docs/DEVELOPMENT.md +240 -237
  92. package/docs/DOCUMENTATION_PRESERVATION_POLICY.md +50 -50
  93. package/docs/PROJECT_DESCRIPTION.md +2248 -2224
  94. package/docs/PROJECT_MILESTONES.md +2681 -2558
  95. package/docs/PROJECT_OVERVIEW.md +200 -191
  96. package/docs/QUICKSTART.md +100 -96
  97. package/docs/RELEASE.md +37 -33
  98. package/docs/ROADMAP.md +1105 -1033
  99. package/docs/SECURITY.md +297 -275
  100. package/docs/WORKFLOWS.md +806 -770
  101. package/docs/plans/v0.10-implementation-plan.md +1509 -0
  102. package/docs/plans/v0.8-implementation-plan.md +655 -655
  103. package/docs/plans/v0.8.1-cli-usability-patch-plan.md +505 -505
  104. package/docs/plans/v0.9-implementation-plan.md +1529 -1529
  105. package/docs/plans/v0.9.1-implementation-plan.md +468 -468
  106. package/docs/reports/v0.10-batch1-visual-change-workflow-foundation.md +102 -0
  107. package/docs/reports/v0.10-batch2-project-composition-check-recording.md +103 -0
  108. package/docs/reports/v0.10-batch3-viewer-visual-change-workspace.md +93 -0
  109. package/docs/reports/v0.10-batch4-actual-frontend-entry.md +59 -0
  110. package/docs/reports/v0.10-batch5-reference-driven-entry.md +238 -0
  111. package/docs/reports/v0.10-batch6-coding-agent-handoff.md +85 -0
  112. package/docs/reports/v0.10-batch7-correction-review-acceptance.md +145 -0
  113. package/docs/reports/v0.10-batch8-integrated-acceptance.md +109 -0
  114. package/docs/reports/v0.10-implementation-completeness-documentation-reconciliation.md +344 -0
  115. package/docs/reports/v0.10-pre-release-readiness.md +120 -0
  116. package/docs/reports/v0.10-release-preparation.md +70 -0
  117. package/docs/reports/v0.10.1-project-check-baseline-context-implementation.md +86 -0
  118. package/docs/reports/v0.7-bounded-fidelity-context-prompt7.md +243 -243
  119. package/docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md +497 -497
  120. package/docs/reports/v0.7-pre-release-readiness.md +337 -337
  121. package/docs/reports/v0.7-reference-binding-prompt5.md +223 -223
  122. package/docs/reports/v0.7-reference-compatibility-prompt4.md +234 -234
  123. package/docs/reports/v0.7-reference-correction-workflow-prompt8.md +222 -222
  124. package/docs/reports/v0.7-reference-fidelity-prompt6.md +216 -216
  125. package/docs/reports/v0.7-reference-foundation-prompt1.md +151 -151
  126. package/docs/reports/v0.7-reference-regions-prompt2.md +195 -195
  127. package/docs/reports/v0.7-reference-requirements-prompt3.md +217 -217
  128. package/docs/reports/v0.7-release-prep.md +423 -423
  129. package/docs/reports/v0.8-binding-fidelity-interaction-batch6.md +279 -279
  130. package/docs/reports/v0.8-bounded-context-correlation-batch7.md +233 -233
  131. package/docs/reports/v0.8-comparison-contract-inspection-batch4.md +279 -279
  132. package/docs/reports/v0.8-evidence-index-readers-batch2.md +247 -247
  133. package/docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md +741 -741
  134. package/docs/reports/v0.8-integrated-viewer-acceptance-batch8.md +128 -128
  135. package/docs/reports/v0.8-observation-svg-inspection-batch3.md +223 -223
  136. package/docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md +687 -687
  137. package/docs/reports/v0.8-reference-candidate-inspection-batch5.md +232 -232
  138. package/docs/reports/v0.8-viewer-runtime-pwa-batch1.md +278 -278
  139. package/docs/reports/v0.8.1-implementation-completeness-documentation-reconciliation.md +114 -114
  140. package/docs/reports/v0.8.1-prerelease-readiness-cross-platform-security-code-rot.md +170 -170
  141. package/docs/reports/v0.9-architecture-retrieval.md +14 -37
  142. package/docs/reports/v0.9-final-pre-release-readiness.md +209 -209
  143. package/docs/reports/v0.9-final-readiness-corrections.md +530 -530
  144. package/docs/reports/v0.9-pre-release-readiness.md +169 -169
  145. package/docs/reports/v0.9.1-batch1-pwa-hard-gate-isolation.md +359 -359
  146. package/docs/reports/v0.9.1-batch2-hard-gate-validation-integration.md +262 -262
  147. package/docs/reports/v0.9.1-pre-release-readiness.md +206 -206
  148. package/package.json +59 -59
  149. package/dist/viewer/assets/index-BN41MI7m.css +0 -1
  150. package/dist/viewer/assets/index-CkKXnlrI.js +0 -9
@@ -1,1238 +1,1277 @@
1
- # Current State
2
-
3
- v0.9.1 is released and published as `@dailephd/my-frontend-observer@0.9.1`.
4
- v0.9 (Human Visual Annotation and Design-Intent Capture) adds structured visual
5
- annotation to the project-aware viewer. It passed integrated real-Chromium
6
- acceptance and final exact-candidate pre-release readiness on Windows, Linux
7
- and macOS, including all four tutorials. The viewer protocol is `1.3.0` and the
8
- visual annotation schema is `1.0.0`. Project aliases, `init`, `capture`,
9
- project-aware `view`, and `check` orchestration from v0.8.1 remain implemented,
10
- and the package is MIT licensed. The
11
- repository also holds a deterministic demo and four tutorial scenarios for
12
- v0.9, recorded by the external `@dailephd/my-dev-kit-lab@0.4.9` tool. See
13
- "v0.9 status" below.
14
-
15
- The project is published at package version `0.9.1` (roadmap v0.9.1, PWA
16
- Hard-Gate Isolation and Reproducible Security Acceptance; the preceding v0.9
17
- release was Human Visual Annotation and Design-Intent Capture; observation
18
- schema `1.2.0`;
19
- comparison schema `1.0.0`; frontend contract schema `1.0.0`; evaluation
20
- artifact schema `1.0.0`; bounded-agent-context schema `1.0.0`;
21
- external-reference schema `1.0.0`; visual annotation schema `1.0.0`). v0.9.0
22
- added the visual annotation schema and did not change any other canonical
23
- evidence schema version. v0.8.1 did not change any canonical evidence schema
24
- version either; see "v0.8 status" below for the final, complete v0.8 viewer
25
- state.
26
-
27
- ## v0.9.1 maintenance status
28
-
29
- Status: released and published as `@dailephd/my-frontend-observer@0.9.1`.
30
- No production code changed.
31
-
32
- Result of the implementation:
33
-
34
- 1. The original failure was reproduced. Selected alone, the hard gate failed at
35
- the offline reload with `net::ERR_CONNECTION_REFUSED`.
36
- 2. Root cause, part one: the old readiness check was
37
- `registration?.active !== undefined`. While the worker was still installing,
38
- `active` was `null` and the page had no controller. Because
39
- `null !== undefined` is true, the check passed and the server was closed
40
- before the worker controlled the page or finished precaching.
41
- 3. Root cause, part two: the gate shared a server, evidence root, and a fixed
42
- persistent Chromium profile with earlier tests. In normal file order those
43
- tests had already activated a controlling worker, which hid the defect.
44
- 4. The hard gate now owns a fresh evidence root, viewer server, temporary
45
- persistent profile, and BrowserContext. No PWA test uses the fixed
46
- `.my-dev-kit-workflow` profile any more.
47
- 5. The gate proves service-worker activation (`registration.active !== null`)
48
- and current-page control (`navigator.serviceWorker.controller !== null`)
49
- as separate facts.
50
- 6. It proves the app shell is in the Workbox precache and that no `/api/`
51
- request is in Cache Storage.
52
- 7. It proves the server is down with a direct Node-side request before the
53
- offline reload.
54
- 8. After the reload, the shell renders, the evidence list shows its explicit
55
- unavailable state, and the previously visible evidence identity is absent.
56
- 9. `npm run test:pwa-hard-gate` runs the gate alone. `npm run test:security`
57
- now ends with it. It passes repeatedly, and the full PWA file, browser suite,
58
- and security suite pass.
59
- 10. Production PWA behavior is unchanged.
60
-
61
- Evidence: `docs/reports/v0.9.1-batch1-pwa-hard-gate-isolation.md` and
62
- `docs/reports/v0.9.1-batch2-hard-gate-validation-integration.md`.
63
-
64
- The historical planning background follows.
65
-
66
- A post-release test-isolation defect has been identified in
67
- `tests/browser/pwaHardening.test.ts`. The PWA server-down test labeled
68
- `HARD GATE` passes in the normal full-file/full-suite execution but fails
69
- when selected independently with Vitest `-t`. The current test shares a
70
- persistent Chromium context/profile with earlier tests, and its own setup proves
71
- that a service-worker registration is active without independently proving all
72
- of the state the server-down experiment needs: that the current page is
73
- controlled, that the application shell is actually precached, and that no
74
- historical profile/cache state was inherited.
75
-
76
- This is currently classified as a test-isolation defect, not a demonstrated
77
- production PWA regression. The released safety contract remains unchanged:
78
- application-shell caching may keep the viewer shell available while evidence
79
- and media remain server-backed, and stale evidence must never be presented as
80
- current after the server is unavailable. No production PWA code change is
81
- authorized unless a corrected fresh-state hard-gate experiment first
82
- demonstrates a real runtime failure.
83
-
84
- The completed v0.9.1 maintenance patch was governed by the frozen implementation
85
- plan `docs/plans/v0.9.1-implementation-plan.md`. It made the hard gate own fresh
86
- disposable evidence/server/browser-profile state, explicitly prove service-worker
87
- control and shell/API cache preconditions, explicitly prove the server is
88
- unavailable before the offline reload, and add an isolated execution gate so the
89
- same test passes by itself as well as inside the full browser and security
90
- suites.
91
-
92
- v0.8 (Interactive Local Observation Viewer) is fully implemented, tested,
93
- formally cross-platform/security validated, and released. All eight v0.8
94
- implementation batches, the hardened documentation/implementation-
95
- completeness audit, and formal pre-release readiness (Windows/Linux/macOS
96
- cross-platform packed-candidate validation, security audit, code-rot audit)
97
- all passed - see
98
- `docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md`
99
- and
100
- `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`.
101
-
102
- ## Greenfield foundation established
103
-
104
- The retained repository contains:
105
-
106
- - Node.js 24+ and TypeScript ESM package configuration;
107
- - TypeScript build and typecheck configuration;
108
- - ESLint configuration;
109
- - a Vitest runner configured to report honestly when no tests exist;
110
- - a safe `dist/` clean script;
111
- - documentation validation;
112
- - package allowlisting;
113
- - `src/cli.ts` and `src/index.ts`, the package/library entry points originally
114
- established by the selected TypeScript CLI starter profile;
115
- - complete repository-local Project Description, Project Milestones, ROADMAP,
116
- and standardized documentation.
117
-
118
- The package bin (`src/cli.ts`) now exposes the real current public CLI
119
- surface described below: the five low-level commands released through `0.6.0`
120
- (`observe`, `compare`, `approve-baseline`, `save-change-contract`,
121
- `evaluate-contract`); three reference commands released in `0.7.0`
122
- (`import-reference`, `approve-reference`, `evaluate-reference-fidelity`);
123
- `view`, released in `0.8.0`; and the v0.8.1 high-level `init`, `capture`, and
124
- `check` commands. v0.8.1 also makes `view` project-aware while preserving its
125
- standalone `--root` form. `src/cli.ts` remains a thin parsing/dispatch/
126
- presentation boundary; it is no longer the not-implemented placeholder.
127
-
128
- ## v0.1 progress (Batch 1–6; implemented and released as 0.1.0)
129
-
130
- - Batch 1 froze and implemented the observation request contract, evidence
131
- states/sources, schema 1.0.0, observation/request identity, bounded
132
- readiness semantics, diagnostic/completion semantics, browser/network
133
- safety policy, and portable path normalization, with 40 passing unit tests.
134
- - Batch 2 added a Playwright Chromium browser boundary (`src/browser/`) and a
135
- minimal application seam (`src/application/`) that launches a real
136
- Chromium browser, enforces the Batch 1 loopback/redirect/subresource
137
- safety policy at runtime, applies the requested viewport, waits for the
138
- approved bounded readiness condition, captures a real viewport PNG
139
- screenshot, returns observer-owned browser provenance, and reliably closes
140
- the browser on every exit path. Deterministic local HTTP fixtures live
141
- under `tests/fixtures/`; the real-Chromium integration tests live under
142
- `tests/browser/` and run via `npm run test:browser` (kept separate from
143
- `npm test`, which continues to run only the fast unit suite).
144
- - Batch 3 extended the same single browser observation (no second Chromium
145
- lifecycle) to also capture the v0.1 minimum page evidence (requested/final
146
- URL, title, viewport, device pixel ratio, document scroll/client
147
- dimensions plus a derived overall document width/height, window scroll
148
- position) and explicit-target evidence (tag, geometry, computed
149
- display/position/overflow, scroll/client metrics, initial visibility, and
150
- role/name where the browser reliably exposes them) for every configured
151
- CSS target, honoring missing/ambiguous-target semantics honestly. This
152
- additively extended `src/domain/schema.ts`'s `TargetEvidenceRecord` (new
153
- `tag`/`layout`/`visibility`/`semantics` categories, and concrete shapes for
154
- `geometry`/`style`) and `BrowserCaptureResult`; schema version stays
155
- `1.0.0`.
156
- - Batch 4 added a portable, atomic observation-artifact writer
157
- (`src/artifacts/artifactWriter.ts`) and a minimal application persistence
158
- seam (`src/application/observationPersistence.ts`) that assembles the
159
- frozen `ObservationArtifact` shape from a Batch 2/3 browser capture (using
160
- the existing Batch 1 identity/completion functions verbatim, no new logic
161
- invented) and writes it to `<outputLocation>/<observationId>/manifest.json`
162
- plus `screenshot.png`. Writing happens in a sibling temporary directory
163
- first (screenshot before manifest), finalized only via one atomic
164
- directory rename, so a consumer can never observe a partially-written
165
- artifact under its real name; a filesystem failure anywhere in that
166
- sequence reports the existing `artifact-write-failure` diagnostic and
167
- leaves no completed artifact behind. Internal artifact references
168
- (`screenshot.png`) are relative/portable; the observation's logical
169
- identity is the existing Batch 1 `observationId`, not its filesystem
170
- location. The writer has no Playwright dependency and does not modify the
171
- observed target. Schema stays `1.0.0`.
172
- - Batch 5 wired the existing owners into the real user-facing workflow:
173
- `src/cli.ts` implements a real `observe` command (thin argument
174
- parsing/output only - no Chromium, safety, evidence, or filesystem logic
175
- of its own), and `src/application/observationPersistence.ts` gained one
176
- `observe()` use case that runs the existing browser capture exactly once
177
- and, only on success, persists it exactly once through the existing
178
- artifact writer. CLI syntax errors (malformed `WIDTHxHEIGHT`, malformed
179
- `id=selector`) are rejected before any browser launches; all domain bounds
180
- and safety decisions still come from the existing Batch 1 request
181
- validator and safety policy, not CLI-local logic. A successfully
182
- persisted observation - including one whose completion state honestly
183
- reports `partial` - exits `0`; invalid syntax/request, an unpersistable
184
- browser failure, or a failed artifact write exits nonzero. Package version
185
- is `0.1.0`; schema stays `1.0.0`.
186
-
187
- So: `my-frontend-observer observe --url ... --viewport ... --target ...
188
- --output ...` is a real, working, source-checkout command that launches
189
- Chromium, produces bounded runtime evidence, and writes a portable local
190
- artifact - proven both via `runCli()`-level tests and a built
191
- `node dist/cli.js observe ...` smoke run against the deterministic fixture.
192
-
193
- Batch 6 closed the remaining v0.1 coverage gap (a genuine real-Chromium
194
- navigation failure - connection reset mid-navigation - distinct from a
195
- readiness timeout or a pre-launch safety rejection) and proved the packaged
196
- form of the implementation works independent of the source checkout: the
197
- real `npm pack` tarball, installed fresh in a clean temporary consumer
198
- directory outside the repository, exposes its `my-frontend-observer` bin,
199
- reports the correct version/help text, installs its own Chromium binary via
200
- the consumer-local Playwright toolchain, and performs a real observation
201
- against a disposable local HTTP target - producing a `manifest.json` +
202
- `screenshot.png` artifact identical in shape to the source-checkout result,
203
- without modifying the observed target, and with the temporary consumer/
204
- tarball/output fully cleaned up afterward. Documentation across the
205
- repository was reconciled to this implemented state as part of the same
206
- batch.
207
-
208
- ## v0.1 status
209
-
210
- `v0.1.0` was the first published release (see `CHANGELOG.md` and
211
- `docs/RELEASE.md`). Everything above this section describes that released
212
- state, still present unchanged in `v0.2.0`.
213
-
214
- ## v0.2 status (Stable Semantic Targets and Region Identity) - released as 0.2.0
215
-
216
- v0.2 is implemented and released as package version `0.2.0`, observation
217
- schema `1.1.0`.
218
-
219
- - **Canonical target/locator model.** Each configured target has a stable
220
- observer-owned `name` plus an ordered, bounded `locators` array
221
- (`src/request/request.ts#TargetLocator`, `NamedTarget`). This identity is
222
- distinct from both the browser locator that resolves it and any
223
- source-code symbol. The legacy `{name, selector}` shape remains accepted
224
- and normalizes to a one-item `css` locator, so every v0.1 CLI invocation
225
- continues to work unchanged. Bounds: 20 targets max, 5 locators per
226
- target max (unchanged/new respectively from v0.1's target count bound).
227
- - **Six frozen locator kinds, all resolved against real Chromium**: `role`
228
- (Playwright's accessibility role/name locator, exact name matching),
229
- `id` and `data-attribute` (exact CSS attribute-equals matching that never
230
- reinterprets the configured value as selector syntax), `semantic-element`
231
- (a frozen structural tag set: `header`, `nav`, `main`, `footer`,
232
- `article`, `section`, `aside`, `form`, `dialog`), `css` (unchanged v0.1
233
- behavior), and `text` (exact match only, no substring/fuzzy matching).
234
- Locator order is the fallback order: 0 matches tries the next locator; 1
235
- match selects and stops; more than 1 match is ambiguous and stops (never
236
- falls through); an unevaluable locator is unavailable and stops (never
237
- falls through). All six kinds converge on one measurement path
238
- (`src/browser/evidenceCapture.ts#captureResolvedTargetRecord`) - locator
239
- strategy never changes the resulting evidence shape.
240
- - **Semantic region evidence**, added to every resolved target alongside
241
- the existing v0.1 role/name capture: `semanticState` (a first bounded
242
- family of `disabled`/`expanded`/`checked`/`selected`/`pressed`/`current`,
243
- read from the element's own native/ARIA properties so an explicit `false`
244
- is always distinguishable from "not applicable"; `checked`/`pressed` also
245
- support the browser's `'mixed'` value); `landmark` (derived only from the
246
- already-captured browser-exposed role - never from locator kind or HTML
247
- tag - against the standard landmark role set `banner`/`navigation`/
248
- `main`/`complementary`/`contentinfo`/`form`/`region`/`search`); and
249
- `containment` (bounded DOM containment checked only among the other
250
- explicitly configured targets in the same observation, in configured
251
- order - `available`/`partial`/`unavailable`, never a layout/spatial-
252
- relationship graph).
253
- - **Proven identity stability**: the same target configuration produces the
254
- same `requestId` across repeated observations (with a fresh
255
- `observationId` every time); changing a target's locator strategy while
256
- keeping its stable name changes `requestId` but not the `targetEvidence`
257
- key; actual runtime disappearance of a still-configured target changes
258
- only its resolution status, never the `requestId`.
259
- - **Public CLI**: `my-frontend-observer observe --targets-file <json-file>`
260
- supplies a structured `{ "targets": [...] }` collection as an alternative
261
- to one or more `--target id=css-selector` flags; the two are mutually
262
- exclusive per invocation. `--targets-file` only validates its own root
263
- wrapper (readable file, valid JSON, object root with exactly a `targets`
264
- field); all target/locator-internal validation stays owned by the
265
- existing `normalizeRequest()`. The file path is operational input only -
266
- never part of request identity, never persisted into `manifest.json`.
267
- - **Observation schema `1.1.0`** (`src/domain/schema.ts#SCHEMA_VERSION`):
268
- additive over the published `1.0.0` - extends `TargetEvidenceRecord` with
269
- `semanticState`/`landmark`/`containment` and extends `TargetResolution`
270
- with `selectedLocatorKind`/`selectedLocatorIndex`/`usedFallback`/
271
- `confidence`/`attempts`. Artifact kind, directory structure, atomic
272
- persistence, and evidence-state/source vocabularies are unchanged.
273
- - **Validation on this branch**: `npm run typecheck`, `npm run lint`,
274
- `npm test`, `npm run test:browser`, `npm run build`, and
275
- `npm run check:docs` all pass (106 unit tests, 69 real-Chromium tests as
276
- of this reconciliation; see `docs/DEVELOPMENT.md` for how to reproduce).
277
- `scripts/dev/builtCliTargetsFileSmoke.mjs` additionally proves the built
278
- `dist/cli.js` (not just the imported `runCli()` function) performs a real
279
- semantic `--targets-file` observation end to end.
280
-
281
- ## v0.3 status (Runtime Scrolling, Overflow, and Visibility Behavior) - released as 0.3.0
282
-
283
- v0.3 is implemented and released as package version `0.3.0`, observation
284
- schema `1.2.0`. It was validated as a packed npm tarball in a clean
285
- consumer environment on Windows, Linux, and macOS before release.
286
-
287
- - **Batch 1** froze the `scrollScenario` request/identity/schema contract:
288
- `ScrollScenario { action }` with exactly two action kinds
289
- (`window-scroll-by`, `target-scroll-by`), signed-integer deltas bounded to
290
- `[-20000, 20000]`, `target-scroll-by.target` referencing an existing stable
291
- configured target name, scenario configuration participating in
292
- `requestId` (runtime results never do), and the full bounded runtime
293
- evidence model (`ScrollRuntimeSnapshot`, `ViewportRelationEvidence`,
294
- `OverflowEvidence`, scenario transitions, `ScrollOwnerInterpretation`) in
295
- schema `1.2.0` (up from `1.1.0`).
296
- - **Batch 2** implemented real `window-scroll-by` execution
297
- (`src/browser/scrollCapture.ts`, `src/domain/scrollEvidence.ts`): initial/
298
- final runtime snapshots around an immediate `window.scrollBy({behavior:
299
- 'instant'})` and exactly two `requestAnimationFrame` cycles, real vertical/
300
- horizontal document scrolling, actual-vs-computed overflow, real viewport
301
- relation, `enteredViewport`/`leftViewport`, and `document`/`none`
302
- scroll-owner evidence - with ordinary final `pageEvidence`/`targetEvidence`
303
- and the screenshot always describing the same final post-action state.
304
- - **Batch 3** implemented real `target-scroll-by` execution against the same
305
- canonical `resolveConfiguredTargets` resolution already used by every v0.2
306
- locator kind: real nested vertical/horizontal element scrolling, boundary
307
- clamping, non-scrollable/no-movement targets, and the completed
308
- `document`/`target:<name>`/`none`/`indeterminate` scroll-owner derivation
309
- (`src/domain/scrollEvidence.ts#deriveScrollOwner`) - proven never to
310
- attribute ownership from bounding-rectangle movement alone in either
311
- direction. An unresolved/ambiguous/hidden action target is never scrolled
312
- and never fabricated as moved; the existing target diagnostics explain it
313
- honestly and the observation still persists.
314
- - **Batch 4** exposed the existing contract through the real public CLI:
315
- `my-frontend-observer observe --scroll-scenario-file <json-file>` (see
316
- `docs/COMMANDS.md`). The file supplies the `scrollScenario` value directly
317
- (no wrapper field); the CLI/input layer only validates file readability,
318
- JSON validity, and a non-array object root - every scenario/action rule
319
- stays owned by the existing `normalizeRequest()`. Usable with either
320
- `--target` or `--targets-file` (independent of target configuration, never
321
- a third mutually-exclusive mode); the scenario-file path is operational
322
- input only, never persisted and never part of request identity, exactly
323
- like `--targets-file`'s path. CLI output/exit-code semantics are
324
- unchanged. Proven via real Chromium (`tests/browser/cliObserve.test.ts`)
325
- and the built `dist/cli.js` (`scripts/dev/builtCliScrollScenarioSmoke.mjs`).
326
-
327
- ## v0.4 status (Layout Relationships, Dependency Evidence, and Before/After Comparison) - released as 0.4.0
328
-
329
- v0.4 is implemented and released as package version `0.4.0`; observation
330
- schema remains `1.2.0`; comparison schema is `1.0.0`. It was validated as a
331
- packed npm tarball in a clean consumer environment on Windows, Linux, and
332
- macOS - covering the legacy CSS-shorthand `--target` path, the structured
333
- `--targets-file` path, both `--scroll-scenario-file` action kinds, and the
334
- installed `compare` command (comparable and incomparable cases) - before
335
- release.
336
-
337
- - **Batch 1** froze the `my-frontend-observer/comparison` artifact contract
338
- (schema `1.0.0`, independent of and never reused for the observation
339
- schema): `ComparisonConfig` (geometry tolerance, default `0.5`px, bounded
340
- `[0, 10]`px), the bounded layout-relationship vocabulary (horizontal/
341
- vertical order, area overlap, relative width, geometric fit, vertical
342
- sequencing, page-width fit, clipping), comparability states, the
343
- before/after difference vocabulary, and the non-causal explicit
344
- dependency-evidence contract, plus `comparisonRequestId`/`comparisonId`
345
- identity (`src/domain/relationships.ts`, `src/domain/comparison.ts`,
346
- `src/domain/comparisonIdentity.ts`). No derivation, comparison, or
347
- persistence.
348
- - **Batch 2** implemented the one canonical pure derivation engine,
349
- `deriveLayoutRelationships(observation, options?)`
350
- (`src/domain/relationships.ts`): consumes an existing `ObservationArtifact`
351
- only (no Chromium, no re-resolution, no DOM access) and derives a bounded,
352
- traceable `LayoutRelationshipGraph` among configured targets - stable
353
- target identity, deterministic configured-target ordering, honest
354
- unresolved-target handling (not-found/ambiguous/unavailable/hidden, never
355
- a fabricated zero-sized region), and evidence-reference provenance for
356
- every derived relationship. DOM containment is read directly from the
357
- existing `TargetContainment` evidence rather than re-derived, and stays
358
- distinct from geometric fit. A standalone `deriveTargetClipping(record)`
359
- derives the frozen clipping concept per target from existing layout/style
360
- evidence.
361
- - **Batch 3** implemented the pure before/after comparison engine,
362
- `compareObservations(before, after, config?)`
363
- (`src/domain/comparisonEngine.ts`): validates both source observations,
364
- evaluates comparability before any rendered difference is calculated
365
- (hard page-URL/viewport/browser-engine/scroll-scenario mismatches;
366
- producer/browser-version and target-configuration warnings), reuses
367
- `deriveLayoutRelationships` unchanged for both sides, and derives target/
368
- page differences (appeared/disappeared, moved, resized, visibility,
369
- clipping, actual overflow, DOM containment, page size, scroll-owner) and
370
- relationship changes (matched by family + subject/related target, never
371
- array position) - all without launching Chromium, re-resolving targets, or
372
- mutating either input observation. Explicit `ComparisonConfig.
373
- expectedDependencies` are evaluated into non-causal
374
- consistent/not-observed/contradictory-to-declaration/unavailable outcomes
375
- only; the observer never infers a dependency from co-change. Comparison
376
- identity reuses the existing Batch 1 `buildComparisonRequestIdentity`/
377
- `buildComparisonIdentity` verbatim. Persistence
378
- (`src/artifacts/comparisonArtifactWriter.ts#writeComparisonArtifact`,
379
- atomic, `<outputLocation>/<comparisonId>/manifest.json` only, no copied
380
- screenshots) and the application-level `compareAndPersist` use case
381
- (`src/application/comparisonService.ts`) are implemented; a narrow
382
- `readObservationArtifact` reader
383
- (`src/artifacts/artifactReader.ts`) is established ahead of the Batch 4
384
- CLI.
385
- - **Batch 4** exposed the existing comparison workflow through the real
386
- public CLI: `my-frontend-observer compare --before <observation-artifact-
387
- root> --after <observation-artifact-root> --output <directory>
388
- [--config-file <json-file>]` (see `docs/COMMANDS.md`). The CLI stays thin
389
- - `src/cli.ts` parses arguments, optionally loads a config file (file
390
- readability/JSON validity/object-root only, exactly like
391
- `--targets-file`/`--scroll-scenario-file`), and delegates to one new
392
- thin application-layer orchestration function,
393
- `compareAndPersistFromArtifactRoots`
394
- (`src/application/comparisonService.ts`), which reads both observation
395
- roots through the existing `readObservationArtifact` reader and calls the
396
- existing `compareAndPersist` exactly once - no comparability/geometry/
397
- relationship/dependency logic lives in the CLI, and comparison itself
398
- never launches Chromium (`src/cli.ts` still imports nothing from
399
- `src/artifacts/` or `src/browser/`, matching the pre-existing observe-CLI
400
- import-boundary test). `comparable`, `comparable-with-warnings`, and
401
- `incomparable` all exit `0` - each is a successful comparison outcome;
402
- only a genuine parse/read/domain/persistence failure exits nonzero.
403
- Operational paths (`--before`/`--after`/`--config-file`/`--output`) never
404
- affect `comparisonRequestId` and are never written into the persisted
405
- manifest. Proven end-to-end via real Chromium
406
- (`tests/browser/cliCompare.test.ts`) and the built `dist/cli.js`
407
- (`scripts/dev/builtCliCompareSmoke.mjs`): unchanged/moved/resized/
408
- appeared/disappeared/configuration-only-change/overlap/geometric-fit/
409
- page-overflow/clipping/scroll-owner cases, plus an explicit
410
- `--config-file` dependency-evidence case, all through the public command
411
- surface.
412
-
413
- v0.4's canonical relationship derivation, before/after comparison,
414
- comparability, differences, relationship changes, explicit dependency
415
- evidence, comparison persistence, and public `compare` CLI are all
416
- implemented, exercised end-to-end, packed-validated cross-platform, and
417
- released.
418
-
419
- v0.5 frontend contract model, identity, and evaluation engine are released
420
- as part of `0.5.0`: `src/domain/frontendContracts.ts` (persistent baseline /
421
- per-change contract types, the four authored change-scope categories plus
422
- the derived `unexpected` classification, the 15-primitive bounded
423
- vocabulary, contract tolerance, and the clause-result/overall-verdict
424
- vocabulary), `src/domain/frontendContractIdentity.ts` (deterministic
425
- contract/baseline/clause identity), and
426
- `src/domain/frontendContractEvaluation.ts#evaluateFrontendContract`
427
- (the one canonical pure evaluator: active-baseline/supersession calculation,
428
- bounded conflict detection, per-category clause evaluation, difference-to-
429
- scope matching, unexpected-change derivation, and overall PASS/FAIL) - all
430
- covered by focused unit tests. Observation schema stays `1.2.0`, comparison
431
- schema stays `1.0.0`.
432
-
433
- v0.5 contract and evaluation persistence are also released as part of
434
- `0.5.0`: `src/artifacts/frontendContractArtifactWriter.ts`/`frontendContractArtifactReader.ts`
435
- (symmetric baseline/per-change contract persistence, atomic write, no
436
- overwrite of existing history), `src/artifacts/comparisonArtifactReader.ts`
437
- (new - no comparison reader existed before this batch; comparison schema
438
- still `1.0.0`), `src/domain/frontendContractEvaluationArtifact.ts` (minimal
439
- additive persisted envelope around the frozen evaluation-result vocabulary,
440
- its own independent schema family `1.0.0`) with
441
- `src/artifacts/frontendContractEvaluationArtifactWriter.ts`/`...Reader.ts`,
442
- and `src/application/frontendContractEvaluationService.ts#evaluateAndPersist`/
443
- `evaluateAndPersistFromArtifactRoots` (calls `evaluateFrontendContract`
444
- exactly once, persists exactly one evaluation artifact for both `PASS` and
445
- `FAIL` verdicts, never persists a fabricated artifact when evaluation
446
- construction itself fails). `evaluateFrontendContract` itself is unmodified.
447
-
448
- v0.5 public contract/baseline-approval/evaluation CLI is also released as
449
- part of `0.5.0`:
450
- `approve-baseline` (the only baseline-approval act - explicit only, never
451
- inferred from `compare` or a `PASS` evaluation; verifies the contract's
452
- `sourceObservation` matches the supplied observation before persisting),
453
- `save-change-contract` (persistence only), and `evaluate-contract`
454
- (evaluates already-persisted before/after/comparison/baseline/change
455
- evidence exactly once and persists exactly one evaluation artifact;
456
- `--enforce` makes a `FAIL` verdict exit nonzero without changing the
457
- verdict, its identity, or its persisted content - a `FAIL` without
458
- `--enforce` still exits `0`). `src/application/frontendContractPersistenceService.ts`
459
- adds the two new thin application seams (`approveAndPersistBaseline`,
460
- `persistPerChangeContract`); `src/cli.ts` gained no browser or artifact-
461
- writer import. Covered by `tests/unit/cliFrontendContracts.test.ts` and the
462
- Chromium-free `scripts/dev/builtCliFrontendContractsSmoke.mjs` dev smoke.
463
- Observation schema `1.2.0`; comparison schema `1.0.0`; frontend contract
464
- schema `1.0.0`; evaluation artifact schema `1.0.0` - no schema was bumped
465
- to add this CLI.
466
-
467
- v0.5 proved the complete public contract workflow (`observe` →
468
- `approve-baseline` → `save-change-contract` → `observe` → `compare` →
469
- `evaluate-contract`) against real Chromium observations, not hand-constructed
470
- artifacts: a fully successful contract change (all clauses `pass`, overall
471
- `PASS`), and the "milestone signature" case - a locally successful requested
472
- change (navigation shrinks, workspace expands, both real and both `pass`)
473
- coexisting with a genuine protected-property regression (real right-rail
474
- `resized` difference) and a genuine preserved-invariant regression (real
475
- `clipping-changed` difference, `not-clipped` → `clipped`) - producing overall
476
- `FAIL`. Both scenarios are covered by `tests/browser/cliFrontendContracts.test.ts`
477
- (real Chromium, via `tests/fixtures/server.ts`'s new `/contract` route) and by
478
- the built-CLI dev smoke `scripts/dev/builtCliFrontendContractsBrowserSmoke.mjs`
479
- (the built `dist/cli.js`, not the imported `runCli()`, against its own
480
- disposable local HTTP fixture). Both confirm `--enforce` behavior (`FAIL`
481
- persists and exits `0` without it, exits nonzero with it, identical
482
- `evaluationRequestId` and `clauseResults` in both cases), full source
483
- observation/comparison immutability, no screenshot copied into the
484
- evaluation artifact, and no operational filesystem path leaked into any
485
- persisted manifest.
486
-
487
- The packed-readiness coverage gap this left (`V0_5_READINESS_VALIDATION_GAP_EXISTS`)
488
- was corrected and proven cross-platform before release:
489
- `scripts/ci/runPackedObservationSmoke.mjs` also exercises the installed
490
- packed candidate's `approve-baseline`/`save-change-contract`/
491
- `evaluate-contract` commands against real installed-candidate `observe`/
492
- `compare` evidence, proving the same successful-change and milestone-
493
- signature scenarios through the installed tarball rather than the source
494
- checkout. v0.5 pre-release readiness passed on the validation branch
495
- `validation/v0.5-pre-release` (GitHub Actions run `31727856546`, one shared
496
- hash-verified candidate tarball on Windows, Linux, and macOS - see
497
- `docs/CI_CD.md` for full evidence) before the version `0.5.0` release below.
498
-
499
- ## v0.6 status (Bounded Agent Context and Native my-dev-kit Ecosystem Integration) - released as `0.6.0`
500
-
501
- v0.6 is published as package version `0.6.0`, tagged `v0.6.0`, from the
502
- canonical `canonicalization/v0.6` lineage (product commit
503
- `514bf3bb513764815a0a5b9e508d5836aa7d7fd8`). Observation schema stays
504
- `1.2.0`; comparison schema `1.0.0`; frontend contract schema `1.0.0`;
505
- evaluation artifact schema `1.0.0`; new bounded-agent-context schema
506
- `1.0.0` (artifact kind `my-frontend-observer/bounded-agent-context`).
507
-
508
- - **Bounded runtime projection** (`src/domain/boundedAgentContext.ts`,
509
- `src/domain/boundedAgentContextProjection.ts#projectBoundedAgentContext`):
510
- page/viewport identity, stable target identities, geometry, runtime
511
- behavior, relationships, before/after differences, contract results, and
512
- requested/expected-dependent/protected/preserved scope - reusing the
513
- existing v0.5 `frontendContracts.ts` types directly rather than
514
- reimplementing them - plus diagnostics, screenshot/artifact references,
515
- provenance, and explicit truncation/omission metadata.
516
- - **Adequacy, omission, and truncation** (`Adequacy`/`ADEQUACY_REASON_CODES`,
517
- `OmissionRecord`/`TruncationRecord`, bounded aggregate-cap summarization):
518
- distinguishes required from optional loss and reports whether captured
519
- evidence is adequate for the task rather than merely present.
520
- - **Runtime/static correlation**
521
- (`src/domain/boundedAgentContextCorrelation.ts#deriveRuntimeStaticCorrelations`/
522
- `attachRuntimeStaticCorrelations`): correlation outcomes are exactly
523
- `correlated`/`ambiguous`/`unavailable`; competing candidate identities
524
- remain visible; a stable runtime target identity is never silently
525
- reported as source ownership. This module has no dependency on
526
- `@dailephd/my-dev-kit` - it accepts only plain, already-retrieved
527
- candidate evidence, since no generic static-side retrieval capability was
528
- found missing.
529
- - **Deterministic identity** (`src/domain/boundedAgentContextIdentity.ts`):
530
- a logical identity distinct from a fresh per-execution instance identity.
531
- - **Export/public boundary**: `src/index.ts` exports the complete
532
- bounded-agent-context and correlation type/function surface as a
533
- programmatic library contract. There is no new CLI command and no disk
534
- artifact writer/reader for this artifact family - it is a pure contract-
535
- and-derivation layer, consistent with the frozen module documentation
536
- describing it as a foundation for orchestrator/lab consumption rather than
537
- a persisted artifact kind.
538
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
539
- lint`, `npm test` (32 files, 627 tests), `npm run test:browser` (9 files,
540
- 120 tests), `npm run test:security`, `npm run build`, and `npm run
541
- check:docs` all pass. Cross-repository neutral verification (observer
542
- `514bf3b`, orchestrator `9473e4c`, lab `271e72c`) passed with 6/6
543
- requirement coverage and no known product blockers.
544
- - **Not Observer-owned / correctly out of scope for this repository**: no
545
- `my-dev-kit` static-side change was made (none was proven necessary); no
546
- orchestrator bounded-evidence consumption or lab reader/fixture/evaluation
547
- code lives in this repository - those are separate sibling-repository
548
- deliverables, not part of `my-frontend-observer`'s v0.6 surface.
549
-
550
- ## v0.7 Prompt 1 status (External Visual Reference Foundation) - released as `0.7.0`
551
-
552
- Only the foundation layer of the v0.7 external-reference architecture is
553
- implemented: an observer-owned `ExternalReferenceArtifact` family
554
- representing one externally supplied design-reference image plus
555
- deterministic identity, provenance, bounded image metadata, and an explicit
556
- two-state lifecycle. This is not the full v0.7 coding-agent workflow.
557
-
558
- - **Domain** (`src/domain/externalReferenceImage.ts`): pure, dependency-free
559
- PNG/JPEG/WebP header-byte format detection and dimension parsing (no
560
- decode, no OCR, no computer vision), bounded to
561
- `EXTERNAL_REFERENCE_MAX_IMAGE_BYTES` (20,000,000 bytes) and
562
- `[EXTERNAL_REFERENCE_MIN_DIMENSION_PX, EXTERNAL_REFERENCE_MAX_DIMENSION_PX]`
563
- (`[1, 8192]`) pixels per side.
564
- - **Domain** (`src/domain/externalReference.ts`): `ExternalReferenceArtifact`
565
- is a discriminated union of `ImportedExternalReferenceArtifact` (owns its
566
- image file) and `ApprovedExternalReferenceArtifact` (carries a
567
- `sourceReference` back to the imported artifact's image instead of copying
568
- it) under `EXTERNAL_REFERENCE_ARTIFACT_KIND` /
569
- `EXTERNAL_REFERENCE_SCHEMA_VERSION` (`'1.0.0'`, independent of the
570
- observation/comparison/contract schema versions). Lifecycle has exactly two
571
- persisted states, `'imported'` and `'approved'` - there is no literal
572
- `'superseded'` state; supersession is represented only as a forward
573
- pointer (`supersedesReferenceId` on the newer artifact), so an existing
574
- persisted artifact's own manifest is never rewritten.
575
- - **Identity** (`src/domain/externalReferenceIdentity.ts`): the same
576
- canonicalize-then-sha256 request identity plus nonce-based fresh instance
577
- identity pattern used by every other artifact family, duplicated per-family
578
- per existing convention. `referenceRequestId` is a pure function of
579
- `{imageSha256, format, width, height, supersedesReferenceId}` only - never
580
- a filesystem path, output location, label, or timestamp.
581
- - **Persistence** (`src/artifacts/externalReferenceArtifactWriter.ts` /
582
- `externalReferenceArtifactReader.ts`): same atomic temp-dir-then-rename
583
- discipline as the observation/comparison writers; an `'imported'`
584
- artifact's directory contains `manifest.json` plus its owned image file;
585
- an `'approved'` artifact's directory contains only `manifest.json`.
586
- - **Application** (`src/application/externalReferencePersistenceService.ts`):
587
- `importExternalReference()` (never approves; fails closed on an
588
- unsupported/undetectable format, invalid or out-of-bound dimensions, an
589
- over-limit file, or an unresolvable `--supersedes` target) and
590
- `approveExternalReference()` (the only explicit approval act; refuses to
591
- approve anything not currently in the `'imported'` state; never mutates the
592
- imported artifact it approves).
593
- - **CLI**: `import-reference <image-file> --output <dir> [--label] [--supersedes]`
594
- and `approve-reference --reference <root> --output <dir> [--supersedes]`.
595
- - **Export/public boundary**: `src/index.ts` exports the complete new type,
596
- constant, validator, identity, writer, reader, and application-service
597
- surface, following the same grouping order as every existing family.
598
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
599
- lint`, `npm test` (38 files, 668 tests), `npm run test:browser` (9 files,
600
- 120 tests), `npm run test:security`, `npm run build`, `npm run check:docs`,
601
- `git diff --check`, and `npm pack --dry-run` all pass with zero changes to
602
- any pre-existing test.
603
- - **Not implemented in this stage** (explicitly deferred to later v0.7
604
- prompts): reference regions, geometry, relationships, design requirements,
605
- tolerances, reference-region/runtime-target binding, reference-vs-candidate
606
- fidelity evaluation, theme/application-state compatibility evaluation,
607
- viewer, and annotation.
608
-
609
- ## v0.7 Prompt 2 status (Explicit Reference Regions, Geometry, and Reusable Reference Relationships) - released as `0.7.0`
610
-
611
- Additive extension of the Prompt 1 foundation above. Still not the full v0.7
612
- coding-agent workflow - no design requirements, tolerances, adequacy,
613
- binding, or fidelity evaluation yet.
614
-
615
- - **Domain** (`src/domain/externalReferenceRegions.ts`): explicit,
616
- user/configuration-authored reference-image rectangles
617
- (`ReferenceRegion { id, rectangle: {x, y, width, height} }`), origin at the
618
- reference image's top-left corner, unit reference-image pixels. Pure
619
- derived geometry (`right`/`bottom`/`centerX`/`centerY`) is always
620
- recomputed from the canonical rectangle, never separately stored. Bounded
621
- at `MAX_REFERENCE_REGIONS` (20, matching `request/request.ts`'s
622
- `MAX_TARGETS`), region ids validated against the same
623
- `^[A-Za-z0-9_-]{1,64}$` pattern as target names, unique
624
- case-insensitively, and rejected outright (never clamped) if any rectangle
625
- extends outside the owning image's bounds.
626
- - **Domain** (`src/domain/externalReferenceRegionRelationships.ts`): reuses
627
- the exact pure geometry predicates `deriveLayoutRelationships` uses for
628
- runtime targets (now exported additively) from `relationships.ts` rather
629
- than reimplemented, so reference-region geometry and runtime-target
630
- geometry can never diverge on the same underlying formula; only the
631
- geometry-only relationship families apply, since a static image exposes
632
- no DOM, scroll, or viewport evidence.
633
- - **Schema**: `ExternalReferenceArtifact` gained one additive, optional
634
- `regions?: ReferenceRegion[]` field. No schema version bump
635
- (`EXTERNAL_REFERENCE_SCHEMA_VERSION` remains `'1.0.0'`) - every Prompt 1
636
- artifact remains valid with no `regions` key at all.
637
- - **Identity**: `buildExternalReferenceRequestIdentity` gained an additive,
638
- optional trailing `regions` parameter, omitted from the hashed view
639
- entirely (not defaulted to `null`) when absent, so every Prompt 1 call
640
- site keeps producing byte-identical identity. Region content (including
641
- authored order) is identity-bearing when present.
642
- - **Application**: `importExternalReference()` validates an optional
643
- `regions` option and fails closed with the new `invalid-reference-region`
644
- diagnostic; `approveExternalReference()` carries an imported artifact's
645
- `regions` forward verbatim, never re-validating or re-deriving them.
646
- - **CLI**: `import-reference` gained an optional
647
- `--regions-file <json-file>` (`{ "regions": [...] }`, same object-root-
648
- wrapper convention as `--targets-file`); legacy invocations without it are
649
- unchanged from Prompt 1. Both commands now print a `Regions: <count>` line.
650
- - **Export/public boundary**: `src/index.ts` exports the complete new region
651
- and relationship type/constant/validator/function surface, following the
652
- same grouping order as every existing family.
653
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
654
- lint`, `npm test` (40 files, 719 tests), `npm run test:browser` (9 files,
655
- 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
656
- check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
657
- zero changes to any pre-existing test.
658
- - **Not implemented in this stage** (explicitly deferred to later v0.7
659
- prompts): selected design requirements, design tolerance semantics,
660
- reference-evidence adequacy, theme/application-state compatibility
661
- evaluation, reference-region/runtime-target binding, reference-vs-candidate
662
- fidelity evaluation, viewer, and annotation.
663
-
664
- ## v0.7 Prompt 3 status (Selected Design Requirements, Tolerance Semantics, and Reference-Evidence Adequacy) - released as `0.7.0`
665
-
666
- Additive extension of the Prompt 1/2 foundation above. Still not the full
667
- v0.7 coding-agent workflow - no runtime binding or fidelity evaluation yet.
668
-
669
- - **Domain** (`src/domain/externalReferenceRequirements.ts`): explicit,
670
- user/configuration-selected design intent over Prompt 2's `regions` -
671
- never inferred merely because a region property or relationship exists.
672
- Requirement category reuses v0.5's `AuthoredChangeScopeCategory`
673
- (`requested`/`expected-dependent`/`protected`/`preserved`) directly;
674
- `'unexpected'` remains impossible to author. Three subject kinds:
675
- `region-property` (one region + a `ReferenceRegionGeometry` field),
676
- `region-relationship` (two regions + a reused `PairwiseRelationshipKind`,
677
- geometry-only families only, no tolerance), `region-measurement` (two
678
- regions + one of six pure derived measurements - `vertical-gap`,
679
- `horizontal-gap`, `center-x-delta`, `center-y-delta`, `left-edge-delta`,
680
- `right-edge-delta` - with a required tolerance). Tolerance is a new,
681
- reference-owned type (`exact` | `absolute-reference-px` | `percent`),
682
- deliberately not a reuse of v0.5's `ContractTolerance` (whose
683
- `absolute-px` is implicitly runtime/CSS pixels). Bounded at
684
- `MAX_REFERENCE_REQUIREMENTS` (50). A requirement's `requirementId` is
685
- always system-computed from its content, never authored.
686
- - **Reference-evidence adequacy**: `deriveReferenceRequirementAdequacy()`
687
- asks only whether the reference definition itself supports every selected
688
- requirement - never whether a runtime target/candidate exists. Its own
689
- small vocabulary (`adequate`/`partial`/`inadequate`, two reason codes)
690
- deliberately does not reuse `boundedAgentContext.ts`'s `Adequacy`, which
691
- describes an unrelated runtime/static-correlation domain. Zero selected
692
- requirements is explicitly `inadequate`. Never a numeric score; reasons
693
- ordered deterministically by authored requirement position.
694
- - **Validation**: a requirement referencing an unknown region id is a
695
- construction-time failure (`invalid-reference-requirement`), never
696
- "unavailable" evidence. Two requirements sharing the exact same structural
697
- subject (regardless of category) are rejected as duplicates/conflicts -
698
- v0.5's runtime-evaluation-time conflict detector
699
- (`evaluateFrontendContract#primitivesConflict`) needs before/after
700
- observation evidence that does not exist at this stage and could not be
701
- reused safely.
702
- - **Schema**: `ExternalReferenceArtifact` gained one additive, optional
703
- `requirements?: ExternalReferenceRequirement[]` field. No schema version
704
- bump - every Prompt 1/2 artifact remains valid with no `requirements` key.
705
- - **Identity**: `buildExternalReferenceRequestIdentity` gained an additive,
706
- optional trailing `requirements` parameter, omitted from the hashed view
707
- entirely when absent, so every Prompt 1/2 call site keeps producing
708
- byte-identical identity. Requirement content (category, subject,
709
- tolerance, mode, authored order) is identity-bearing when present.
710
- - **Application**: `importExternalReference()` validates an optional
711
- `requirements` option (computing each requirement's identity from its raw
712
- authored content) and fails closed on any invalid requirement;
713
- `approveExternalReference()` carries `requirements` forward verbatim.
714
- Both now also compute and return reference-evidence adequacy.
715
- - **CLI**: `import-reference` gained an optional
716
- `--requirements-file <json-file>` (`{ "requirements": [...] }`, same
717
- object-root-wrapper convention as `--regions-file`); legacy invocations
718
- without it are unchanged. Both commands now also print
719
- `Requirements: <count>` and `Adequacy: <status>` lines.
720
- - **Export/public boundary**: `src/index.ts` exports the complete new
721
- requirement/tolerance/adequacy type/constant/validator/function surface,
722
- following the same grouping order as every existing family.
723
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
724
- lint`, `npm test` (42 files, 779 tests), `npm run test:browser` (9 files,
725
- 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
726
- check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
727
- zero changes to any pre-existing test.
728
- - **Not implemented in this stage** (explicitly deferred to later v0.7
729
- prompts): theme/application-state compatibility evaluation,
730
- reference-region/runtime-target binding, reference-vs-candidate fidelity
731
- evaluation, viewer, and annotation.
732
-
733
- ## v0.7 Prompt 4 status (Reference Applicability and Candidate-State Compatibility) - released as `0.7.0`
734
-
735
- Additive extension of the Prompt 1/2/3 foundation above. Still not the full
736
- v0.7 coding-agent workflow - no runtime binding or fidelity evaluation yet.
737
-
738
- - **Domain** (`src/domain/explicitState.ts`): a small, closed, caller/
739
- configuration-supplied state model (`theme`, `applicationState`,
740
- `authenticatedState`) shared by both `ObservationArtifact.requestConfig.explicitState`
741
- and `ExternalReferenceArtifact.applicability` - never inferred from
742
- screenshot pixels, CSS, DOM, URLs, or any other runtime signal. Labels are
743
- bounded opaque identities (`^[A-Za-z0-9_-]{1,64}$`) compared by exact,
744
- case-sensitive equality only. `authenticatedState` is a closed
745
- `'authenticated' | 'unauthenticated'` vocabulary with no field capable of
746
- holding a credential, token, or cookie.
747
- - **Domain** (`src/domain/externalReferenceApplicability.ts`): adds an
748
- optional CSS-pixel `viewport` to the shared state model - deliberately
749
- distinct from the reference image's own pixel dimensions (`image.width`/
750
- `height`), which a reference image may be captured at any resolution/DPI
751
- relative to.
752
- - **Domain** (`src/domain/externalReferenceCompatibility.ts`):
753
- `evaluateReferenceCandidateCompatibility(reference, candidate)` answers
754
- "does this reference describe the same frontend state as this candidate
755
- observation?" by reusing v0.4's own `ComparabilityResult`/`ComparabilityReason`
756
- vocabulary and a newly-extracted, shared pure helper
757
- (`assessOptionalComparabilityDimension`, exported from
758
- `comparisonEngine.ts`) rather than a parallel model. The same helper now
759
- also drives v0.4's own `evaluateComparability`, which additionally assesses
760
- theme/authenticated-state/application-state when both observations declare
761
- `explicitState` - every historical observation pair without it keeps its
762
- exact prior unassessed-only behavior (a frozen regression vector proves
763
- this). A dimension the reference constrains but the candidate omits (or
764
- vice versa) is `unassessed`, never fabricated as a match or a mismatch.
765
- - **Schema**: `ExternalReferenceArtifact` gained one additive, optional
766
- `applicability?: ExternalReferenceApplicability` field; `ObservationArtifact.requestConfig`
767
- gained one additive, optional `explicitState?: ExplicitStateDimensions`
768
- field. No schema version bump on either family.
769
- - **Identity**: `buildExternalReferenceRequestIdentity` gained an additive,
770
- optional trailing `applicability` parameter; `buildRequestIdentity` gained
771
- an additive, optional trailing `explicitState` parameter - both omitted
772
- from their hashed views (never `null`) when absent, so every earlier call
773
- site keeps producing byte-identical identity.
774
- - **CLI**: `import-reference` gained an optional `--applicability-file <json-file>`;
775
- `observe` gained an optional `--state-file <json-file>` (both unwrapped
776
- raw-object files, following `--scroll-scenario-file`'s exact convention).
777
- `import-reference`/`approve-reference` now also print an
778
- `Applicability: declared|none` line.
779
- - **Export/public boundary**: `src/index.ts` exports the complete new
780
- explicit-state/applicability/compatibility type/constant/validator/function
781
- surface, following the same grouping order as every existing family.
782
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
783
- lint`, `npm test` (45 files, 857 tests), `npm run test:browser` (9 files,
784
- 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
785
- check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
786
- zero changes to any pre-existing test.
787
- - **Not implemented in this stage** (explicitly deferred to later v0.7
788
- prompts): reference-region/runtime-target binding, reference-vs-candidate
789
- fidelity evaluation, bounded fidelity context, the end-to-end correction
790
- workflow, viewer, and annotation.
791
-
792
- ## v0.7 Prompt 5 status (Explicit Reference-Region <-> Runtime-Target Binding) - released as `0.7.0`
793
-
794
- Additive extension of the Prompt 1-4 foundation above. Still not the full
795
- v0.7 coding-agent workflow - no fidelity evaluation yet.
796
-
797
- - **Domain** (`src/domain/externalReferenceRuntimeBinding.ts`):
798
- `evaluateReferenceRuntimeBindings(reference, candidate, declarations)`
799
- answers "which stable v0.2 runtime target does this candidate resolve for
800
- each explicitly declared reference region?" A binding declaration
801
- (`{referenceRegion, runtimeTarget}`) is explicit user/configuration input
802
- - never inferred from geometry, matching names, or source code; two
803
- strings with the same textual value in the reference-region and
804
- runtime-target identity domains never bind to each other merely because
805
- they match. Reuses `evaluateReferenceCandidateCompatibility` (Prompt 4) as
806
- a hard gate and `targetPresence` (v0.4, exported additively) as the sole
807
- "how do I read a `TargetEvidenceRecord`'s resolution" rule - no second
808
- target resolver, no browser launch. Status vocabulary: `bound` / `ambiguous`
809
- / `unavailable`, each with closed reason codes. An unknown reference
810
- region fails the whole evaluation closed (structural, candidate-independent);
811
- an unknown/ambiguous/unavailable runtime target produces a per-declaration
812
- `unavailable`/`ambiguous` result, never a guessed target. Bounded at
813
- `MAX_REFERENCE_RUNTIME_BINDINGS` (20).
814
- - **Persistence**: none - a pure, on-demand function over already-persisted/
815
- in-memory evidence, no new artifact family.
816
- - **CLI**: none added - deliberately deferred to Prompt 6, the capability's
817
- first concrete consumer.
818
- - **Export/public boundary**: `src/index.ts` exports the complete new
819
- binding type/constant/validator/function surface.
820
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
821
- lint`, `npm test` (46 files, 889 tests), `npm run test:browser` (9 files,
822
- 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
823
- check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
824
- zero changes to any pre-existing test.
825
- - **Not implemented in this stage** (explicitly deferred to later v0.7
826
- prompts): reference-vs-candidate fidelity evaluation, bounded fidelity
827
- context, the end-to-end correction workflow, viewer, and annotation.
828
-
829
- ## v0.7 Prompt 6 status (Structured Reference-vs-Candidate Fidelity Evaluation) - released as `0.7.0`
830
-
831
- Additive extension of the Prompt 1-5 foundation above. The first point in
832
- the v0.7 stack where a reference's authored expectation is actually
833
- compared against live candidate evidence.
834
-
835
- - **Domain** (`src/domain/externalReferenceFidelity.ts`):
836
- `evaluateReferenceCandidateFidelity(reference, candidate, bindings)`
837
- evaluates in a frozen order - reference/candidate structural validation ->
838
- Prompt 3 adequacy -> Prompt 4 compatibility -> Prompt 5 binding ->
839
- per-requirement evaluation - and never fabricates an ordinary PASS/FAIL
840
- past an earlier blocking gate: overall `state` is `'not-evaluated'` /
841
- `'pass'` / `'fail'`, with `blockedBy` preserved for the first two gates.
842
- Establishes one explicit, deterministic reference-image-pixel <->
843
- CSS-pixel coordinate scale from `reference.applicability.viewport` and the
844
- image's own dimensions, gated by an independent (never a design-tolerance)
845
- aspect-ratio coherence check. Reuses Prompt 3 tolerances
846
- (`exact`/`absolute-reference-px`/`percent`) and v0.4's
847
- `deriveLayoutRelationships` (family-scoped lookup, the same bug class
848
- Prompt 3 already fixed) unchanged - no duplicated geometry or
849
- comparability logic.
850
- - **Persistence**: none - a pure, on-demand function; the CLI-facing
851
- `evaluateReferenceCandidateFidelityFromArtifactRoots` application-service
852
- wrapper only reads already-persisted artifacts, it does not write one.
853
- - **CLI**: `evaluate-reference-fidelity --reference --candidate
854
- [--bindings-file] [--enforce]` - the CLI surface Prompt 5 deferred,
855
- following `evaluate-contract`'s exact `--enforce`/exit-code precedent.
856
- Persists nothing; there is no `--output` flag.
857
- - **Export/public boundary**: `src/index.ts` exports the complete new
858
- fidelity-result type/constant/validator/function surface plus the
859
- application-service wrapper.
860
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
861
- lint`, `npm test` (48 files, 927 tests), `npm run test:browser` (9 files,
862
- 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
863
- check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
864
- zero changes to any pre-existing test.
865
- - **Not implemented in this stage** (explicitly deferred to later v0.7
866
- prompts): bounded fidelity context integration, the end-to-end correction
867
- workflow, viewer, and annotation.
868
-
869
- ## v0.7 Prompt 7 status (Bounded Reference-Fidelity Projection and v0.6 Bounded-Agent-Context Integration) - released as `0.7.0`
870
-
871
- Additive extension of the v0.6 bounded-agent-context architecture and the
872
- Prompt 1-6 foundation above.
873
-
874
- - **Domain** (`src/domain/referenceFidelityProjection.ts`):
875
- `projectReferenceFidelity()` selects, prioritizes (failed-required, then
876
- unavailable-required, then other non-pass), and bounds Prompt 6's
877
- non-passing requirement results (`MAX_FIDELITY_MISMATCHES`, 15) and
878
- passing protected/preserved context (`MAX_FIDELITY_PROTECTED_CONTEXT`, 10)
879
- for a coding agent's bounded context - passing requirements are never
880
- dumped by default.
881
- - **Integration**: `projectBoundedAgentContext` (v0.6) itself, not a second
882
- context system, gained one new optional input (`fidelity`,
883
- `fidelityRequired?`): fidelity-relevant runtime targets fold into the
884
- exact same required/permitted-target allocation and omission/truncation/
885
- adequacy machinery v0.5 contract clauses already compete in, so a
886
- `not-evaluated` fidelity always degrades adequacy away from `'adequate'`,
887
- never silently reported as "no problems". A new `fidelity?:
888
- BoundedReferenceFidelityProjection` field on `BoundedAgentContextArtifact`
889
- mirrors `correlations?`'s own additive precedent - no schema version bump.
890
- v0.6's own runtime/static correlation is reused entirely unchanged.
891
- - **Identity**: `buildBoundedAgentContextRequestIdentity` gained a final
892
- optional `fidelity` parameter (omit-when-absent; verified byte-identical
893
- for every pre-Prompt-7 call site).
894
- - **Persistence / CLI**: none - bounded agent context remains
895
- library-only, exactly as v0.6 established it.
896
- - **Export/public boundary**: `src/index.ts` exports the complete new
897
- fidelity-projection type/constant/function surface.
898
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
899
- lint`, `npm test` (49 files, 981 tests), `npm run test:browser` (9 files,
900
- 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
901
- check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
902
- zero changes to any pre-existing test.
903
- - **Not implemented in this stage** (explicitly deferred to Prompt 8):
904
- the end-to-end coding-agent correction workflow, viewer, and annotation.
905
-
906
- ## v0.7 Prompt 8 status (Controlled End-to-End External-Reference Coding-Agent Correction Workflow) - released as `0.7.0`
907
-
908
- The first complete v0.7 correction cycle, composing every Prompt 1-7 and
909
- v0.1/v0.4/v0.5/v0.6 owner - this completes the v0.7 (End-to-End Coding-Agent
910
- Frontend Change Review) milestone's core workflow.
911
-
912
- - **Domain** (`src/domain/referenceCorrectionWorkflow.ts`,
913
- `referenceCorrectionIdentity.ts`): `prepareReferenceCorrection()`
914
- evaluates the approved reference against the current (pre-change)
915
- observation (Prompt 6) and, when evaluable, projects a bounded
916
- coding-agent handoff (Prompt 7/v0.6) - a `not-evaluated` fidelity is
917
- reported as `status: 'blocked-not-evaluated'`, never a fabricated
918
- handoff. `reviewReferenceCorrectionAttempt()` composes one overall result
919
- from a fresh post-edit candidate: `compareObservations` (v0.4) ->
920
- `evaluateReferenceCandidateFidelity` (Prompt 6) -> `evaluateFrontendContract`
921
- (v0.5) -> overall `'not-evaluated'`/`'pass'`/`'fail'`, where `'pass'`
922
- requires *both* reference fidelity `'pass'` *and* v0.5 contract evaluation
923
- `'PASS'` - matching the design reference is necessary but never
924
- sufficient. Review identity is a deterministic hash of
925
- `{referenceRequestId, baselineObservationId, baselineContractId,
926
- baselineContractClauses, changeContractId, changeContractClauses,
927
- bindingDeclarations}` (including actual contract *clause content*, not
928
- merely the caller-authored contract id labels) - `reviewReferenceCorrectionAttempt`
929
- recomputes and rejects any call whose supplied review id does not match,
930
- enforcing "no hidden baseline change" structurally. Attempt identity is a
931
- deterministic hash of `{reviewRequestId, candidateObservationId}`. Both
932
- functions are pure, so no prior attempt can ever be overwritten.
933
- - **External implementation boundary**: absolute - neither this module nor
934
- anything it calls opens, parses, or writes any target source file; real
935
- candidate capture remains the caller's own responsibility through the
936
- existing, unmodified `runBrowserCapture`/`buildObservationArtifact`
937
- pipeline. No automatic baseline/reference approval ever occurs.
938
- - **Persistence / CLI**: none - both operations remain pure, in-memory,
939
- programmatic functions; no `--output` flag, no new command.
940
- - **Real-Chromium proof** (`tests/browser/referenceCorrectionWorkflow.test.ts`):
941
- a deterministic, test-only "controlled external actor" (living entirely
942
- outside `src/`) edits a disposable, repository-local copy of a tracked
943
- HTML fixture template, proving a full success correction, a protected-
944
- regression case (candidate visually matches the reference but a real
945
- Chromium-observed element becomes hidden - still overall `FAIL`), a
946
- two-attempt correction iteration (both attempts traceable to the same
947
- baseline), and an incompatible-viewport blocking case that never produces
948
- a handoff. The tracked template remains byte-identical before and after.
949
- - **Export/public boundary**: `src/index.ts` exports the complete new
950
- workflow/identity type/constant/function surface.
951
- - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
952
- lint`, `npm test` (50 files, 1000 tests), `npm run test:browser` (10
953
- files, 124 tests), `npm run test:security`, `npm run build`, `npm run
954
- check:docs`, `git diff --check`, `npm pack --dry-run`, and a real
955
- installed-packed-candidate smoke all pass with zero regressions to any
956
- pre-existing test.
957
- - **Not implemented in this stage** (remain future, v0.8+): interactive
958
- viewer, structured visual annotation, and automatic baseline/reference
959
- approval (approval remains an explicit, separate action through the
960
- existing `approve-baseline`/`approve-reference` commands).
961
-
962
- ## v0.8 status (Interactive Local Observation Viewer) - released as `0.8.0`
963
-
964
- All eight v0.8 implementation batches have passed
965
- (`IMPLEMENTATION_BATCHES_STATUS: ALL_8_IMPLEMENTATION_BATCHES_PASS`), followed
966
- by a hardened documentation/implementation-completeness audit and formal
967
- pre-release readiness (cross-platform Windows/Linux/macOS packed-candidate
968
- validation, security audit, code-rot audit - see
969
- `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`).
970
- No schema version changed for v0.8, and no CLI command from v0.1-v0.7 was
971
- altered.
972
-
973
- - **Batch 1** (`docs/reports/v0.8-viewer-runtime-pwa-batch1.md`) froze the
974
- version-start architecture decisions (React + TypeScript + Vite; normal
975
- browser + Node-backed loopback server + installable PWA using the same
976
- application; ephemeral viewer adapters over existing canonical readers,
977
- never a new persisted viewer artifact) and implemented the `view` CLI
978
- command (`--root`, `--port`, `--no-open`), the loopback-only (`127.0.0.1`)
979
- Node viewer server, the built React/Vite/PWA shell (service worker,
980
- manifest, app-shell precache with an `/api/` cache-boundary denylist), and
981
- one minimal read-only status endpoint. `npm run build` gained the
982
- `dist/viewer` build step.
983
- - **Batch 2** (`v0.8-evidence-index-readers-batch2.md`) added bounded,
984
- metadata-first evidence discovery (`GET /api/index`) across every existing
985
- artifact family, honest support-state classification
986
- (supported/unsupported-version/invalid-structure/unrecognized-kind/
987
- malformed-json/unreadable), and on-demand full-artifact/media loading
988
- (`GET /api/artifacts/<handle>`, `GET /api/media/<handle>/<role>`) with
989
- path-containment/traversal safety.
990
- - **Batch 3** (`v0.8-observation-svg-inspection-batch3.md`) added the
991
- observation screenshot/SVG-overlay workspace: runtime target geometry,
992
- semantics, visibility, overflow, scroll evidence, and on-demand layout
993
- relationships (`GET /api/observations/<handle>/relationships`, reusing the
994
- existing canonical `deriveLayoutRelationships` at its one sanctioned
995
- viewer-server call site).
996
- - **Batch 4** (`v0.8-comparison-contract-inspection-batch4.md`) added
997
- before/after comparison and contract/change-scope inspection
998
- (`GET /api/comparisons/<handle>/view`, `GET /api/evaluations/<handle>/view`),
999
- exact-identity linked-evidence resolution (never fuzzy matching), and the
1000
- required protected/preserved-failure safety case (a locally successful
1001
- requested change alongside a genuine protected/preserved regression,
1002
- shown as overall `FAIL`, never masked).
1003
- - **Batch 5** (`v0.8-reference-candidate-inspection-batch5.md`) added
1004
- external-reference and reference/candidate inspection: reference image and
1005
- region overlays in the reference's own pixel coordinate domain, explicit
1006
- (never auto-selected) candidate selection, reference/candidate
1007
- compatibility, adequacy, and applicability display.
1008
- - **Batch 6** (`v0.8-binding-fidelity-interaction-batch6.md`) added
1009
- explicit-binding cross-selection (reference region ↔ runtime target, only
1010
- through an explicit `--bindings-file` declaration, never inferred from
1011
- matching names), independent bounded (`1x`-`8x`) zoom/pan per pane,
1012
- conditional view lock (enabled only when compatibility/coordinate-mapping
1013
- genuinely permit it), and on-demand reference-fidelity evaluation
1014
- (`not-evaluated`/`pass`/`fail`) shown alongside, never merged into, any
1015
- selected contract evaluation's own verdict.
1016
- - **Batch 7** (`v0.8-bounded-context-correlation-batch7.md`) added the
1017
- `--context-file` input and a dedicated "Bounded context" mode: session-only
1018
- bounded-agent-context display (identity, adequacy, omissions/truncations
1019
- with required loss visually distinguished from optional loss,
1020
- runtime/static correlation - `correlated`/`ambiguous`/`unavailable`,
1021
- never "owner" language), safe raw-evidence navigation, and explicit
1022
- non-ownership/non-rebuild language. The viewer never calls
1023
- `projectBoundedAgentContext`, `deriveRuntimeStaticCorrelations`, or
1024
- `attachRuntimeStaticCorrelations` - it only displays the exact context it
1025
- was started with.
1026
- - **Batch 8** (`v0.8-integrated-viewer-acceptance-batch8.md`, the final
1027
- implementation batch) integrated and hardened the above rather than adding
1028
- new features: closed three named real-browser coverage gaps (many
1029
- reference regions bound to one runtime target must all cross-highlight;
1030
- reference-fidelity FAIL alongside a genuine frontend-contract PASS for the
1031
- same candidate must display independently with no hidden precedence; a
1032
- bounded context whose sources include two observations sharing a stable
1033
- target id must list every matching source observation, never one); fixed a
1034
- real accessibility gap (a cross-highlighted, non-selected region/target
1035
- rect now exposes `data-highlighted` plus an `aria-label` suffix to
1036
- assistive technology, without disturbing `aria-pressed`'s existing
1037
- single-selection semantics); added the first live-browser PWA proof suite
1038
- (real service-worker registration, zero `/api/` cache-storage entries, and
1039
- a hard server-down "stale evidence must never be presented as current"
1040
- gate, which held); and proved the actual packed-and-installed npm
1041
- candidate (not just the source checkout) works end-to-end through a real
1042
- browser, with read-only evidence-root integrity confirmed via before/after
1043
- content hashing. Standalone/installed-PWA proof did not exceed CDP
1044
- command-acceptance (the emulated display-mode feature was not observed to
1045
- take effect) - recorded honestly as a residual gap, not overstated as
1046
- actual OS-level installation verification.
1047
-
1048
- **Architectural invariants proven across all eight batches** (re-audited in
1049
- this documentation/completeness stage): no second observer, relationship
1050
- engine, comparison engine, contract engine, reference model,
1051
- reference-evaluation engine, correlation implementation, or bounded-context
1052
- builder exists anywhere in `src/viewerServer` or `viewer/src` - every
1053
- canonical engine function the viewer displays results from is called from at
1054
- most one designated server-side call site, and several (`compareObservations`,
1055
- `evaluateFrontendContract`, `projectBoundedAgentContext`,
1056
- `deriveRuntimeStaticCorrelations`, `attachRuntimeStaticCorrelations`) are
1057
- never called by the viewer at all. The viewer never runs
1058
- `@dailephd/my-dev-kit`, never mutates target source or any Observer
1059
- artifact, never persists a new viewer-owned evidence family, and every route
1060
- rejects non-`GET`/`HEAD` methods. (That was the complete v0.8 surface. v0.9
1061
- later adds exactly three project-aware authoring `POST` routes. See "v0.9
1062
- status" below.)
1063
-
1064
- **Validated on the canonical worktree**: `npm run typecheck`, `npm run
1065
- lint`, `npm test`, `npm run build`, `npm run check:docs`, `npm run
1066
- test:browser`, and `npm run test:security` all pass - see "Post-edit
1067
- validation" in
1068
- `docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md`
1069
- for the completeness-stage counts, and
1070
- `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`
1071
- for the formal cross-platform/security readiness stage that followed.
1072
-
1073
- Formal Windows/Linux/macOS cross-platform pre-release validation of the
1074
- viewer/PWA surface (through `.github/workflows/pre-release-readiness.yml`,
1075
- now covering v0.1-v0.8) and formal pre-release security review of the
1076
- viewer surface both passed - see the readiness report above, including the
1077
- one security finding it found and fixed (a symlinked-media evidence-root
1078
- escape in the viewer's media route).
1079
-
1080
- ## v0.9 status (Human Visual Annotation and Design-Intent Capture) - released as 0.9.0
1081
-
1082
- v0.9 is implemented against the frozen plan
1083
- `docs/plans/v0.9-implementation-plan.md` and released as
1084
- `@dailephd/my-frontend-observer@0.9.0`.
1085
-
1086
- - **Prompt 1** (`docs/reports/v0.9-batch1-visual-annotation-foundation.md`)
1087
- added the `VisualAnnotationArtifact` domain (schema `1.0.0`), structured
1088
- point/rectangle/line/arrow/note marks, runtime and reference coordinate
1089
- spaces, explicit associations, candidate/confirmed interpretation,
1090
- deterministic identity, the atomic writer, the canonical reader, the
1091
- persistence service, and the derived overlay SVG.
1092
- - **Prompt 2**
1093
- (`docs/reports/v0.9-batch2-viewer-annotation-authoring-boundary.md`) added
1094
- viewer discovery of annotations, the source-resolving annotation view
1095
- route, the verified overlay media role, and the project-aware authoring
1096
- boundary with `POST /api/annotations`. `view --root` stays read-only.
1097
- - **Prompt 3**
1098
- (`docs/reports/v0.9-batch3-runtime-screenshot-annotation-authoring.md`)
1099
- added runtime screenshot annotation in runtime CSS pixels with zoom, pan,
1100
- keyboard selection, save, reload, revisions, and stale-parent conflicts.
1101
- - **Prompt 4**
1102
- (`docs/reports/v0.9-batch4-external-reference-annotation-authoring.md`)
1103
- added external-reference annotation in reference-image pixels, candidate
1104
- region create and refine proposals, candidate reference requirements, and
1105
- informational and asset-sensitive intent.
1106
- - **Prompt 5**
1107
- (`docs/reports/v0.9-batch5-runtime-intent-contract-promotion.md`) added
1108
- runtime intent, explicit confirmation, promotion of selected confirmed
1109
- `move`/`resize`/`preserve` intent into a canonical per-change contract
1110
- (`POST /api/annotations/:handle/promote-contract`), optional explicit
1111
- project contract activation, and `.tmp-*` discovery exclusion. Confirmed
1112
- `remove` intent is honestly non-promotable.
1113
- - **Prompt 6** (`docs/reports/v0.9-batch6-reference-materialization.md`)
1114
- added materialization of selected confirmed reference regions and
1115
- requirements into a new imported external-reference revision
1116
- (`POST /api/annotations/:handle/materialize-reference`). The source is never
1117
- changed and nothing is approved automatically.
1118
- - **Prompt 7** (`docs/reports/v0.9-batch7-integrated-acceptance.md`) added the
1119
- integrated real-Chromium acceptance suite
1120
- (`tests/browser/v09IntegratedAcceptance.test.ts`), the packed installed
1121
- annotation smoke (`scripts/ci/runPackedV09AnnotationSmoke.mjs`), its step in
1122
- the pre-release readiness matrix, and this documentation reconciliation.
1123
-
1124
- Current versions: package `0.9.0`, viewer protocol `1.3.0`, visual annotation
1125
- schema `1.0.0`, frontend contract schema `1.0.0`, external-reference schema
1126
- `1.0.0`. No other schema changed.
1127
-
1128
- Invariants: annotations are evidence, not contracts. Only selected confirmed
1129
- supported intent is promoted or materialized, always through the existing
1130
- canonical contract and external-reference services. The existing contract,
1131
- reference relationship, adequacy, and fidelity evaluators remain the only
1132
- source of verdicts. Observer never edits target source, never approves a
1133
- baseline or reference automatically, and never updates project reference
1134
- acceptance.
1135
-
1136
- Validation state: the full local validation suite, the integrated acceptance
1137
- suite, and all three packed installed-candidate smokes passed locally on
1138
- Windows. See the Prompt 7 report for exact results. A cross-platform
1139
- pre-release readiness run passed on Windows, Linux, and macOS for the Prompt 7
1140
- commit `a78a058` (`docs/reports/v0.9-pre-release-readiness.md`). That run is
1141
- historical evidence only. It did not contain the demo and tutorial commits
1142
- described below, so it is not readiness evidence for the final candidate.
1143
-
1144
- ### v0.9 demo and tutorials (release support, not product behavior)
1145
-
1146
- - **Demo foundation** (commit `59ae009`,
1147
- `docs/reports/v0.9-demo-foundation.md`): a deterministic demo application
1148
- in `examples/v09-demo/` with ten stable region names, nine frozen states, a
1149
- loopback-only demo server, a disposable-target materializer, and a fixed
1150
- 1440x900 reference PNG.
1151
- - **Tutorial integration** (commit `6895b30`,
1152
- `docs/reports/v0.9-tutorial-integration.md`): four `TutorialScenarioV1`
1153
- scenarios in `examples/v09-demo/tutorials/`, a per-run target-contract
1154
- generator, and a prepare command that builds each disposable target through
1155
- the canonical `init`, `capture`, contract, and reference commands. The only
1156
- product change was two optional `data-testid` attributes on the viewer
1157
- drawing surfaces.
1158
- - **End-to-end acceptance**
1159
- (`docs/reports/v0.9-tutorial-end-to-end-acceptance.md`): all four tutorials
1160
- regenerated from clean targets with `@dailephd/my-dev-kit-lab@0.4.9`,
1161
- structural and content acceptance, canonical evidence checks, and a full
1162
- local regression. Scenario narration, reading pauses, and screenshot
1163
- requests were corrected in this stage. Human visual review of the videos
1164
- was completed and approved before release.
1165
- - **Final pre-release readiness**
1166
- (`docs/reports/v0.9-final-pre-release-readiness.md`, with corrections in
1167
- `docs/reports/v0.9-final-readiness-corrections.md`): one exact candidate
1168
- package passed the packed observation, viewer and v0.9 annotation smokes and
1169
- all four tutorials on Windows, Linux and macOS, using
1170
- `@dailephd/my-dev-kit-lab@0.4.9` semantic `select-option` for native
1171
- selects.
1172
-
1173
- The four scenarios are annotation basics, runtime intent to an active change
1174
- contract, reference authoring, and reference materialization. After each run
1175
- the canonical evidence is read directly from the disposable target. The checks
1176
- prove, for example, that only the two selected clauses were promoted, that
1177
- `remove` and `inspect` never became clauses, and that a materialized reference
1178
- revision is `imported`, supersedes its approved source, and reuses the source
1179
- image bytes unchanged.
1180
-
1181
- `my-dev-kit-lab` is an external tool invoked through `npx`. It is not an
1182
- Observer dependency, and Observer has no tutorial command, recorder, subtitle
1183
- writer, or tutorial manifest schema. `examples/v09-demo/` is excluded from the
1184
- npm package.
1185
-
1186
- ## Not implemented
1187
-
1188
- - v0.5 baseline-selection/discovery policy (the caller must supply which
1189
- baseline to approve/evaluate against; there is no "find the current
1190
- baseline" command), source ownership, and orchestrator/lab product
1191
- integration all remain unimplemented in this repository.
1192
- (v0.6's bounded runtime projection and runtime/static correlation, the
1193
- complete v0.7 external-reference correction workflow described above, and
1194
- the v0.8 interactive viewer described in "v0.8 status" above, *are* now
1195
- implemented.) A CLI surface for Prompt 8's correction workflow specifically
1196
- remains unimplemented by design (programmatic-only, library-level use is
1197
- the current supported entry point) - see "v0.7 Prompt 8 status" above.
1198
- The full graphical human-LLM workflow (v0.10) remains future and
1199
- unimplemented. Structured visual annotation (v0.9) is implemented and
1200
- released as `0.9.0` - see "v0.9 status" above.
1201
-
1202
- ## Next target
1203
-
1204
- v0.1-v0.9 are implemented, validated, and released (`0.1.0`, `0.2.0`,
1205
- `0.3.0`, `0.4.0`, `0.5.0`, `0.6.0`, `0.7.0`, `0.8.0`, `0.8.1`, `0.9.0`). v0.7 (End-to-End
1206
- Coding-Agent Frontend Change Review) is fully implemented and released: the
1207
- external-reference artifact foundation, explicit reference
1208
- regions/relationships, selected design requirements/tolerance
1209
- semantics/reference-evidence adequacy, reference applicability
1210
- and candidate-state compatibility, explicit reference-region/
1211
- runtime-target binding, structured reference-vs-candidate
1212
- fidelity evaluation, bounded reference-fidelity projection into
1213
- the existing v0.6 bounded-agent-context, and the controlled
1214
- end-to-end correction workflow with real-Chromium proof are all
1215
- implemented and released as package version `0.7.0`, following a completed
1216
- pre-release readiness, cross-platform, and security validation stage - see
1217
- `docs/ROADMAP.md` for v0.7's full scope,
1218
- `docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md`
1219
- for the completeness audit, and
1220
- `docs/reports/v0.7-pre-release-readiness.md` for the cross-platform
1221
- readiness validation that preceded this release.
1222
-
1223
- v0.8 (Interactive Local Observation Viewer) is fully implemented, tested,
1224
- and released - see "v0.8 status" above. v0.8.1 was released as
1225
- `@dailephd/my-frontend-observer@0.8.1`. All
1226
- eight implementation batches, the hardened documentation/implementation-
1227
- completeness audit, and formal pre-release readiness (cross-platform and
1228
- security validation) have passed - see `docs/ROADMAP.md` for v0.8's full
1229
- scope,
1230
- `docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md`
1231
- for the completeness audit, and
1232
- `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`
1233
- for the cross-platform readiness validation that preceded this release.
1234
-
1235
- v0.9 (structured visual annotation) is released as
1236
- `@dailephd/my-frontend-observer@0.9.0` - see "v0.9 status" above. The next
1237
- target is v0.10 (full graphical human-LLM workflow), which remains future and
1238
- unimplemented - see `docs/ROADMAP.md`.
1
+ # Current State
2
+
3
+ v0.10.1 is the current release of `@dailephd/my-frontend-observer`.
4
+ Formal Windows, Linux, and macOS exact-candidate readiness, security checks,
5
+ and PWA gates passed before release. The package version is `0.10.1`.
6
+ ECO-00 was adopted on 2026-09-25. The next planned Observer version is
7
+ `v0.11.0` (OBS-DIAG-01), followed by the adopted v0.12.0-v0.14.0 controlled-state,
8
+ performance-evidence, and bounded browser/viewport milestones. These are planned
9
+ only; they do not change the current v0.10.1 runtime surface.
10
+
11
+ ## v0.10.1 maintenance status
12
+
13
+ v0.10.1 is released as package version `0.10.1`. The implementation was
14
+ completed at `82dc7745b1935b827a57870ff9a942d166d4cca5`; exact-candidate
15
+ readiness passed on `f915d693ff697399704269a10145a791ccd4e523` in hosted run
16
+ `37354455573`, attempt 2 (7/7 jobs). Project-aware `check` replays only a
17
+ validated baseline's optional
18
+ `scrollScenario` and caller-declared `explicitState` into candidate capture.
19
+ URL, viewport, targets, and ordinary capture settings remain project-config
20
+ owned. There is no project-config, observation, comparison, or check-result
21
+ schema change; no CLI change; and no dependency change. The downstream
22
+ `iworkhere.space` v0.3.0 candidate
23
+ `b0ee1bb251571ce2f83b08c55285a12ee68dc4c4` passed all ten document Observer
24
+ lanes with comparable results, zero differences, and passing configured
25
+ contracts. This is consumer validation evidence; it does not mean that
26
+ `iworkhere.space` v0.3.0 is released.
27
+
28
+ The full Visual Change workflow supports actual-frontend and approved-reference
29
+ entry, structured intent, explicit activation, bounded coding-agent handoff,
30
+ immutable check attempts and correction, PASS-only human acceptance, and
31
+ separate governance. The Viewer discovers installed-package workflow evidence.
32
+ Observer never edits source or performs automatic approval. Schemas remain
33
+ independently versioned: observation `1.2.0`, comparison `1.0.0`, frontend
34
+ contract `1.0.0`, evaluation `1.0.0`, bounded-agent-context `1.0.0`,
35
+ external-reference `1.0.0`, visual annotation `1.0.0`, visual-change workflow
36
+ `1.0.0`, handoff `1.0.0`; Viewer protocol remains `1.3.0`.
37
+ v0.9 (Human Visual Annotation and Design-Intent Capture) adds structured visual
38
+ annotation to the project-aware viewer. It passed integrated real-Chromium
39
+ acceptance and final exact-candidate pre-release readiness on Windows, Linux
40
+ and macOS, including all four tutorials. The viewer protocol is `1.3.0` and the
41
+ visual annotation schema is `1.0.0`. Project aliases, `init`, `capture`,
42
+ project-aware `view`, and `check` orchestration from v0.8.1 remain implemented,
43
+ and the package is MIT licensed. The
44
+ repository also holds a deterministic demo and four tutorial scenarios for
45
+ v0.9, recorded by the external `@dailephd/my-dev-kit-lab@0.4.9` tool. See
46
+ "v0.9 status" below.
47
+
48
+ The project is published at package version `0.10.1` (roadmap v0.10, Full
49
+ Visual Human–LLM Frontend Change Workflow; the preceding v0.9.1 maintenance
50
+ release was PWA Hard-Gate Isolation and Reproducible Security Acceptance, and
51
+ the v0.9 release was Human Visual Annotation and Design-Intent Capture;
52
+ observation schema `1.2.0`;
53
+ comparison schema `1.0.0`; frontend contract schema `1.0.0`; evaluation
54
+ artifact schema `1.0.0`; bounded-agent-context schema `1.0.0`;
55
+ external-reference schema `1.0.0`; visual annotation schema `1.0.0`). v0.9.0
56
+ added the visual annotation schema and did not change any other canonical
57
+ evidence schema version. v0.8.1 did not change any canonical evidence schema
58
+ version either; see "v0.8 status" below for the final, complete v0.8 viewer
59
+ state.
60
+
61
+ ## v0.9.1 maintenance status
62
+
63
+ Status: released and published as `@dailephd/my-frontend-observer@0.9.1`.
64
+ No production code changed.
65
+
66
+ Result of the implementation:
67
+
68
+ 1. The original failure was reproduced. Selected alone, the hard gate failed at
69
+ the offline reload with `net::ERR_CONNECTION_REFUSED`.
70
+ 2. Root cause, part one: the old readiness check was
71
+ `registration?.active !== undefined`. While the worker was still installing,
72
+ `active` was `null` and the page had no controller. Because
73
+ `null !== undefined` is true, the check passed and the server was closed
74
+ before the worker controlled the page or finished precaching.
75
+ 3. Root cause, part two: the gate shared a server, evidence root, and a fixed
76
+ persistent Chromium profile with earlier tests. In normal file order those
77
+ tests had already activated a controlling worker, which hid the defect.
78
+ 4. The hard gate now owns a fresh evidence root, viewer server, temporary
79
+ persistent profile, and BrowserContext. No PWA test uses the fixed
80
+ `.my-dev-kit-workflow` profile any more.
81
+ 5. The gate proves service-worker activation (`registration.active !== null`)
82
+ and current-page control (`navigator.serviceWorker.controller !== null`)
83
+ as separate facts.
84
+ 6. It proves the app shell is in the Workbox precache and that no `/api/`
85
+ request is in Cache Storage.
86
+ 7. It proves the server is down with a direct Node-side request before the
87
+ offline reload.
88
+ 8. After the reload, the shell renders, the evidence list shows its explicit
89
+ unavailable state, and the previously visible evidence identity is absent.
90
+ 9. `npm run test:pwa-hard-gate` runs the gate alone. `npm run test:security`
91
+ now ends with it. It passes repeatedly, and the full PWA file, browser suite,
92
+ and security suite pass.
93
+ 10. Production PWA behavior is unchanged.
94
+
95
+ Evidence: `docs/reports/v0.9.1-batch1-pwa-hard-gate-isolation.md` and
96
+ `docs/reports/v0.9.1-batch2-hard-gate-validation-integration.md`.
97
+
98
+ The historical planning background follows.
99
+
100
+ A post-release test-isolation defect has been identified in
101
+ `tests/browser/pwaHardening.test.ts`. The PWA server-down test labeled
102
+ `HARD GATE` passes in the normal full-file/full-suite execution but fails
103
+ when selected independently with Vitest `-t`. The current test shares a
104
+ persistent Chromium context/profile with earlier tests, and its own setup proves
105
+ that a service-worker registration is active without independently proving all
106
+ of the state the server-down experiment needs: that the current page is
107
+ controlled, that the application shell is actually precached, and that no
108
+ historical profile/cache state was inherited.
109
+
110
+ This is currently classified as a test-isolation defect, not a demonstrated
111
+ production PWA regression. The released safety contract remains unchanged:
112
+ application-shell caching may keep the viewer shell available while evidence
113
+ and media remain server-backed, and stale evidence must never be presented as
114
+ current after the server is unavailable. No production PWA code change is
115
+ authorized unless a corrected fresh-state hard-gate experiment first
116
+ demonstrates a real runtime failure.
117
+
118
+ The completed v0.9.1 maintenance patch was governed by the frozen implementation
119
+ plan `docs/plans/v0.9.1-implementation-plan.md`. It made the hard gate own fresh
120
+ disposable evidence/server/browser-profile state, explicitly prove service-worker
121
+ control and shell/API cache preconditions, explicitly prove the server is
122
+ unavailable before the offline reload, and add an isolated execution gate so the
123
+ same test passes by itself as well as inside the full browser and security
124
+ suites.
125
+
126
+ v0.8 (Interactive Local Observation Viewer) is fully implemented, tested,
127
+ formally cross-platform/security validated, and released. All eight v0.8
128
+ implementation batches, the hardened documentation/implementation-
129
+ completeness audit, and formal pre-release readiness (Windows/Linux/macOS
130
+ cross-platform packed-candidate validation, security audit, code-rot audit)
131
+ all passed - see
132
+ `docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md`
133
+ and
134
+ `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`.
135
+
136
+ ## Greenfield foundation established
137
+
138
+ The retained repository contains:
139
+
140
+ - Node.js 24+ and TypeScript ESM package configuration;
141
+ - TypeScript build and typecheck configuration;
142
+ - ESLint configuration;
143
+ - a Vitest runner configured to report honestly when no tests exist;
144
+ - a safe `dist/` clean script;
145
+ - documentation validation;
146
+ - package allowlisting;
147
+ - `src/cli.ts` and `src/index.ts`, the package/library entry points originally
148
+ established by the selected TypeScript CLI starter profile;
149
+ - complete repository-local Project Description, Project Milestones, ROADMAP,
150
+ and standardized documentation.
151
+
152
+ The package bin (`src/cli.ts`) now exposes the real current public CLI
153
+ surface described below: the five low-level commands released through `0.6.0`
154
+ (`observe`, `compare`, `approve-baseline`, `save-change-contract`,
155
+ `evaluate-contract`); three reference commands released in `0.7.0`
156
+ (`import-reference`, `approve-reference`, `evaluate-reference-fidelity`);
157
+ `view`, released in `0.8.0`; and the v0.8.1 high-level `init`, `capture`, and
158
+ `check` commands. v0.8.1 also makes `view` project-aware while preserving its
159
+ standalone `--root` form. `src/cli.ts` remains a thin parsing/dispatch/
160
+ presentation boundary; it is no longer the not-implemented placeholder.
161
+
162
+ ## v0.1 progress (Batch 1–6; implemented and released as 0.1.0)
163
+
164
+ - Batch 1 froze and implemented the observation request contract, evidence
165
+ states/sources, schema 1.0.0, observation/request identity, bounded
166
+ readiness semantics, diagnostic/completion semantics, browser/network
167
+ safety policy, and portable path normalization, with 40 passing unit tests.
168
+ - Batch 2 added a Playwright Chromium browser boundary (`src/browser/`) and a
169
+ minimal application seam (`src/application/`) that launches a real
170
+ Chromium browser, enforces the Batch 1 loopback/redirect/subresource
171
+ safety policy at runtime, applies the requested viewport, waits for the
172
+ approved bounded readiness condition, captures a real viewport PNG
173
+ screenshot, returns observer-owned browser provenance, and reliably closes
174
+ the browser on every exit path. Deterministic local HTTP fixtures live
175
+ under `tests/fixtures/`; the real-Chromium integration tests live under
176
+ `tests/browser/` and run via `npm run test:browser` (kept separate from
177
+ `npm test`, which continues to run only the fast unit suite).
178
+ - Batch 3 extended the same single browser observation (no second Chromium
179
+ lifecycle) to also capture the v0.1 minimum page evidence (requested/final
180
+ URL, title, viewport, device pixel ratio, document scroll/client
181
+ dimensions plus a derived overall document width/height, window scroll
182
+ position) and explicit-target evidence (tag, geometry, computed
183
+ display/position/overflow, scroll/client metrics, initial visibility, and
184
+ role/name where the browser reliably exposes them) for every configured
185
+ CSS target, honoring missing/ambiguous-target semantics honestly. This
186
+ additively extended `src/domain/schema.ts`'s `TargetEvidenceRecord` (new
187
+ `tag`/`layout`/`visibility`/`semantics` categories, and concrete shapes for
188
+ `geometry`/`style`) and `BrowserCaptureResult`; schema version stays
189
+ `1.0.0`.
190
+ - Batch 4 added a portable, atomic observation-artifact writer
191
+ (`src/artifacts/artifactWriter.ts`) and a minimal application persistence
192
+ seam (`src/application/observationPersistence.ts`) that assembles the
193
+ frozen `ObservationArtifact` shape from a Batch 2/3 browser capture (using
194
+ the existing Batch 1 identity/completion functions verbatim, no new logic
195
+ invented) and writes it to `<outputLocation>/<observationId>/manifest.json`
196
+ plus `screenshot.png`. Writing happens in a sibling temporary directory
197
+ first (screenshot before manifest), finalized only via one atomic
198
+ directory rename, so a consumer can never observe a partially-written
199
+ artifact under its real name; a filesystem failure anywhere in that
200
+ sequence reports the existing `artifact-write-failure` diagnostic and
201
+ leaves no completed artifact behind. Internal artifact references
202
+ (`screenshot.png`) are relative/portable; the observation's logical
203
+ identity is the existing Batch 1 `observationId`, not its filesystem
204
+ location. The writer has no Playwright dependency and does not modify the
205
+ observed target. Schema stays `1.0.0`.
206
+ - Batch 5 wired the existing owners into the real user-facing workflow:
207
+ `src/cli.ts` implements a real `observe` command (thin argument
208
+ parsing/output only - no Chromium, safety, evidence, or filesystem logic
209
+ of its own), and `src/application/observationPersistence.ts` gained one
210
+ `observe()` use case that runs the existing browser capture exactly once
211
+ and, only on success, persists it exactly once through the existing
212
+ artifact writer. CLI syntax errors (malformed `WIDTHxHEIGHT`, malformed
213
+ `id=selector`) are rejected before any browser launches; all domain bounds
214
+ and safety decisions still come from the existing Batch 1 request
215
+ validator and safety policy, not CLI-local logic. A successfully
216
+ persisted observation - including one whose completion state honestly
217
+ reports `partial` - exits `0`; invalid syntax/request, an unpersistable
218
+ browser failure, or a failed artifact write exits nonzero. Package version
219
+ is `0.1.0`; schema stays `1.0.0`.
220
+
221
+ So: `my-frontend-observer observe --url ... --viewport ... --target ...
222
+ --output ...` is a real, working, source-checkout command that launches
223
+ Chromium, produces bounded runtime evidence, and writes a portable local
224
+ artifact - proven both via `runCli()`-level tests and a built
225
+ `node dist/cli.js observe ...` smoke run against the deterministic fixture.
226
+
227
+ Batch 6 closed the remaining v0.1 coverage gap (a genuine real-Chromium
228
+ navigation failure - connection reset mid-navigation - distinct from a
229
+ readiness timeout or a pre-launch safety rejection) and proved the packaged
230
+ form of the implementation works independent of the source checkout: the
231
+ real `npm pack` tarball, installed fresh in a clean temporary consumer
232
+ directory outside the repository, exposes its `my-frontend-observer` bin,
233
+ reports the correct version/help text, installs its own Chromium binary via
234
+ the consumer-local Playwright toolchain, and performs a real observation
235
+ against a disposable local HTTP target - producing a `manifest.json` +
236
+ `screenshot.png` artifact identical in shape to the source-checkout result,
237
+ without modifying the observed target, and with the temporary consumer/
238
+ tarball/output fully cleaned up afterward. Documentation across the
239
+ repository was reconciled to this implemented state as part of the same
240
+ batch.
241
+
242
+ ## v0.1 status
243
+
244
+ `v0.1.0` was the first published release (see `CHANGELOG.md` and
245
+ `docs/RELEASE.md`). Everything above this section describes that released
246
+ state, still present unchanged in `v0.2.0`.
247
+
248
+ ## v0.2 status (Stable Semantic Targets and Region Identity) - released as 0.2.0
249
+
250
+ v0.2 is implemented and released as package version `0.2.0`, observation
251
+ schema `1.1.0`.
252
+
253
+ - **Canonical target/locator model.** Each configured target has a stable
254
+ observer-owned `name` plus an ordered, bounded `locators` array
255
+ (`src/request/request.ts#TargetLocator`, `NamedTarget`). This identity is
256
+ distinct from both the browser locator that resolves it and any
257
+ source-code symbol. The legacy `{name, selector}` shape remains accepted
258
+ and normalizes to a one-item `css` locator, so every v0.1 CLI invocation
259
+ continues to work unchanged. Bounds: 20 targets max, 5 locators per
260
+ target max (unchanged/new respectively from v0.1's target count bound).
261
+ - **Six frozen locator kinds, all resolved against real Chromium**: `role`
262
+ (Playwright's accessibility role/name locator, exact name matching),
263
+ `id` and `data-attribute` (exact CSS attribute-equals matching that never
264
+ reinterprets the configured value as selector syntax), `semantic-element`
265
+ (a frozen structural tag set: `header`, `nav`, `main`, `footer`,
266
+ `article`, `section`, `aside`, `form`, `dialog`), `css` (unchanged v0.1
267
+ behavior), and `text` (exact match only, no substring/fuzzy matching).
268
+ Locator order is the fallback order: 0 matches tries the next locator; 1
269
+ match selects and stops; more than 1 match is ambiguous and stops (never
270
+ falls through); an unevaluable locator is unavailable and stops (never
271
+ falls through). All six kinds converge on one measurement path
272
+ (`src/browser/evidenceCapture.ts#captureResolvedTargetRecord`) - locator
273
+ strategy never changes the resulting evidence shape.
274
+ - **Semantic region evidence**, added to every resolved target alongside
275
+ the existing v0.1 role/name capture: `semanticState` (a first bounded
276
+ family of `disabled`/`expanded`/`checked`/`selected`/`pressed`/`current`,
277
+ read from the element's own native/ARIA properties so an explicit `false`
278
+ is always distinguishable from "not applicable"; `checked`/`pressed` also
279
+ support the browser's `'mixed'` value); `landmark` (derived only from the
280
+ already-captured browser-exposed role - never from locator kind or HTML
281
+ tag - against the standard landmark role set `banner`/`navigation`/
282
+ `main`/`complementary`/`contentinfo`/`form`/`region`/`search`); and
283
+ `containment` (bounded DOM containment checked only among the other
284
+ explicitly configured targets in the same observation, in configured
285
+ order - `available`/`partial`/`unavailable`, never a layout/spatial-
286
+ relationship graph).
287
+ - **Proven identity stability**: the same target configuration produces the
288
+ same `requestId` across repeated observations (with a fresh
289
+ `observationId` every time); changing a target's locator strategy while
290
+ keeping its stable name changes `requestId` but not the `targetEvidence`
291
+ key; actual runtime disappearance of a still-configured target changes
292
+ only its resolution status, never the `requestId`.
293
+ - **Public CLI**: `my-frontend-observer observe --targets-file <json-file>`
294
+ supplies a structured `{ "targets": [...] }` collection as an alternative
295
+ to one or more `--target id=css-selector` flags; the two are mutually
296
+ exclusive per invocation. `--targets-file` only validates its own root
297
+ wrapper (readable file, valid JSON, object root with exactly a `targets`
298
+ field); all target/locator-internal validation stays owned by the
299
+ existing `normalizeRequest()`. The file path is operational input only -
300
+ never part of request identity, never persisted into `manifest.json`.
301
+ - **Observation schema `1.1.0`** (`src/domain/schema.ts#SCHEMA_VERSION`):
302
+ additive over the published `1.0.0` - extends `TargetEvidenceRecord` with
303
+ `semanticState`/`landmark`/`containment` and extends `TargetResolution`
304
+ with `selectedLocatorKind`/`selectedLocatorIndex`/`usedFallback`/
305
+ `confidence`/`attempts`. Artifact kind, directory structure, atomic
306
+ persistence, and evidence-state/source vocabularies are unchanged.
307
+ - **Validation on this branch**: `npm run typecheck`, `npm run lint`,
308
+ `npm test`, `npm run test:browser`, `npm run build`, and
309
+ `npm run check:docs` all pass (106 unit tests, 69 real-Chromium tests as
310
+ of this reconciliation; see `docs/DEVELOPMENT.md` for how to reproduce).
311
+ `scripts/dev/builtCliTargetsFileSmoke.mjs` additionally proves the built
312
+ `dist/cli.js` (not just the imported `runCli()` function) performs a real
313
+ semantic `--targets-file` observation end to end.
314
+
315
+ ## v0.3 status (Runtime Scrolling, Overflow, and Visibility Behavior) - released as 0.3.0
316
+
317
+ v0.3 is implemented and released as package version `0.3.0`, observation
318
+ schema `1.2.0`. It was validated as a packed npm tarball in a clean
319
+ consumer environment on Windows, Linux, and macOS before release.
320
+
321
+ - **Batch 1** froze the `scrollScenario` request/identity/schema contract:
322
+ `ScrollScenario { action }` with exactly two action kinds
323
+ (`window-scroll-by`, `target-scroll-by`), signed-integer deltas bounded to
324
+ `[-20000, 20000]`, `target-scroll-by.target` referencing an existing stable
325
+ configured target name, scenario configuration participating in
326
+ `requestId` (runtime results never do), and the full bounded runtime
327
+ evidence model (`ScrollRuntimeSnapshot`, `ViewportRelationEvidence`,
328
+ `OverflowEvidence`, scenario transitions, `ScrollOwnerInterpretation`) in
329
+ schema `1.2.0` (up from `1.1.0`).
330
+ - **Batch 2** implemented real `window-scroll-by` execution
331
+ (`src/browser/scrollCapture.ts`, `src/domain/scrollEvidence.ts`): initial/
332
+ final runtime snapshots around an immediate `window.scrollBy({behavior:
333
+ 'instant'})` and exactly two `requestAnimationFrame` cycles, real vertical/
334
+ horizontal document scrolling, actual-vs-computed overflow, real viewport
335
+ relation, `enteredViewport`/`leftViewport`, and `document`/`none`
336
+ scroll-owner evidence - with ordinary final `pageEvidence`/`targetEvidence`
337
+ and the screenshot always describing the same final post-action state.
338
+ - **Batch 3** implemented real `target-scroll-by` execution against the same
339
+ canonical `resolveConfiguredTargets` resolution already used by every v0.2
340
+ locator kind: real nested vertical/horizontal element scrolling, boundary
341
+ clamping, non-scrollable/no-movement targets, and the completed
342
+ `document`/`target:<name>`/`none`/`indeterminate` scroll-owner derivation
343
+ (`src/domain/scrollEvidence.ts#deriveScrollOwner`) - proven never to
344
+ attribute ownership from bounding-rectangle movement alone in either
345
+ direction. An unresolved/ambiguous/hidden action target is never scrolled
346
+ and never fabricated as moved; the existing target diagnostics explain it
347
+ honestly and the observation still persists.
348
+ - **Batch 4** exposed the existing contract through the real public CLI:
349
+ `my-frontend-observer observe --scroll-scenario-file <json-file>` (see
350
+ `docs/COMMANDS.md`). The file supplies the `scrollScenario` value directly
351
+ (no wrapper field); the CLI/input layer only validates file readability,
352
+ JSON validity, and a non-array object root - every scenario/action rule
353
+ stays owned by the existing `normalizeRequest()`. Usable with either
354
+ `--target` or `--targets-file` (independent of target configuration, never
355
+ a third mutually-exclusive mode); the scenario-file path is operational
356
+ input only, never persisted and never part of request identity, exactly
357
+ like `--targets-file`'s path. CLI output/exit-code semantics are
358
+ unchanged. Proven via real Chromium (`tests/browser/cliObserve.test.ts`)
359
+ and the built `dist/cli.js` (`scripts/dev/builtCliScrollScenarioSmoke.mjs`).
360
+
361
+ ## v0.4 status (Layout Relationships, Dependency Evidence, and Before/After Comparison) - released as 0.4.0
362
+
363
+ v0.4 is implemented and released as package version `0.4.0`; observation
364
+ schema remains `1.2.0`; comparison schema is `1.0.0`. It was validated as a
365
+ packed npm tarball in a clean consumer environment on Windows, Linux, and
366
+ macOS - covering the legacy CSS-shorthand `--target` path, the structured
367
+ `--targets-file` path, both `--scroll-scenario-file` action kinds, and the
368
+ installed `compare` command (comparable and incomparable cases) - before
369
+ release.
370
+
371
+ - **Batch 1** froze the `my-frontend-observer/comparison` artifact contract
372
+ (schema `1.0.0`, independent of and never reused for the observation
373
+ schema): `ComparisonConfig` (geometry tolerance, default `0.5`px, bounded
374
+ `[0, 10]`px), the bounded layout-relationship vocabulary (horizontal/
375
+ vertical order, area overlap, relative width, geometric fit, vertical
376
+ sequencing, page-width fit, clipping), comparability states, the
377
+ before/after difference vocabulary, and the non-causal explicit
378
+ dependency-evidence contract, plus `comparisonRequestId`/`comparisonId`
379
+ identity (`src/domain/relationships.ts`, `src/domain/comparison.ts`,
380
+ `src/domain/comparisonIdentity.ts`). No derivation, comparison, or
381
+ persistence.
382
+ - **Batch 2** implemented the one canonical pure derivation engine,
383
+ `deriveLayoutRelationships(observation, options?)`
384
+ (`src/domain/relationships.ts`): consumes an existing `ObservationArtifact`
385
+ only (no Chromium, no re-resolution, no DOM access) and derives a bounded,
386
+ traceable `LayoutRelationshipGraph` among configured targets - stable
387
+ target identity, deterministic configured-target ordering, honest
388
+ unresolved-target handling (not-found/ambiguous/unavailable/hidden, never
389
+ a fabricated zero-sized region), and evidence-reference provenance for
390
+ every derived relationship. DOM containment is read directly from the
391
+ existing `TargetContainment` evidence rather than re-derived, and stays
392
+ distinct from geometric fit. A standalone `deriveTargetClipping(record)`
393
+ derives the frozen clipping concept per target from existing layout/style
394
+ evidence.
395
+ - **Batch 3** implemented the pure before/after comparison engine,
396
+ `compareObservations(before, after, config?)`
397
+ (`src/domain/comparisonEngine.ts`): validates both source observations,
398
+ evaluates comparability before any rendered difference is calculated
399
+ (hard page-URL/viewport/browser-engine/scroll-scenario mismatches;
400
+ producer/browser-version and target-configuration warnings), reuses
401
+ `deriveLayoutRelationships` unchanged for both sides, and derives target/
402
+ page differences (appeared/disappeared, moved, resized, visibility,
403
+ clipping, actual overflow, DOM containment, page size, scroll-owner) and
404
+ relationship changes (matched by family + subject/related target, never
405
+ array position) - all without launching Chromium, re-resolving targets, or
406
+ mutating either input observation. Explicit `ComparisonConfig.
407
+ expectedDependencies` are evaluated into non-causal
408
+ consistent/not-observed/contradictory-to-declaration/unavailable outcomes
409
+ only; the observer never infers a dependency from co-change. Comparison
410
+ identity reuses the existing Batch 1 `buildComparisonRequestIdentity`/
411
+ `buildComparisonIdentity` verbatim. Persistence
412
+ (`src/artifacts/comparisonArtifactWriter.ts#writeComparisonArtifact`,
413
+ atomic, `<outputLocation>/<comparisonId>/manifest.json` only, no copied
414
+ screenshots) and the application-level `compareAndPersist` use case
415
+ (`src/application/comparisonService.ts`) are implemented; a narrow
416
+ `readObservationArtifact` reader
417
+ (`src/artifacts/artifactReader.ts`) is established ahead of the Batch 4
418
+ CLI.
419
+ - **Batch 4** exposed the existing comparison workflow through the real
420
+ public CLI: `my-frontend-observer compare --before <observation-artifact-
421
+ root> --after <observation-artifact-root> --output <directory>
422
+ [--config-file <json-file>]` (see `docs/COMMANDS.md`). The CLI stays thin
423
+ - `src/cli.ts` parses arguments, optionally loads a config file (file
424
+ readability/JSON validity/object-root only, exactly like
425
+ `--targets-file`/`--scroll-scenario-file`), and delegates to one new
426
+ thin application-layer orchestration function,
427
+ `compareAndPersistFromArtifactRoots`
428
+ (`src/application/comparisonService.ts`), which reads both observation
429
+ roots through the existing `readObservationArtifact` reader and calls the
430
+ existing `compareAndPersist` exactly once - no comparability/geometry/
431
+ relationship/dependency logic lives in the CLI, and comparison itself
432
+ never launches Chromium (`src/cli.ts` still imports nothing from
433
+ `src/artifacts/` or `src/browser/`, matching the pre-existing observe-CLI
434
+ import-boundary test). `comparable`, `comparable-with-warnings`, and
435
+ `incomparable` all exit `0` - each is a successful comparison outcome;
436
+ only a genuine parse/read/domain/persistence failure exits nonzero.
437
+ Operational paths (`--before`/`--after`/`--config-file`/`--output`) never
438
+ affect `comparisonRequestId` and are never written into the persisted
439
+ manifest. Proven end-to-end via real Chromium
440
+ (`tests/browser/cliCompare.test.ts`) and the built `dist/cli.js`
441
+ (`scripts/dev/builtCliCompareSmoke.mjs`): unchanged/moved/resized/
442
+ appeared/disappeared/configuration-only-change/overlap/geometric-fit/
443
+ page-overflow/clipping/scroll-owner cases, plus an explicit
444
+ `--config-file` dependency-evidence case, all through the public command
445
+ surface.
446
+
447
+ v0.4's canonical relationship derivation, before/after comparison,
448
+ comparability, differences, relationship changes, explicit dependency
449
+ evidence, comparison persistence, and public `compare` CLI are all
450
+ implemented, exercised end-to-end, packed-validated cross-platform, and
451
+ released.
452
+
453
+ v0.5 frontend contract model, identity, and evaluation engine are released
454
+ as part of `0.5.0`: `src/domain/frontendContracts.ts` (persistent baseline /
455
+ per-change contract types, the four authored change-scope categories plus
456
+ the derived `unexpected` classification, the 15-primitive bounded
457
+ vocabulary, contract tolerance, and the clause-result/overall-verdict
458
+ vocabulary), `src/domain/frontendContractIdentity.ts` (deterministic
459
+ contract/baseline/clause identity), and
460
+ `src/domain/frontendContractEvaluation.ts#evaluateFrontendContract`
461
+ (the one canonical pure evaluator: active-baseline/supersession calculation,
462
+ bounded conflict detection, per-category clause evaluation, difference-to-
463
+ scope matching, unexpected-change derivation, and overall PASS/FAIL) - all
464
+ covered by focused unit tests. Observation schema stays `1.2.0`, comparison
465
+ schema stays `1.0.0`.
466
+
467
+ v0.5 contract and evaluation persistence are also released as part of
468
+ `0.5.0`: `src/artifacts/frontendContractArtifactWriter.ts`/`frontendContractArtifactReader.ts`
469
+ (symmetric baseline/per-change contract persistence, atomic write, no
470
+ overwrite of existing history), `src/artifacts/comparisonArtifactReader.ts`
471
+ (new - no comparison reader existed before this batch; comparison schema
472
+ still `1.0.0`), `src/domain/frontendContractEvaluationArtifact.ts` (minimal
473
+ additive persisted envelope around the frozen evaluation-result vocabulary,
474
+ its own independent schema family `1.0.0`) with
475
+ `src/artifacts/frontendContractEvaluationArtifactWriter.ts`/`...Reader.ts`,
476
+ and `src/application/frontendContractEvaluationService.ts#evaluateAndPersist`/
477
+ `evaluateAndPersistFromArtifactRoots` (calls `evaluateFrontendContract`
478
+ exactly once, persists exactly one evaluation artifact for both `PASS` and
479
+ `FAIL` verdicts, never persists a fabricated artifact when evaluation
480
+ construction itself fails). `evaluateFrontendContract` itself is unmodified.
481
+
482
+ v0.5 public contract/baseline-approval/evaluation CLI is also released as
483
+ part of `0.5.0`:
484
+ `approve-baseline` (the only baseline-approval act - explicit only, never
485
+ inferred from `compare` or a `PASS` evaluation; verifies the contract's
486
+ `sourceObservation` matches the supplied observation before persisting),
487
+ `save-change-contract` (persistence only), and `evaluate-contract`
488
+ (evaluates already-persisted before/after/comparison/baseline/change
489
+ evidence exactly once and persists exactly one evaluation artifact;
490
+ `--enforce` makes a `FAIL` verdict exit nonzero without changing the
491
+ verdict, its identity, or its persisted content - a `FAIL` without
492
+ `--enforce` still exits `0`). `src/application/frontendContractPersistenceService.ts`
493
+ adds the two new thin application seams (`approveAndPersistBaseline`,
494
+ `persistPerChangeContract`); `src/cli.ts` gained no browser or artifact-
495
+ writer import. Covered by `tests/unit/cliFrontendContracts.test.ts` and the
496
+ Chromium-free `scripts/dev/builtCliFrontendContractsSmoke.mjs` dev smoke.
497
+ Observation schema `1.2.0`; comparison schema `1.0.0`; frontend contract
498
+ schema `1.0.0`; evaluation artifact schema `1.0.0` - no schema was bumped
499
+ to add this CLI.
500
+
501
+ v0.5 proved the complete public contract workflow (`observe` →
502
+ `approve-baseline` → `save-change-contract` → `observe` → `compare` →
503
+ `evaluate-contract`) against real Chromium observations, not hand-constructed
504
+ artifacts: a fully successful contract change (all clauses `pass`, overall
505
+ `PASS`), and the "milestone signature" case - a locally successful requested
506
+ change (navigation shrinks, workspace expands, both real and both `pass`)
507
+ coexisting with a genuine protected-property regression (real right-rail
508
+ `resized` difference) and a genuine preserved-invariant regression (real
509
+ `clipping-changed` difference, `not-clipped` → `clipped`) - producing overall
510
+ `FAIL`. Both scenarios are covered by `tests/browser/cliFrontendContracts.test.ts`
511
+ (real Chromium, via `tests/fixtures/server.ts`'s new `/contract` route) and by
512
+ the built-CLI dev smoke `scripts/dev/builtCliFrontendContractsBrowserSmoke.mjs`
513
+ (the built `dist/cli.js`, not the imported `runCli()`, against its own
514
+ disposable local HTTP fixture). Both confirm `--enforce` behavior (`FAIL`
515
+ persists and exits `0` without it, exits nonzero with it, identical
516
+ `evaluationRequestId` and `clauseResults` in both cases), full source
517
+ observation/comparison immutability, no screenshot copied into the
518
+ evaluation artifact, and no operational filesystem path leaked into any
519
+ persisted manifest.
520
+
521
+ The packed-readiness coverage gap this left (`V0_5_READINESS_VALIDATION_GAP_EXISTS`)
522
+ was corrected and proven cross-platform before release:
523
+ `scripts/ci/runPackedObservationSmoke.mjs` also exercises the installed
524
+ packed candidate's `approve-baseline`/`save-change-contract`/
525
+ `evaluate-contract` commands against real installed-candidate `observe`/
526
+ `compare` evidence, proving the same successful-change and milestone-
527
+ signature scenarios through the installed tarball rather than the source
528
+ checkout. v0.5 pre-release readiness passed on the validation branch
529
+ `validation/v0.5-pre-release` (GitHub Actions run `31727856546`, one shared
530
+ hash-verified candidate tarball on Windows, Linux, and macOS - see
531
+ `docs/CI_CD.md` for full evidence) before the version `0.5.0` release below.
532
+
533
+ ## v0.6 status (Bounded Agent Context and Native my-dev-kit Ecosystem Integration) - released as `0.6.0`
534
+
535
+ v0.6 is published as package version `0.6.0`, tagged `v0.6.0`, from the
536
+ canonical `canonicalization/v0.6` lineage (product commit
537
+ `514bf3bb513764815a0a5b9e508d5836aa7d7fd8`). Observation schema stays
538
+ `1.2.0`; comparison schema `1.0.0`; frontend contract schema `1.0.0`;
539
+ evaluation artifact schema `1.0.0`; new bounded-agent-context schema
540
+ `1.0.0` (artifact kind `my-frontend-observer/bounded-agent-context`).
541
+
542
+ - **Bounded runtime projection** (`src/domain/boundedAgentContext.ts`,
543
+ `src/domain/boundedAgentContextProjection.ts#projectBoundedAgentContext`):
544
+ page/viewport identity, stable target identities, geometry, runtime
545
+ behavior, relationships, before/after differences, contract results, and
546
+ requested/expected-dependent/protected/preserved scope - reusing the
547
+ existing v0.5 `frontendContracts.ts` types directly rather than
548
+ reimplementing them - plus diagnostics, screenshot/artifact references,
549
+ provenance, and explicit truncation/omission metadata.
550
+ - **Adequacy, omission, and truncation** (`Adequacy`/`ADEQUACY_REASON_CODES`,
551
+ `OmissionRecord`/`TruncationRecord`, bounded aggregate-cap summarization):
552
+ distinguishes required from optional loss and reports whether captured
553
+ evidence is adequate for the task rather than merely present.
554
+ - **Runtime/static correlation**
555
+ (`src/domain/boundedAgentContextCorrelation.ts#deriveRuntimeStaticCorrelations`/
556
+ `attachRuntimeStaticCorrelations`): correlation outcomes are exactly
557
+ `correlated`/`ambiguous`/`unavailable`; competing candidate identities
558
+ remain visible; a stable runtime target identity is never silently
559
+ reported as source ownership. This module has no dependency on
560
+ `@dailephd/my-dev-kit` - it accepts only plain, already-retrieved
561
+ candidate evidence, since no generic static-side retrieval capability was
562
+ found missing.
563
+ - **Deterministic identity** (`src/domain/boundedAgentContextIdentity.ts`):
564
+ a logical identity distinct from a fresh per-execution instance identity.
565
+ - **Export/public boundary**: `src/index.ts` exports the complete
566
+ bounded-agent-context and correlation type/function surface as a
567
+ programmatic library contract. There is no new CLI command and no disk
568
+ artifact writer/reader for this artifact family - it is a pure contract-
569
+ and-derivation layer, consistent with the frozen module documentation
570
+ describing it as a foundation for orchestrator/lab consumption rather than
571
+ a persisted artifact kind.
572
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
573
+ lint`, `npm test` (32 files, 627 tests), `npm run test:browser` (9 files,
574
+ 120 tests), `npm run test:security`, `npm run build`, and `npm run
575
+ check:docs` all pass. Cross-repository neutral verification (observer
576
+ `514bf3b`, orchestrator `9473e4c`, lab `271e72c`) passed with 6/6
577
+ requirement coverage and no known product blockers.
578
+ - **Not Observer-owned / correctly out of scope for this repository**: no
579
+ `my-dev-kit` static-side change was made (none was proven necessary); no
580
+ orchestrator bounded-evidence consumption or lab reader/fixture/evaluation
581
+ code lives in this repository - those are separate sibling-repository
582
+ deliverables, not part of `my-frontend-observer`'s v0.6 surface.
583
+
584
+ ## v0.7 Prompt 1 status (External Visual Reference Foundation) - released as `0.7.0`
585
+
586
+ Only the foundation layer of the v0.7 external-reference architecture is
587
+ implemented: an observer-owned `ExternalReferenceArtifact` family
588
+ representing one externally supplied design-reference image plus
589
+ deterministic identity, provenance, bounded image metadata, and an explicit
590
+ two-state lifecycle. This is not the full v0.7 coding-agent workflow.
591
+
592
+ - **Domain** (`src/domain/externalReferenceImage.ts`): pure, dependency-free
593
+ PNG/JPEG/WebP header-byte format detection and dimension parsing (no
594
+ decode, no OCR, no computer vision), bounded to
595
+ `EXTERNAL_REFERENCE_MAX_IMAGE_BYTES` (20,000,000 bytes) and
596
+ `[EXTERNAL_REFERENCE_MIN_DIMENSION_PX, EXTERNAL_REFERENCE_MAX_DIMENSION_PX]`
597
+ (`[1, 8192]`) pixels per side.
598
+ - **Domain** (`src/domain/externalReference.ts`): `ExternalReferenceArtifact`
599
+ is a discriminated union of `ImportedExternalReferenceArtifact` (owns its
600
+ image file) and `ApprovedExternalReferenceArtifact` (carries a
601
+ `sourceReference` back to the imported artifact's image instead of copying
602
+ it) under `EXTERNAL_REFERENCE_ARTIFACT_KIND` /
603
+ `EXTERNAL_REFERENCE_SCHEMA_VERSION` (`'1.0.0'`, independent of the
604
+ observation/comparison/contract schema versions). Lifecycle has exactly two
605
+ persisted states, `'imported'` and `'approved'` - there is no literal
606
+ `'superseded'` state; supersession is represented only as a forward
607
+ pointer (`supersedesReferenceId` on the newer artifact), so an existing
608
+ persisted artifact's own manifest is never rewritten.
609
+ - **Identity** (`src/domain/externalReferenceIdentity.ts`): the same
610
+ canonicalize-then-sha256 request identity plus nonce-based fresh instance
611
+ identity pattern used by every other artifact family, duplicated per-family
612
+ per existing convention. `referenceRequestId` is a pure function of
613
+ `{imageSha256, format, width, height, supersedesReferenceId}` only - never
614
+ a filesystem path, output location, label, or timestamp.
615
+ - **Persistence** (`src/artifacts/externalReferenceArtifactWriter.ts` /
616
+ `externalReferenceArtifactReader.ts`): same atomic temp-dir-then-rename
617
+ discipline as the observation/comparison writers; an `'imported'`
618
+ artifact's directory contains `manifest.json` plus its owned image file;
619
+ an `'approved'` artifact's directory contains only `manifest.json`.
620
+ - **Application** (`src/application/externalReferencePersistenceService.ts`):
621
+ `importExternalReference()` (never approves; fails closed on an
622
+ unsupported/undetectable format, invalid or out-of-bound dimensions, an
623
+ over-limit file, or an unresolvable `--supersedes` target) and
624
+ `approveExternalReference()` (the only explicit approval act; refuses to
625
+ approve anything not currently in the `'imported'` state; never mutates the
626
+ imported artifact it approves).
627
+ - **CLI**: `import-reference <image-file> --output <dir> [--label] [--supersedes]`
628
+ and `approve-reference --reference <root> --output <dir> [--supersedes]`.
629
+ - **Export/public boundary**: `src/index.ts` exports the complete new type,
630
+ constant, validator, identity, writer, reader, and application-service
631
+ surface, following the same grouping order as every existing family.
632
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
633
+ lint`, `npm test` (38 files, 668 tests), `npm run test:browser` (9 files,
634
+ 120 tests), `npm run test:security`, `npm run build`, `npm run check:docs`,
635
+ `git diff --check`, and `npm pack --dry-run` all pass with zero changes to
636
+ any pre-existing test.
637
+ - **Not implemented in this stage** (explicitly deferred to later v0.7
638
+ prompts): reference regions, geometry, relationships, design requirements,
639
+ tolerances, reference-region/runtime-target binding, reference-vs-candidate
640
+ fidelity evaluation, theme/application-state compatibility evaluation,
641
+ viewer, and annotation.
642
+
643
+ ## v0.7 Prompt 2 status (Explicit Reference Regions, Geometry, and Reusable Reference Relationships) - released as `0.7.0`
644
+
645
+ Additive extension of the Prompt 1 foundation above. Still not the full v0.7
646
+ coding-agent workflow - no design requirements, tolerances, adequacy,
647
+ binding, or fidelity evaluation yet.
648
+
649
+ - **Domain** (`src/domain/externalReferenceRegions.ts`): explicit,
650
+ user/configuration-authored reference-image rectangles
651
+ (`ReferenceRegion { id, rectangle: {x, y, width, height} }`), origin at the
652
+ reference image's top-left corner, unit reference-image pixels. Pure
653
+ derived geometry (`right`/`bottom`/`centerX`/`centerY`) is always
654
+ recomputed from the canonical rectangle, never separately stored. Bounded
655
+ at `MAX_REFERENCE_REGIONS` (20, matching `request/request.ts`'s
656
+ `MAX_TARGETS`), region ids validated against the same
657
+ `^[A-Za-z0-9_-]{1,64}$` pattern as target names, unique
658
+ case-insensitively, and rejected outright (never clamped) if any rectangle
659
+ extends outside the owning image's bounds.
660
+ - **Domain** (`src/domain/externalReferenceRegionRelationships.ts`): reuses
661
+ the exact pure geometry predicates `deriveLayoutRelationships` uses for
662
+ runtime targets (now exported additively) from `relationships.ts` rather
663
+ than reimplemented, so reference-region geometry and runtime-target
664
+ geometry can never diverge on the same underlying formula; only the
665
+ geometry-only relationship families apply, since a static image exposes
666
+ no DOM, scroll, or viewport evidence.
667
+ - **Schema**: `ExternalReferenceArtifact` gained one additive, optional
668
+ `regions?: ReferenceRegion[]` field. No schema version bump
669
+ (`EXTERNAL_REFERENCE_SCHEMA_VERSION` remains `'1.0.0'`) - every Prompt 1
670
+ artifact remains valid with no `regions` key at all.
671
+ - **Identity**: `buildExternalReferenceRequestIdentity` gained an additive,
672
+ optional trailing `regions` parameter, omitted from the hashed view
673
+ entirely (not defaulted to `null`) when absent, so every Prompt 1 call
674
+ site keeps producing byte-identical identity. Region content (including
675
+ authored order) is identity-bearing when present.
676
+ - **Application**: `importExternalReference()` validates an optional
677
+ `regions` option and fails closed with the new `invalid-reference-region`
678
+ diagnostic; `approveExternalReference()` carries an imported artifact's
679
+ `regions` forward verbatim, never re-validating or re-deriving them.
680
+ - **CLI**: `import-reference` gained an optional
681
+ `--regions-file <json-file>` (`{ "regions": [...] }`, same object-root-
682
+ wrapper convention as `--targets-file`); legacy invocations without it are
683
+ unchanged from Prompt 1. Both commands now print a `Regions: <count>` line.
684
+ - **Export/public boundary**: `src/index.ts` exports the complete new region
685
+ and relationship type/constant/validator/function surface, following the
686
+ same grouping order as every existing family.
687
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
688
+ lint`, `npm test` (40 files, 719 tests), `npm run test:browser` (9 files,
689
+ 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
690
+ check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
691
+ zero changes to any pre-existing test.
692
+ - **Not implemented in this stage** (explicitly deferred to later v0.7
693
+ prompts): selected design requirements, design tolerance semantics,
694
+ reference-evidence adequacy, theme/application-state compatibility
695
+ evaluation, reference-region/runtime-target binding, reference-vs-candidate
696
+ fidelity evaluation, viewer, and annotation.
697
+
698
+ ## v0.7 Prompt 3 status (Selected Design Requirements, Tolerance Semantics, and Reference-Evidence Adequacy) - released as `0.7.0`
699
+
700
+ Additive extension of the Prompt 1/2 foundation above. Still not the full
701
+ v0.7 coding-agent workflow - no runtime binding or fidelity evaluation yet.
702
+
703
+ - **Domain** (`src/domain/externalReferenceRequirements.ts`): explicit,
704
+ user/configuration-selected design intent over Prompt 2's `regions` -
705
+ never inferred merely because a region property or relationship exists.
706
+ Requirement category reuses v0.5's `AuthoredChangeScopeCategory`
707
+ (`requested`/`expected-dependent`/`protected`/`preserved`) directly;
708
+ `'unexpected'` remains impossible to author. Three subject kinds:
709
+ `region-property` (one region + a `ReferenceRegionGeometry` field),
710
+ `region-relationship` (two regions + a reused `PairwiseRelationshipKind`,
711
+ geometry-only families only, no tolerance), `region-measurement` (two
712
+ regions + one of six pure derived measurements - `vertical-gap`,
713
+ `horizontal-gap`, `center-x-delta`, `center-y-delta`, `left-edge-delta`,
714
+ `right-edge-delta` - with a required tolerance). Tolerance is a new,
715
+ reference-owned type (`exact` | `absolute-reference-px` | `percent`),
716
+ deliberately not a reuse of v0.5's `ContractTolerance` (whose
717
+ `absolute-px` is implicitly runtime/CSS pixels). Bounded at
718
+ `MAX_REFERENCE_REQUIREMENTS` (50). A requirement's `requirementId` is
719
+ always system-computed from its content, never authored.
720
+ - **Reference-evidence adequacy**: `deriveReferenceRequirementAdequacy()`
721
+ asks only whether the reference definition itself supports every selected
722
+ requirement - never whether a runtime target/candidate exists. Its own
723
+ small vocabulary (`adequate`/`partial`/`inadequate`, two reason codes)
724
+ deliberately does not reuse `boundedAgentContext.ts`'s `Adequacy`, which
725
+ describes an unrelated runtime/static-correlation domain. Zero selected
726
+ requirements is explicitly `inadequate`. Never a numeric score; reasons
727
+ ordered deterministically by authored requirement position.
728
+ - **Validation**: a requirement referencing an unknown region id is a
729
+ construction-time failure (`invalid-reference-requirement`), never
730
+ "unavailable" evidence. Two requirements sharing the exact same structural
731
+ subject (regardless of category) are rejected as duplicates/conflicts -
732
+ v0.5's runtime-evaluation-time conflict detector
733
+ (`evaluateFrontendContract#primitivesConflict`) needs before/after
734
+ observation evidence that does not exist at this stage and could not be
735
+ reused safely.
736
+ - **Schema**: `ExternalReferenceArtifact` gained one additive, optional
737
+ `requirements?: ExternalReferenceRequirement[]` field. No schema version
738
+ bump - every Prompt 1/2 artifact remains valid with no `requirements` key.
739
+ - **Identity**: `buildExternalReferenceRequestIdentity` gained an additive,
740
+ optional trailing `requirements` parameter, omitted from the hashed view
741
+ entirely when absent, so every Prompt 1/2 call site keeps producing
742
+ byte-identical identity. Requirement content (category, subject,
743
+ tolerance, mode, authored order) is identity-bearing when present.
744
+ - **Application**: `importExternalReference()` validates an optional
745
+ `requirements` option (computing each requirement's identity from its raw
746
+ authored content) and fails closed on any invalid requirement;
747
+ `approveExternalReference()` carries `requirements` forward verbatim.
748
+ Both now also compute and return reference-evidence adequacy.
749
+ - **CLI**: `import-reference` gained an optional
750
+ `--requirements-file <json-file>` (`{ "requirements": [...] }`, same
751
+ object-root-wrapper convention as `--regions-file`); legacy invocations
752
+ without it are unchanged. Both commands now also print
753
+ `Requirements: <count>` and `Adequacy: <status>` lines.
754
+ - **Export/public boundary**: `src/index.ts` exports the complete new
755
+ requirement/tolerance/adequacy type/constant/validator/function surface,
756
+ following the same grouping order as every existing family.
757
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
758
+ lint`, `npm test` (42 files, 779 tests), `npm run test:browser` (9 files,
759
+ 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
760
+ check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
761
+ zero changes to any pre-existing test.
762
+ - **Not implemented in this stage** (explicitly deferred to later v0.7
763
+ prompts): theme/application-state compatibility evaluation,
764
+ reference-region/runtime-target binding, reference-vs-candidate fidelity
765
+ evaluation, viewer, and annotation.
766
+
767
+ ## v0.7 Prompt 4 status (Reference Applicability and Candidate-State Compatibility) - released as `0.7.0`
768
+
769
+ Additive extension of the Prompt 1/2/3 foundation above. Still not the full
770
+ v0.7 coding-agent workflow - no runtime binding or fidelity evaluation yet.
771
+
772
+ - **Domain** (`src/domain/explicitState.ts`): a small, closed, caller/
773
+ configuration-supplied state model (`theme`, `applicationState`,
774
+ `authenticatedState`) shared by both `ObservationArtifact.requestConfig.explicitState`
775
+ and `ExternalReferenceArtifact.applicability` - never inferred from
776
+ screenshot pixels, CSS, DOM, URLs, or any other runtime signal. Labels are
777
+ bounded opaque identities (`^[A-Za-z0-9_-]{1,64}$`) compared by exact,
778
+ case-sensitive equality only. `authenticatedState` is a closed
779
+ `'authenticated' | 'unauthenticated'` vocabulary with no field capable of
780
+ holding a credential, token, or cookie.
781
+ - **Domain** (`src/domain/externalReferenceApplicability.ts`): adds an
782
+ optional CSS-pixel `viewport` to the shared state model - deliberately
783
+ distinct from the reference image's own pixel dimensions (`image.width`/
784
+ `height`), which a reference image may be captured at any resolution/DPI
785
+ relative to.
786
+ - **Domain** (`src/domain/externalReferenceCompatibility.ts`):
787
+ `evaluateReferenceCandidateCompatibility(reference, candidate)` answers
788
+ "does this reference describe the same frontend state as this candidate
789
+ observation?" by reusing v0.4's own `ComparabilityResult`/`ComparabilityReason`
790
+ vocabulary and a newly-extracted, shared pure helper
791
+ (`assessOptionalComparabilityDimension`, exported from
792
+ `comparisonEngine.ts`) rather than a parallel model. The same helper now
793
+ also drives v0.4's own `evaluateComparability`, which additionally assesses
794
+ theme/authenticated-state/application-state when both observations declare
795
+ `explicitState` - every historical observation pair without it keeps its
796
+ exact prior unassessed-only behavior (a frozen regression vector proves
797
+ this). A dimension the reference constrains but the candidate omits (or
798
+ vice versa) is `unassessed`, never fabricated as a match or a mismatch.
799
+ - **Schema**: `ExternalReferenceArtifact` gained one additive, optional
800
+ `applicability?: ExternalReferenceApplicability` field; `ObservationArtifact.requestConfig`
801
+ gained one additive, optional `explicitState?: ExplicitStateDimensions`
802
+ field. No schema version bump on either family.
803
+ - **Identity**: `buildExternalReferenceRequestIdentity` gained an additive,
804
+ optional trailing `applicability` parameter; `buildRequestIdentity` gained
805
+ an additive, optional trailing `explicitState` parameter - both omitted
806
+ from their hashed views (never `null`) when absent, so every earlier call
807
+ site keeps producing byte-identical identity.
808
+ - **CLI**: `import-reference` gained an optional `--applicability-file <json-file>`;
809
+ `observe` gained an optional `--state-file <json-file>` (both unwrapped
810
+ raw-object files, following `--scroll-scenario-file`'s exact convention).
811
+ `import-reference`/`approve-reference` now also print an
812
+ `Applicability: declared|none` line.
813
+ - **Export/public boundary**: `src/index.ts` exports the complete new
814
+ explicit-state/applicability/compatibility type/constant/validator/function
815
+ surface, following the same grouping order as every existing family.
816
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
817
+ lint`, `npm test` (45 files, 857 tests), `npm run test:browser` (9 files,
818
+ 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
819
+ check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
820
+ zero changes to any pre-existing test.
821
+ - **Not implemented in this stage** (explicitly deferred to later v0.7
822
+ prompts): reference-region/runtime-target binding, reference-vs-candidate
823
+ fidelity evaluation, bounded fidelity context, the end-to-end correction
824
+ workflow, viewer, and annotation.
825
+
826
+ ## v0.7 Prompt 5 status (Explicit Reference-Region <-> Runtime-Target Binding) - released as `0.7.0`
827
+
828
+ Additive extension of the Prompt 1-4 foundation above. Still not the full
829
+ v0.7 coding-agent workflow - no fidelity evaluation yet.
830
+
831
+ - **Domain** (`src/domain/externalReferenceRuntimeBinding.ts`):
832
+ `evaluateReferenceRuntimeBindings(reference, candidate, declarations)`
833
+ answers "which stable v0.2 runtime target does this candidate resolve for
834
+ each explicitly declared reference region?" A binding declaration
835
+ (`{referenceRegion, runtimeTarget}`) is explicit user/configuration input
836
+ - never inferred from geometry, matching names, or source code; two
837
+ strings with the same textual value in the reference-region and
838
+ runtime-target identity domains never bind to each other merely because
839
+ they match. Reuses `evaluateReferenceCandidateCompatibility` (Prompt 4) as
840
+ a hard gate and `targetPresence` (v0.4, exported additively) as the sole
841
+ "how do I read a `TargetEvidenceRecord`'s resolution" rule - no second
842
+ target resolver, no browser launch. Status vocabulary: `bound` / `ambiguous`
843
+ / `unavailable`, each with closed reason codes. An unknown reference
844
+ region fails the whole evaluation closed (structural, candidate-independent);
845
+ an unknown/ambiguous/unavailable runtime target produces a per-declaration
846
+ `unavailable`/`ambiguous` result, never a guessed target. Bounded at
847
+ `MAX_REFERENCE_RUNTIME_BINDINGS` (20).
848
+ - **Persistence**: none - a pure, on-demand function over already-persisted/
849
+ in-memory evidence, no new artifact family.
850
+ - **CLI**: none added - deliberately deferred to Prompt 6, the capability's
851
+ first concrete consumer.
852
+ - **Export/public boundary**: `src/index.ts` exports the complete new
853
+ binding type/constant/validator/function surface.
854
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
855
+ lint`, `npm test` (46 files, 889 tests), `npm run test:browser` (9 files,
856
+ 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
857
+ check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
858
+ zero changes to any pre-existing test.
859
+ - **Not implemented in this stage** (explicitly deferred to later v0.7
860
+ prompts): reference-vs-candidate fidelity evaluation, bounded fidelity
861
+ context, the end-to-end correction workflow, viewer, and annotation.
862
+
863
+ ## v0.7 Prompt 6 status (Structured Reference-vs-Candidate Fidelity Evaluation) - released as `0.7.0`
864
+
865
+ Additive extension of the Prompt 1-5 foundation above. The first point in
866
+ the v0.7 stack where a reference's authored expectation is actually
867
+ compared against live candidate evidence.
868
+
869
+ - **Domain** (`src/domain/externalReferenceFidelity.ts`):
870
+ `evaluateReferenceCandidateFidelity(reference, candidate, bindings)`
871
+ evaluates in a frozen order - reference/candidate structural validation ->
872
+ Prompt 3 adequacy -> Prompt 4 compatibility -> Prompt 5 binding ->
873
+ per-requirement evaluation - and never fabricates an ordinary PASS/FAIL
874
+ past an earlier blocking gate: overall `state` is `'not-evaluated'` /
875
+ `'pass'` / `'fail'`, with `blockedBy` preserved for the first two gates.
876
+ Establishes one explicit, deterministic reference-image-pixel <->
877
+ CSS-pixel coordinate scale from `reference.applicability.viewport` and the
878
+ image's own dimensions, gated by an independent (never a design-tolerance)
879
+ aspect-ratio coherence check. Reuses Prompt 3 tolerances
880
+ (`exact`/`absolute-reference-px`/`percent`) and v0.4's
881
+ `deriveLayoutRelationships` (family-scoped lookup, the same bug class
882
+ Prompt 3 already fixed) unchanged - no duplicated geometry or
883
+ comparability logic.
884
+ - **Persistence**: none - a pure, on-demand function; the CLI-facing
885
+ `evaluateReferenceCandidateFidelityFromArtifactRoots` application-service
886
+ wrapper only reads already-persisted artifacts, it does not write one.
887
+ - **CLI**: `evaluate-reference-fidelity --reference --candidate
888
+ [--bindings-file] [--enforce]` - the CLI surface Prompt 5 deferred,
889
+ following `evaluate-contract`'s exact `--enforce`/exit-code precedent.
890
+ Persists nothing; there is no `--output` flag.
891
+ - **Export/public boundary**: `src/index.ts` exports the complete new
892
+ fidelity-result type/constant/validator/function surface plus the
893
+ application-service wrapper.
894
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
895
+ lint`, `npm test` (48 files, 927 tests), `npm run test:browser` (9 files,
896
+ 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
897
+ check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
898
+ zero changes to any pre-existing test.
899
+ - **Not implemented in this stage** (explicitly deferred to later v0.7
900
+ prompts): bounded fidelity context integration, the end-to-end correction
901
+ workflow, viewer, and annotation.
902
+
903
+ ## v0.7 Prompt 7 status (Bounded Reference-Fidelity Projection and v0.6 Bounded-Agent-Context Integration) - released as `0.7.0`
904
+
905
+ Additive extension of the v0.6 bounded-agent-context architecture and the
906
+ Prompt 1-6 foundation above.
907
+
908
+ - **Domain** (`src/domain/referenceFidelityProjection.ts`):
909
+ `projectReferenceFidelity()` selects, prioritizes (failed-required, then
910
+ unavailable-required, then other non-pass), and bounds Prompt 6's
911
+ non-passing requirement results (`MAX_FIDELITY_MISMATCHES`, 15) and
912
+ passing protected/preserved context (`MAX_FIDELITY_PROTECTED_CONTEXT`, 10)
913
+ for a coding agent's bounded context - passing requirements are never
914
+ dumped by default.
915
+ - **Integration**: `projectBoundedAgentContext` (v0.6) itself, not a second
916
+ context system, gained one new optional input (`fidelity`,
917
+ `fidelityRequired?`): fidelity-relevant runtime targets fold into the
918
+ exact same required/permitted-target allocation and omission/truncation/
919
+ adequacy machinery v0.5 contract clauses already compete in, so a
920
+ `not-evaluated` fidelity always degrades adequacy away from `'adequate'`,
921
+ never silently reported as "no problems". A new `fidelity?:
922
+ BoundedReferenceFidelityProjection` field on `BoundedAgentContextArtifact`
923
+ mirrors `correlations?`'s own additive precedent - no schema version bump.
924
+ v0.6's own runtime/static correlation is reused entirely unchanged.
925
+ - **Identity**: `buildBoundedAgentContextRequestIdentity` gained a final
926
+ optional `fidelity` parameter (omit-when-absent; verified byte-identical
927
+ for every pre-Prompt-7 call site).
928
+ - **Persistence / CLI**: none - bounded agent context remains
929
+ library-only, exactly as v0.6 established it.
930
+ - **Export/public boundary**: `src/index.ts` exports the complete new
931
+ fidelity-projection type/constant/function surface.
932
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
933
+ lint`, `npm test` (49 files, 981 tests), `npm run test:browser` (9 files,
934
+ 120 tests, unchanged), `npm run test:security`, `npm run build`, `npm run
935
+ check:docs`, `git diff --check`, and `npm pack --dry-run` all pass with
936
+ zero changes to any pre-existing test.
937
+ - **Not implemented in this stage** (explicitly deferred to Prompt 8):
938
+ the end-to-end coding-agent correction workflow, viewer, and annotation.
939
+
940
+ ## v0.7 Prompt 8 status (Controlled End-to-End External-Reference Coding-Agent Correction Workflow) - released as `0.7.0`
941
+
942
+ The first complete v0.7 correction cycle, composing every Prompt 1-7 and
943
+ v0.1/v0.4/v0.5/v0.6 owner - this completes the v0.7 (End-to-End Coding-Agent
944
+ Frontend Change Review) milestone's core workflow.
945
+
946
+ - **Domain** (`src/domain/referenceCorrectionWorkflow.ts`,
947
+ `referenceCorrectionIdentity.ts`): `prepareReferenceCorrection()`
948
+ evaluates the approved reference against the current (pre-change)
949
+ observation (Prompt 6) and, when evaluable, projects a bounded
950
+ coding-agent handoff (Prompt 7/v0.6) - a `not-evaluated` fidelity is
951
+ reported as `status: 'blocked-not-evaluated'`, never a fabricated
952
+ handoff. `reviewReferenceCorrectionAttempt()` composes one overall result
953
+ from a fresh post-edit candidate: `compareObservations` (v0.4) ->
954
+ `evaluateReferenceCandidateFidelity` (Prompt 6) -> `evaluateFrontendContract`
955
+ (v0.5) -> overall `'not-evaluated'`/`'pass'`/`'fail'`, where `'pass'`
956
+ requires *both* reference fidelity `'pass'` *and* v0.5 contract evaluation
957
+ `'PASS'` - matching the design reference is necessary but never
958
+ sufficient. Review identity is a deterministic hash of
959
+ `{referenceRequestId, baselineObservationId, baselineContractId,
960
+ baselineContractClauses, changeContractId, changeContractClauses,
961
+ bindingDeclarations}` (including actual contract *clause content*, not
962
+ merely the caller-authored contract id labels) - `reviewReferenceCorrectionAttempt`
963
+ recomputes and rejects any call whose supplied review id does not match,
964
+ enforcing "no hidden baseline change" structurally. Attempt identity is a
965
+ deterministic hash of `{reviewRequestId, candidateObservationId}`. Both
966
+ functions are pure, so no prior attempt can ever be overwritten.
967
+ - **External implementation boundary**: absolute - neither this module nor
968
+ anything it calls opens, parses, or writes any target source file; real
969
+ candidate capture remains the caller's own responsibility through the
970
+ existing, unmodified `runBrowserCapture`/`buildObservationArtifact`
971
+ pipeline. No automatic baseline/reference approval ever occurs.
972
+ - **Persistence / CLI**: none - both operations remain pure, in-memory,
973
+ programmatic functions; no `--output` flag, no new command.
974
+ - **Real-Chromium proof** (`tests/browser/referenceCorrectionWorkflow.test.ts`):
975
+ a deterministic, test-only "controlled external actor" (living entirely
976
+ outside `src/`) edits a disposable, repository-local copy of a tracked
977
+ HTML fixture template, proving a full success correction, a protected-
978
+ regression case (candidate visually matches the reference but a real
979
+ Chromium-observed element becomes hidden - still overall `FAIL`), a
980
+ two-attempt correction iteration (both attempts traceable to the same
981
+ baseline), and an incompatible-viewport blocking case that never produces
982
+ a handoff. The tracked template remains byte-identical before and after.
983
+ - **Export/public boundary**: `src/index.ts` exports the complete new
984
+ workflow/identity type/constant/function surface.
985
+ - **Validated on the canonical worktree**: `npm run typecheck`, `npm run
986
+ lint`, `npm test` (50 files, 1000 tests), `npm run test:browser` (10
987
+ files, 124 tests), `npm run test:security`, `npm run build`, `npm run
988
+ check:docs`, `git diff --check`, `npm pack --dry-run`, and a real
989
+ installed-packed-candidate smoke all pass with zero regressions to any
990
+ pre-existing test.
991
+ - **Not implemented in this stage** (remain future, v0.8+): interactive
992
+ viewer, structured visual annotation, and automatic baseline/reference
993
+ approval (approval remains an explicit, separate action through the
994
+ existing `approve-baseline`/`approve-reference` commands).
995
+
996
+ ## v0.8 status (Interactive Local Observation Viewer) - released as `0.8.0`
997
+
998
+ All eight v0.8 implementation batches have passed
999
+ (`IMPLEMENTATION_BATCHES_STATUS: ALL_8_IMPLEMENTATION_BATCHES_PASS`), followed
1000
+ by a hardened documentation/implementation-completeness audit and formal
1001
+ pre-release readiness (cross-platform Windows/Linux/macOS packed-candidate
1002
+ validation, security audit, code-rot audit - see
1003
+ `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`).
1004
+ No schema version changed for v0.8, and no CLI command from v0.1-v0.7 was
1005
+ altered.
1006
+
1007
+ - **Batch 1** (`docs/reports/v0.8-viewer-runtime-pwa-batch1.md`) froze the
1008
+ version-start architecture decisions (React + TypeScript + Vite; normal
1009
+ browser + Node-backed loopback server + installable PWA using the same
1010
+ application; ephemeral viewer adapters over existing canonical readers,
1011
+ never a new persisted viewer artifact) and implemented the `view` CLI
1012
+ command (`--root`, `--port`, `--no-open`), the loopback-only (`127.0.0.1`)
1013
+ Node viewer server, the built React/Vite/PWA shell (service worker,
1014
+ manifest, app-shell precache with an `/api/` cache-boundary denylist), and
1015
+ one minimal read-only status endpoint. `npm run build` gained the
1016
+ `dist/viewer` build step.
1017
+ - **Batch 2** (`v0.8-evidence-index-readers-batch2.md`) added bounded,
1018
+ metadata-first evidence discovery (`GET /api/index`) across every existing
1019
+ artifact family, honest support-state classification
1020
+ (supported/unsupported-version/invalid-structure/unrecognized-kind/
1021
+ malformed-json/unreadable), and on-demand full-artifact/media loading
1022
+ (`GET /api/artifacts/<handle>`, `GET /api/media/<handle>/<role>`) with
1023
+ path-containment/traversal safety.
1024
+ - **Batch 3** (`v0.8-observation-svg-inspection-batch3.md`) added the
1025
+ observation screenshot/SVG-overlay workspace: runtime target geometry,
1026
+ semantics, visibility, overflow, scroll evidence, and on-demand layout
1027
+ relationships (`GET /api/observations/<handle>/relationships`, reusing the
1028
+ existing canonical `deriveLayoutRelationships` at its one sanctioned
1029
+ viewer-server call site).
1030
+ - **Batch 4** (`v0.8-comparison-contract-inspection-batch4.md`) added
1031
+ before/after comparison and contract/change-scope inspection
1032
+ (`GET /api/comparisons/<handle>/view`, `GET /api/evaluations/<handle>/view`),
1033
+ exact-identity linked-evidence resolution (never fuzzy matching), and the
1034
+ required protected/preserved-failure safety case (a locally successful
1035
+ requested change alongside a genuine protected/preserved regression,
1036
+ shown as overall `FAIL`, never masked).
1037
+ - **Batch 5** (`v0.8-reference-candidate-inspection-batch5.md`) added
1038
+ external-reference and reference/candidate inspection: reference image and
1039
+ region overlays in the reference's own pixel coordinate domain, explicit
1040
+ (never auto-selected) candidate selection, reference/candidate
1041
+ compatibility, adequacy, and applicability display.
1042
+ - **Batch 6** (`v0.8-binding-fidelity-interaction-batch6.md`) added
1043
+ explicit-binding cross-selection (reference region ↔ runtime target, only
1044
+ through an explicit `--bindings-file` declaration, never inferred from
1045
+ matching names), independent bounded (`1x`-`8x`) zoom/pan per pane,
1046
+ conditional view lock (enabled only when compatibility/coordinate-mapping
1047
+ genuinely permit it), and on-demand reference-fidelity evaluation
1048
+ (`not-evaluated`/`pass`/`fail`) shown alongside, never merged into, any
1049
+ selected contract evaluation's own verdict.
1050
+ - **Batch 7** (`v0.8-bounded-context-correlation-batch7.md`) added the
1051
+ `--context-file` input and a dedicated "Bounded context" mode: session-only
1052
+ bounded-agent-context display (identity, adequacy, omissions/truncations
1053
+ with required loss visually distinguished from optional loss,
1054
+ runtime/static correlation - `correlated`/`ambiguous`/`unavailable`,
1055
+ never "owner" language), safe raw-evidence navigation, and explicit
1056
+ non-ownership/non-rebuild language. The viewer never calls
1057
+ `projectBoundedAgentContext`, `deriveRuntimeStaticCorrelations`, or
1058
+ `attachRuntimeStaticCorrelations` - it only displays the exact context it
1059
+ was started with.
1060
+ - **Batch 8** (`v0.8-integrated-viewer-acceptance-batch8.md`, the final
1061
+ implementation batch) integrated and hardened the above rather than adding
1062
+ new features: closed three named real-browser coverage gaps (many
1063
+ reference regions bound to one runtime target must all cross-highlight;
1064
+ reference-fidelity FAIL alongside a genuine frontend-contract PASS for the
1065
+ same candidate must display independently with no hidden precedence; a
1066
+ bounded context whose sources include two observations sharing a stable
1067
+ target id must list every matching source observation, never one); fixed a
1068
+ real accessibility gap (a cross-highlighted, non-selected region/target
1069
+ rect now exposes `data-highlighted` plus an `aria-label` suffix to
1070
+ assistive technology, without disturbing `aria-pressed`'s existing
1071
+ single-selection semantics); added the first live-browser PWA proof suite
1072
+ (real service-worker registration, zero `/api/` cache-storage entries, and
1073
+ a hard server-down "stale evidence must never be presented as current"
1074
+ gate, which held); and proved the actual packed-and-installed npm
1075
+ candidate (not just the source checkout) works end-to-end through a real
1076
+ browser, with read-only evidence-root integrity confirmed via before/after
1077
+ content hashing. Standalone/installed-PWA proof did not exceed CDP
1078
+ command-acceptance (the emulated display-mode feature was not observed to
1079
+ take effect) - recorded honestly as a residual gap, not overstated as
1080
+ actual OS-level installation verification.
1081
+
1082
+ **Architectural invariants proven across all eight batches** (re-audited in
1083
+ this documentation/completeness stage): no second observer, relationship
1084
+ engine, comparison engine, contract engine, reference model,
1085
+ reference-evaluation engine, correlation implementation, or bounded-context
1086
+ builder exists anywhere in `src/viewerServer` or `viewer/src` - every
1087
+ canonical engine function the viewer displays results from is called from at
1088
+ most one designated server-side call site, and several (`compareObservations`,
1089
+ `evaluateFrontendContract`, `projectBoundedAgentContext`,
1090
+ `deriveRuntimeStaticCorrelations`, `attachRuntimeStaticCorrelations`) are
1091
+ never called by the viewer at all. The viewer never runs
1092
+ `@dailephd/my-dev-kit`, never mutates target source or any Observer
1093
+ artifact, never persists a new viewer-owned evidence family, and every route
1094
+ rejects non-`GET`/`HEAD` methods. (That was the complete v0.8 surface. v0.9
1095
+ later adds exactly three project-aware authoring `POST` routes. See "v0.9
1096
+ status" below.)
1097
+
1098
+ **Validated on the canonical worktree**: `npm run typecheck`, `npm run
1099
+ lint`, `npm test`, `npm run build`, `npm run check:docs`, `npm run
1100
+ test:browser`, and `npm run test:security` all pass - see "Post-edit
1101
+ validation" in
1102
+ `docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md`
1103
+ for the completeness-stage counts, and
1104
+ `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`
1105
+ for the formal cross-platform/security readiness stage that followed.
1106
+
1107
+ Formal Windows/Linux/macOS cross-platform pre-release validation of the
1108
+ viewer/PWA surface (through `.github/workflows/pre-release-readiness.yml`,
1109
+ now covering v0.1-v0.8) and formal pre-release security review of the
1110
+ viewer surface both passed - see the readiness report above, including the
1111
+ one security finding it found and fixed (a symlinked-media evidence-root
1112
+ escape in the viewer's media route).
1113
+
1114
+ ## v0.9 status (Human Visual Annotation and Design-Intent Capture) - released as 0.9.0
1115
+
1116
+ v0.9 is implemented against the frozen plan
1117
+ `docs/plans/v0.9-implementation-plan.md` and released as
1118
+ `@dailephd/my-frontend-observer@0.9.0`.
1119
+
1120
+ - **Prompt 1** (`docs/reports/v0.9-batch1-visual-annotation-foundation.md`)
1121
+ added the `VisualAnnotationArtifact` domain (schema `1.0.0`), structured
1122
+ point/rectangle/line/arrow/note marks, runtime and reference coordinate
1123
+ spaces, explicit associations, candidate/confirmed interpretation,
1124
+ deterministic identity, the atomic writer, the canonical reader, the
1125
+ persistence service, and the derived overlay SVG.
1126
+ - **Prompt 2**
1127
+ (`docs/reports/v0.9-batch2-viewer-annotation-authoring-boundary.md`) added
1128
+ viewer discovery of annotations, the source-resolving annotation view
1129
+ route, the verified overlay media role, and the project-aware authoring
1130
+ boundary with `POST /api/annotations`. `view --root` stays read-only.
1131
+ - **Prompt 3**
1132
+ (`docs/reports/v0.9-batch3-runtime-screenshot-annotation-authoring.md`)
1133
+ added runtime screenshot annotation in runtime CSS pixels with zoom, pan,
1134
+ keyboard selection, save, reload, revisions, and stale-parent conflicts.
1135
+ - **Prompt 4**
1136
+ (`docs/reports/v0.9-batch4-external-reference-annotation-authoring.md`)
1137
+ added external-reference annotation in reference-image pixels, candidate
1138
+ region create and refine proposals, candidate reference requirements, and
1139
+ informational and asset-sensitive intent.
1140
+ - **Prompt 5**
1141
+ (`docs/reports/v0.9-batch5-runtime-intent-contract-promotion.md`) added
1142
+ runtime intent, explicit confirmation, promotion of selected confirmed
1143
+ `move`/`resize`/`preserve` intent into a canonical per-change contract
1144
+ (`POST /api/annotations/:handle/promote-contract`), optional explicit
1145
+ project contract activation, and `.tmp-*` discovery exclusion. Confirmed
1146
+ `remove` intent is honestly non-promotable.
1147
+ - **Prompt 6** (`docs/reports/v0.9-batch6-reference-materialization.md`)
1148
+ added materialization of selected confirmed reference regions and
1149
+ requirements into a new imported external-reference revision
1150
+ (`POST /api/annotations/:handle/materialize-reference`). The source is never
1151
+ changed and nothing is approved automatically.
1152
+ - **Prompt 7** (`docs/reports/v0.9-batch7-integrated-acceptance.md`) added the
1153
+ integrated real-Chromium acceptance suite
1154
+ (`tests/browser/v09IntegratedAcceptance.test.ts`), the packed installed
1155
+ annotation smoke (`scripts/ci/runPackedV09AnnotationSmoke.mjs`), its step in
1156
+ the pre-release readiness matrix, and this documentation reconciliation.
1157
+
1158
+ Current versions: package `0.9.0`, viewer protocol `1.3.0`, visual annotation
1159
+ schema `1.0.0`, frontend contract schema `1.0.0`, external-reference schema
1160
+ `1.0.0`. No other schema changed.
1161
+
1162
+ Invariants: annotations are evidence, not contracts. Only selected confirmed
1163
+ supported intent is promoted or materialized, always through the existing
1164
+ canonical contract and external-reference services. The existing contract,
1165
+ reference relationship, adequacy, and fidelity evaluators remain the only
1166
+ source of verdicts. Observer never edits target source, never approves a
1167
+ baseline or reference automatically, and never updates project reference
1168
+ acceptance.
1169
+
1170
+ Validation state: the full local validation suite, the integrated acceptance
1171
+ suite, and all three packed installed-candidate smokes passed locally on
1172
+ Windows. See the Prompt 7 report for exact results. A cross-platform
1173
+ pre-release readiness run passed on Windows, Linux, and macOS for the Prompt 7
1174
+ commit `a78a058` (`docs/reports/v0.9-pre-release-readiness.md`). That run is
1175
+ historical evidence only. It did not contain the demo and tutorial commits
1176
+ described below, so it is not readiness evidence for the final candidate.
1177
+
1178
+ ### v0.9 demo and tutorials (release support, not product behavior)
1179
+
1180
+ - **Demo foundation** (commit `59ae009`,
1181
+ `docs/reports/v0.9-demo-foundation.md`): a deterministic demo application
1182
+ in `examples/v09-demo/` with ten stable region names, nine frozen states, a
1183
+ loopback-only demo server, a disposable-target materializer, and a fixed
1184
+ 1440x900 reference PNG.
1185
+ - **Tutorial integration** (commit `6895b30`,
1186
+ `docs/reports/v0.9-tutorial-integration.md`): four `TutorialScenarioV1`
1187
+ scenarios in `examples/v09-demo/tutorials/`, a per-run target-contract
1188
+ generator, and a prepare command that builds each disposable target through
1189
+ the canonical `init`, `capture`, contract, and reference commands. The only
1190
+ product change was two optional `data-testid` attributes on the viewer
1191
+ drawing surfaces.
1192
+ - **End-to-end acceptance**
1193
+ (`docs/reports/v0.9-tutorial-end-to-end-acceptance.md`): all four tutorials
1194
+ regenerated from clean targets with `@dailephd/my-dev-kit-lab@0.4.9`,
1195
+ structural and content acceptance, canonical evidence checks, and a full
1196
+ local regression. Scenario narration, reading pauses, and screenshot
1197
+ requests were corrected in this stage. Human visual review of the videos
1198
+ was completed and approved before release.
1199
+ - **Final pre-release readiness**
1200
+ (`docs/reports/v0.9-final-pre-release-readiness.md`, with corrections in
1201
+ `docs/reports/v0.9-final-readiness-corrections.md`): one exact candidate
1202
+ package passed the packed observation, viewer and v0.9 annotation smokes and
1203
+ all four tutorials on Windows, Linux and macOS, using
1204
+ `@dailephd/my-dev-kit-lab@0.4.9` semantic `select-option` for native
1205
+ selects.
1206
+
1207
+ The four scenarios are annotation basics, runtime intent to an active change
1208
+ contract, reference authoring, and reference materialization. After each run
1209
+ the canonical evidence is read directly from the disposable target. The checks
1210
+ prove, for example, that only the two selected clauses were promoted, that
1211
+ `remove` and `inspect` never became clauses, and that a materialized reference
1212
+ revision is `imported`, supersedes its approved source, and reuses the source
1213
+ image bytes unchanged.
1214
+
1215
+ `my-dev-kit-lab` is an external tool invoked through `npx`. It is not an
1216
+ Observer dependency, and Observer has no tutorial command, recorder, subtitle
1217
+ writer, or tutorial manifest schema. `examples/v09-demo/` is excluded from the
1218
+ npm package.
1219
+
1220
+ ## Not implemented
1221
+
1222
+ - v0.5 baseline-selection/discovery policy (the caller must supply which
1223
+ baseline to approve/evaluate against; there is no "find the current
1224
+ baseline" command), source ownership, and orchestrator/lab product
1225
+ integration all remain unimplemented in this repository.
1226
+ (v0.6's bounded runtime projection and runtime/static correlation, the
1227
+ complete v0.7 external-reference correction workflow described above, and
1228
+ the v0.8 interactive viewer described in "v0.8 status" above, *are* now
1229
+ implemented.) A CLI surface for Prompt 8's correction workflow specifically
1230
+ remains unimplemented by design (programmatic-only, library-level use is
1231
+ the current supported entry point) - see "v0.7 Prompt 8 status" above.
1232
+ The full graphical human-LLM workflow is released as `0.10.0`. Structured
1233
+ visual annotation (v0.9) is
1234
+ implemented and released as `0.9.0` - see "v0.9 status" above.
1235
+
1236
+ ## Next target
1237
+
1238
+ The next planned release is `v0.11.0` (OBS-DIAG-01: bounded runtime diagnostics and failure evidence). v0.12.0-v0.14.0 are later adopted roadmap reservations; none is implemented yet.
1239
+
1240
+ v0.1-v0.10 are implemented, validated, and released (`0.1.0`, `0.2.0`,
1241
+ `0.3.0`, `0.4.0`, `0.5.0`, `0.6.0`, `0.7.0`, `0.8.0`, `0.8.1`, `0.9.0`,
1242
+ `0.9.1`, `0.10.0`). v0.7 (End-to-End
1243
+ Coding-Agent Frontend Change Review) is fully implemented and released: the
1244
+ external-reference artifact foundation, explicit reference
1245
+ regions/relationships, selected design requirements/tolerance
1246
+ semantics/reference-evidence adequacy, reference applicability
1247
+ and candidate-state compatibility, explicit reference-region/
1248
+ runtime-target binding, structured reference-vs-candidate
1249
+ fidelity evaluation, bounded reference-fidelity projection into
1250
+ the existing v0.6 bounded-agent-context, and the controlled
1251
+ end-to-end correction workflow with real-Chromium proof are all
1252
+ implemented and released as package version `0.7.0`, following a completed
1253
+ pre-release readiness, cross-platform, and security validation stage - see
1254
+ `docs/ROADMAP.md` for v0.7's full scope,
1255
+ `docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md`
1256
+ for the completeness audit, and
1257
+ `docs/reports/v0.7-pre-release-readiness.md` for the cross-platform
1258
+ readiness validation that preceded this release.
1259
+
1260
+ v0.8 (Interactive Local Observation Viewer) is fully implemented, tested,
1261
+ and released - see "v0.8 status" above. v0.8.1 was released as
1262
+ `@dailephd/my-frontend-observer@0.8.1`. All
1263
+ eight implementation batches, the hardened documentation/implementation-
1264
+ completeness audit, and formal pre-release readiness (cross-platform and
1265
+ security validation) have passed - see `docs/ROADMAP.md` for v0.8's full
1266
+ scope,
1267
+ `docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md`
1268
+ for the completeness audit, and
1269
+ `docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md`
1270
+ for the cross-platform readiness validation that preceded this release.
1271
+
1272
+ v0.9 (structured visual annotation) is released as
1273
+ `@dailephd/my-frontend-observer@0.9.0` - see "v0.9 status" above. v0.10.0 is
1274
+ the previous release; v0.10.1 is the current maintenance release. v0.10.0's
1275
+ formal exact-candidate readiness passed on Windows,
1276
+ Linux, and macOS, including installed-package, security, and PWA gates. See
1277
+ `docs/reports/v0.10-release-preparation.md` for release-preparation evidence.