@dailephd/my-frontend-observer 0.8.1 → 0.9.0

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 (107) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +107 -7
  3. package/dist/application/projectWorkflowService.d.ts +18 -1
  4. package/dist/application/projectWorkflowService.js +40 -2
  5. package/dist/application/projectWorkflowService.js.map +1 -1
  6. package/dist/application/visualAnnotationContractPromotionService.d.ts +41 -0
  7. package/dist/application/visualAnnotationContractPromotionService.js +143 -0
  8. package/dist/application/visualAnnotationContractPromotionService.js.map +1 -0
  9. package/dist/application/visualAnnotationPersistenceService.d.ts +34 -0
  10. package/dist/application/visualAnnotationPersistenceService.js +68 -0
  11. package/dist/application/visualAnnotationPersistenceService.js.map +1 -0
  12. package/dist/application/visualAnnotationReferenceMaterializationService.d.ts +53 -0
  13. package/dist/application/visualAnnotationReferenceMaterializationService.js +194 -0
  14. package/dist/application/visualAnnotationReferenceMaterializationService.js.map +1 -0
  15. package/dist/artifacts/visualAnnotationArtifactReader.d.ts +19 -0
  16. package/dist/artifacts/visualAnnotationArtifactReader.js +66 -0
  17. package/dist/artifacts/visualAnnotationArtifactReader.js.map +1 -0
  18. package/dist/artifacts/visualAnnotationArtifactWriter.d.ts +42 -0
  19. package/dist/artifacts/visualAnnotationArtifactWriter.js +85 -0
  20. package/dist/artifacts/visualAnnotationArtifactWriter.js.map +1 -0
  21. package/dist/cli.js +464 -454
  22. package/dist/cli.js.map +1 -1
  23. package/dist/domain/visualAnnotation.d.ts +217 -0
  24. package/dist/domain/visualAnnotation.js +584 -0
  25. package/dist/domain/visualAnnotation.js.map +1 -0
  26. package/dist/domain/visualAnnotationIdentity.d.ts +17 -0
  27. package/dist/domain/visualAnnotationIdentity.js +47 -0
  28. package/dist/domain/visualAnnotationIdentity.js.map +1 -0
  29. package/dist/index.d.ts +11 -0
  30. package/dist/index.js +6 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/projectWorkflow/projectPaths.d.ts +9 -0
  33. package/dist/projectWorkflow/projectPaths.js +21 -0
  34. package/dist/projectWorkflow/projectPaths.js.map +1 -1
  35. package/dist/viewer/assets/{index-CN_yb9Uf.css → index-BN41MI7m.css} +1 -1
  36. package/dist/viewer/assets/index-CkKXnlrI.js +9 -0
  37. package/dist/viewer/index.html +2 -2
  38. package/dist/viewer/sw.js +1 -1
  39. package/dist/viewerServer/annotationAuthoring.d.ts +64 -0
  40. package/dist/viewerServer/annotationAuthoring.js +230 -0
  41. package/dist/viewerServer/annotationAuthoring.js.map +1 -0
  42. package/dist/viewerServer/annotationContractPromotion.d.ts +51 -0
  43. package/dist/viewerServer/annotationContractPromotion.js +105 -0
  44. package/dist/viewerServer/annotationContractPromotion.js.map +1 -0
  45. package/dist/viewerServer/annotationReferenceMaterialization.d.ts +40 -0
  46. package/dist/viewerServer/annotationReferenceMaterialization.js +91 -0
  47. package/dist/viewerServer/annotationReferenceMaterialization.js.map +1 -0
  48. package/dist/viewerServer/authoringSecurity.d.ts +59 -0
  49. package/dist/viewerServer/authoringSecurity.js +112 -0
  50. package/dist/viewerServer/authoringSecurity.js.map +1 -0
  51. package/dist/viewerServer/evidence/annotationView.d.ts +28 -0
  52. package/dist/viewerServer/evidence/annotationView.js +43 -0
  53. package/dist/viewerServer/evidence/annotationView.js.map +1 -0
  54. package/dist/viewerServer/evidence/classify.d.ts +3 -1
  55. package/dist/viewerServer/evidence/classify.js +12 -0
  56. package/dist/viewerServer/evidence/classify.js.map +1 -1
  57. package/dist/viewerServer/evidence/discovery.d.ts +2 -0
  58. package/dist/viewerServer/evidence/discovery.js +6 -0
  59. package/dist/viewerServer/evidence/discovery.js.map +1 -1
  60. package/dist/viewerServer/evidence/handles.js +1 -0
  61. package/dist/viewerServer/evidence/handles.js.map +1 -1
  62. package/dist/viewerServer/evidence/index.d.ts +29 -0
  63. package/dist/viewerServer/evidence/index.js +43 -1
  64. package/dist/viewerServer/evidence/index.js.map +1 -1
  65. package/dist/viewerServer/evidence/mediaResolver.d.ts +1 -1
  66. package/dist/viewerServer/evidence/mediaResolver.js +28 -2
  67. package/dist/viewerServer/evidence/mediaResolver.js.map +1 -1
  68. package/dist/viewerServer/evidence/projection.d.ts +5 -1
  69. package/dist/viewerServer/evidence/projection.js +19 -0
  70. package/dist/viewerServer/evidence/projection.js.map +1 -1
  71. package/dist/viewerServer/httpServer.d.ts +13 -2
  72. package/dist/viewerServer/httpServer.js +278 -4
  73. package/dist/viewerServer/httpServer.js.map +1 -1
  74. package/dist/viewerServer/viewerService.d.ts +8 -0
  75. package/dist/viewerServer/viewerService.js +38 -2
  76. package/dist/viewerServer/viewerService.js.map +1 -1
  77. package/docs/ARCHITECTURE.md +108 -21
  78. package/docs/CI_CD.md +57 -1
  79. package/docs/COMMANDS.md +44 -4
  80. package/docs/CONTRACTS.md +78 -8
  81. package/docs/CURRENT_STATE.md +157 -35
  82. package/docs/DEVELOPMENT.md +8 -3
  83. package/docs/PROJECT_DESCRIPTION.md +4 -1
  84. package/docs/PROJECT_MILESTONES.md +4 -0
  85. package/docs/PROJECT_OVERVIEW.md +41 -17
  86. package/docs/QUICKSTART.md +52 -39
  87. package/docs/RELEASE.md +16 -11
  88. package/docs/ROADMAP.md +406 -66
  89. package/docs/SECURITY.md +71 -14
  90. package/docs/WORKFLOWS.md +151 -23
  91. package/docs/plans/v0.9-implementation-plan.md +1529 -0
  92. package/docs/reports/v0.9-architecture-retrieval.md +567 -0
  93. package/docs/reports/v0.9-batch1-visual-annotation-foundation.md +351 -0
  94. package/docs/reports/v0.9-batch2-viewer-annotation-authoring-boundary.md +438 -0
  95. package/docs/reports/v0.9-batch3-runtime-screenshot-annotation-authoring.md +412 -0
  96. package/docs/reports/v0.9-batch4-external-reference-annotation-authoring.md +452 -0
  97. package/docs/reports/v0.9-batch5-runtime-intent-contract-promotion.md +535 -0
  98. package/docs/reports/v0.9-batch6-reference-materialization.md +514 -0
  99. package/docs/reports/v0.9-batch7-integrated-acceptance.md +644 -0
  100. package/docs/reports/v0.9-demo-foundation.md +589 -0
  101. package/docs/reports/v0.9-final-pre-release-readiness.md +209 -0
  102. package/docs/reports/v0.9-final-readiness-corrections.md +530 -0
  103. package/docs/reports/v0.9-pre-release-readiness.md +170 -0
  104. package/docs/reports/v0.9-tutorial-end-to-end-acceptance.md +980 -0
  105. package/docs/reports/v0.9-tutorial-integration.md +731 -0
  106. package/package.json +2 -2
  107. package/dist/viewer/assets/index-D98S1_2d.js +0 -9
@@ -0,0 +1,644 @@
1
+ # v0.9 Batch 7 Report: Integrated Acceptance, Packaging, Documentation, and Regression
2
+
3
+ ## 1. VERDICT
4
+
5
+ PASS_V0_9_BATCH7_INTEGRATED_IMPLEMENTATION_COMPLETE
6
+
7
+ v0.9 implementation is complete in the repository and validated locally. v0.9
8
+ is not released. The package version is still `0.8.1`.
9
+
10
+ ## 2. Repository identity
11
+
12
+ 1. Repository: `C:\Users\daile\Projects\my-frontend-observer`
13
+ 2. Branch: `master`
14
+ 3. Starting HEAD: `1dccd17d0fe9dfbbc5d476ea8deaae9625e1f395`
15
+ 4. Ending HEAD before the final commit: `1dccd17d0fe9dfbbc5d476ea8deaae9625e1f395`
16
+ 5. Package: `@dailephd/my-frontend-observer`, version `0.8.1` (unchanged in
17
+ `package.json` and `package-lock.json`)
18
+ 6. Node `v24.20.0`, npm `11.19.0`, Windows 11 (win32 x64)
19
+
20
+ ## 3. Prompt 6 entry gate
21
+
22
+ 1. Preflight: branch `master`, HEAD `1dccd17d0fe9dfbbc5d476ea8deaae9625e1f395`,
23
+ package `0.8.1`, clean tracked worktree.
24
+ 2. All six prior reports exist with PASS verdicts:
25
+ 1. `PASS_V0_9_BATCH1_VISUAL_ANNOTATION_FOUNDATION`
26
+ 2. `PASS_V0_9_BATCH2_VIEWER_ANNOTATION_AUTHORING_BOUNDARY`
27
+ 3. `PASS_V0_9_BATCH3_RUNTIME_SCREENSHOT_ANNOTATION_AUTHORING`
28
+ 4. `PASS_V0_9_BATCH4_EXTERNAL_REFERENCE_ANNOTATION_AUTHORING`
29
+ 5. `PASS_V0_9_BATCH5_RUNTIME_INTENT_CONTRACT_PROMOTION`
30
+ 6. `PASS_V0_9_BATCH6_REFERENCE_MATERIALIZATION`
31
+ 3. Constants verified in source: viewer protocol `1.3.0`
32
+ (`src/viewerServer/httpServer.ts`), visual annotation schema `1.0.0`,
33
+ frontend contract schema `1.0.0`, external-reference schema `1.0.0`.
34
+ 4. `git ls-files -v docs/reports/v0.9-architecture-retrieval.md` printed `S` at
35
+ entry and before commit. The skip-worktree state was preserved. The file was
36
+ not restored, overwritten, deleted, or committed. No pull, rebase, reset,
37
+ stash, or clean was run.
38
+
39
+ ## 4. v0.9 implementation inventory
40
+
41
+ This inventory lists implemented owners. It is not release evidence.
42
+
43
+ 1. Annotation domain: `src/domain/visualAnnotation.ts`.
44
+ 2. Annotation identity: `src/domain/visualAnnotationIdentity.ts`.
45
+ 3. Annotation reader and writer: `src/artifacts/visualAnnotationArtifactReader.ts`
46
+ and `src/artifacts/visualAnnotationArtifactWriter.ts`.
47
+ 4. Annotation persistence: `src/application/visualAnnotationPersistenceService.ts`.
48
+ 5. Viewer discovery: `visual-annotation` classification and `.tmp-*` exclusion
49
+ in `src/viewerServer/evidence/`, plus `evidence/annotationView.ts`.
50
+ 6. Annotation overlay media: the verified `annotation-overlay` media role.
51
+ 7. Secure authoring boundary: `src/viewerServer/authoringSecurity.ts`, the
52
+ shared gate in `httpServer.ts`, and the write queue in
53
+ `src/viewerServer/annotationAuthoring.ts`.
54
+ 8. Runtime annotation UI: `viewer/src/components/AnnotationLayer.tsx`,
55
+ `AnnotationToolbar.tsx`, `RuntimeAnnotationPanel.tsx`, and the runtime hooks.
56
+ 9. Reference annotation UI: `ReferenceAnnotationPanel.tsx`,
57
+ `CandidateRegionPreviewLayer.tsx`, and the reference hooks.
58
+ 10. Runtime intent model: `viewer/src/annotation/runtimeIntent.ts`.
59
+ 11. Runtime and reference confirmation: `viewer/src/annotation/confirmation.ts`
60
+ and `referenceIntent.ts`.
61
+ 12. Contract promotion: `src/application/visualAnnotationContractPromotionService.ts`
62
+ and `src/viewerServer/annotationContractPromotion.ts`.
63
+ 13. Reference materialization:
64
+ `src/application/visualAnnotationReferenceMaterializationService.ts` and
65
+ `src/viewerServer/annotationReferenceMaterialization.ts`.
66
+ 14. Project contract activation: `activateProjectChangeContract` in
67
+ `src/application/projectWorkflowService.ts`.
68
+
69
+ ## 5. Integrated acceptance matrix
70
+
71
+ Every scenario below passed in the Pass A full runs (`npm run test:browser`:
72
+ 26 files, 235 tests; `npm test`: 84 files, 1379 tests) and in the packed smokes
73
+ recorded in sections 15 to 17.
74
+
75
+ 1. Scenario 1: runtime annotation
76
+ 1. Requirement: project-aware view, draw and note, save, reload the browser,
77
+ same canonical source, item ids, structured marks, and runtime CSS-pixel
78
+ geometry.
79
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts`, "annotates a
80
+ runtime observation, reloads it from canonical evidence, promotes only
81
+ confirmed supported intent, and keeps remove, notes, and free marks
82
+ non-contractual". Also `tests/browser/runtimeAnnotationAuthoring.test.ts`,
83
+ "reloads a saved annotation from canonical evidence with the same ids,
84
+ marks, associations, and source", and the packed v0.9 smoke.
85
+ 3. Result: PASS
86
+ 4. Evidence: the persisted source matches the observation id and request id.
87
+ After `page.reload()` the loaded draft renders the same four item ids,
88
+ and the rendered rectangle `x` and `width` equal the persisted runtime
89
+ CSS-pixel values.
90
+ 2. Scenario 2: alias identity
91
+ 1. Requirement: alias current to A, annotate A, alias moves to B, the
92
+ annotation stays bound to A.
93
+ 2. Test: `tests/browser/runtimeAnnotationAuthoring.test.ts`, "never rebinds
94
+ a saved annotation when the alias moves to another observation".
95
+ 3. Result: PASS
96
+ 4. Evidence: after the canonical alias catalog moves `current` to B and the
97
+ viewer restarts, B shows no saved annotations, A still lists X, and the
98
+ persisted source still names A.
99
+ 3. Scenario 3: move intent to contract
100
+ 1. Requirement: mark, explicit target association, move candidate, explicit
101
+ confirmation, save, selected promotion, normal `PerChangeContract`.
102
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts` (runtime test
103
+ above). Also `tests/browser/runtimeAnnotationContractPromotion.test.ts`,
104
+ "promotes explicit move intents; arrow direction never decides the move
105
+ direction", and the packed v0.9 smoke.
106
+ 3. Result: PASS
107
+ 4. Evidence: the promoted contract has `contractClass: change`, schema
108
+ `1.0.0`, and exactly one clause `requested`
109
+ `property-increases header.x`.
110
+ 4. Scenario 4: preserve intent to contract
111
+ 1. Requirement: one complete preserve path into a canonical contract.
112
+ 2. Test: `tests/browser/runtimeAnnotationContractPromotion.test.ts`,
113
+ "promotes only the selected items, including expected-dependent resize
114
+ and preserve property/relationship intent".
115
+ 3. Result: PASS
116
+ 4. Evidence: a preserved `property-unchanged-within-tolerance sidebar.width`
117
+ (absolute-px 2) clause and a protected `relationship-unchanged` clause
118
+ are persisted in normal canonical `PerChangeContract` artifacts.
119
+ 5. Scenario 5: remove remains unsupported
120
+ 1. Requirement: remove candidate, confirm, save and reload, no primitive, no
121
+ checkbox, forced promotion rejected, no contract.
122
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts` (runtime test).
123
+ Also `runtimeAnnotationContractPromotion.test.ts`, "keeps remove,
124
+ inspect, and unconfirmed candidates out of promotion, including forced
125
+ API requests".
126
+ 3. Result: PASS
127
+ 4. Evidence: the saved remove item is confirmed with no `contractPrimitive`.
128
+ After reload its promotion checkbox is disabled. A forced promotion
129
+ returns 422, and the contracts directory holds only the move contract.
130
+ 6. Scenario 6: ambiguous or free drawing
131
+ 1. Requirement: a free mark stays visual evidence and never becomes an
132
+ association, clause, or requirement.
133
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts` (runtime test).
134
+ Also `runtimeAnnotationAuthoring.test.ts`, "never associates a mark drawn
135
+ over a target until the user explicitly associates it", and
136
+ `referenceAnnotationAuthoring.test.ts`, "never turns drawn geometry over a
137
+ region into a requirement, and saving never confirms".
138
+ 3. Result: PASS
139
+ 4. Evidence: a rectangle drawn over `header` is saved uninterpreted with no
140
+ association. It is not listed for promotion, and a forced promotion
141
+ returns 422.
142
+ 7. Scenario 7: reference annotation
143
+ 1. Requirement: open a reference, draw, save, reload, reference-image pixels.
144
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts`, "annotates an
145
+ approved reference in image pixels, reloads it, and materializes a
146
+ confirmed region and measurement requirement into a new imported
147
+ revision without touching sources or project acceptance". Also
148
+ `referenceAnnotationAuthoring.test.ts`, "reloads marks, associations, and
149
+ candidate/confirmed intent from canonical evidence on the exact
150
+ reference".
151
+ 3. Result: PASS
152
+ 4. Evidence: the persisted source is `reference-image-px` 400x300 for the
153
+ approved reference, with the imported image owner. After reload the
154
+ rendered rectangle equals the persisted reference-pixel mark (x 200,
155
+ height 100 within one pixel of pointer input).
156
+ 8. Scenario 8: region create materialization
157
+ 1. Requirement: rectangle, candidate create, confirm, save, select,
158
+ materialize, new imported reference, source unchanged, explicit
159
+ supersession.
160
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts` (reference test).
161
+ Also `tests/browser/referenceAnnotationMaterialization.test.ts`,
162
+ "materializes a confirmed created region into a new imported revision
163
+ without approval, config change, or switching the viewed reference", and
164
+ the packed v0.9 smoke.
165
+ 3. Result: PASS
166
+ 4. Evidence: the new artifact is `imported`, supersedes the approved source
167
+ id, and has regions `header`, `sidebar`, `hero-new`. Byte snapshots of
168
+ the approved and imported source directories are identical.
169
+ 9. Scenario 9: region refine materialization
170
+ 1. Requirement: existing region, candidate refine, confirm, materialize,
171
+ revised rectangle, same id, old reference unchanged.
172
+ 2. Test: `tests/browser/referenceAnnotationMaterialization.test.ts`,
173
+ "materializes a confirmed refinement from an approved source, superseding
174
+ the approved id and reusing the owning image bytes".
175
+ 3. Result: PASS
176
+ 4. Evidence: `sidebar` keeps its id with the new rectangle, `header` is
177
+ unchanged, and both source directories are byte-identical.
178
+ 10. Scenario 10: reference requirements
179
+ 1. Requirement: region-property, region-relationship, and
180
+ region-measurement travel through canonical reference semantics, with
181
+ at least one going from viewer authoring to a new
182
+ `ExternalReferenceArtifact`.
183
+ 2. Tests:
184
+ 1. region-measurement, full path:
185
+ `tests/browser/v09IntegratedAcceptance.test.ts` (reference test).
186
+ 2. region-property, full path:
187
+ `referenceAnnotationMaterialization.test.ts`, "materializes only the
188
+ selected subset: a created region and a requirement against it,
189
+ never the unselected create".
190
+ 3. region-relationship: authoring and confirmation in
191
+ `referenceAnnotationAuthoring.test.ts`, "authors a
192
+ region-relationship requirement only from canonical relationships,
193
+ with no tolerance". Materialization and canonical relationship
194
+ derivation in `tests/unit/visualAnnotationReferenceMaterialization.test.ts`,
195
+ "keeps existing requirements first with recomputed identical ids,
196
+ then selected requirements in selection order" and "exposes normal
197
+ canonical relationships and adequacy for the new reference".
198
+ 3. Result: PASS
199
+ 4. Evidence: the materialized measurement requirement persists only
200
+ `category`, `requirementId`, `subject`, and `tolerance` (no measured
201
+ value). All requirements pass canonical validation.
202
+ 11. Scenario 11: informational intent
203
+ 1. Requirement: inspect, note, and asset-sensitive stay informational.
204
+ 2. Tests: `tests/browser/v09IntegratedAcceptance.test.ts` (note, runtime
205
+ test); `runtimeAnnotationContractPromotion.test.ts` (inspect forced
206
+ 422); `referenceAnnotationMaterialization.test.ts`, "keeps
207
+ informational and candidate items unselectable, and forced API requests
208
+ for them are rejected without a write"; and
209
+ `referenceAnnotationAuthoring.test.ts`, "records informational and
210
+ asset-sensitive intent only through explicit actions and confirmation".
211
+ 3. Result: PASS
212
+ 4. Evidence: notes and inspect items are never listed for promotion, and
213
+ forced promotion returns 422. Informational reference items are
214
+ disabled with the informational reason, and forced materialization
215
+ returns 422 with no reference written.
216
+ 12. Scenario 12: stale revision
217
+ 1. Requirement: B supersedes A, a second child from stale A conflicts with
218
+ no overwrite and no silent branch.
219
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts`, "rejects a second
220
+ child of a stale revision without overwrite, and keeps an annotation
221
+ inspectable with an honestly unavailable source". Also
222
+ `runtimeAnnotationAuthoring.test.ts`, "keeps the draft and shows a
223
+ conflict when the loaded parent was already revised elsewhere, without
224
+ retrying".
225
+ 3. Result: PASS
226
+ 4. Evidence: two real pages share one viewer. The stale page receives 409
227
+ and a "Save conflict" alert and keeps its draft. Exactly two annotation
228
+ directories exist, and A and B manifests are byte-identical.
229
+ 13. Scenario 13: unrelated origin
230
+ 1. Requirement: an unrelated browser origin cannot POST any authoring
231
+ write. The security suite covers all three routes.
232
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts`, "never lets an
233
+ unrelated browser origin read the authoring capability or write through
234
+ any authoring POST route". Unit route suites
235
+ `viewerAuthoringSecurity.test.ts`, `viewerAnnotationAuthoring.test.ts`,
236
+ `viewerAnnotationContractPromotion.test.ts`, and
237
+ `viewerAnnotationReferenceMaterialization.test.ts` (all in
238
+ `npm run test:security`).
239
+ 3. Result: PASS
240
+ 4. Evidence: from a real page on another loopback origin, reading
241
+ `/api/authoring/session` and JSON POSTs to all three routes are blocked
242
+ by the browser. Simple no-cors POSTs are opaque. With the real token, a
243
+ request carrying the unrelated `Origin` returns 403 on all three routes.
244
+ No annotation, contract, or reference was written.
245
+ 14. Scenario 14: missing source
246
+ 1. Requirement: the annotation stays loadable after its source
247
+ disappears, source status `unavailable`, no replacement guessed.
248
+ 2. Test: `tests/browser/v09IntegratedAcceptance.test.ts` (stale revision
249
+ and missing source test). Also `tests/unit/viewerAnnotationEvidence.test.ts`,
250
+ "D: keeps the annotation loadable and reports the source unavailable when
251
+ source evidence is removed".
252
+ 3. Result: PASS
253
+ 4. Evidence: after the observation directory is moved outside the evidence
254
+ root, the annotation is still a supported evidence-list entry with a raw
255
+ preview. Its view route returns 200 with `source.status: unavailable`,
256
+ no handle, and no mention of the other observation present in the root.
257
+ 15. Scenario 15: v0.8 viewer regression
258
+ 1. Requirement: screenshot, targets, relationships, comparison, contract
259
+ evaluation, reference and candidate inspection, bindings, fidelity,
260
+ bounded context, zoom and pan, PWA shell.
261
+ 2. Tests (all unchanged v0.8 browser suites, run in `npm run test:browser`):
262
+ 1. `observationSvgWorkspace.test.ts` (screenshot, targets, relationships);
263
+ 2. `comparisonEvaluationWorkspace.test.ts` (comparison, contract
264
+ evaluation, safety case);
265
+ 3. `referenceCandidateWorkspace.test.ts` (reference and candidate);
266
+ 4. `referenceBindingFidelityWorkspace.test.ts` (bindings, zoom and pan,
267
+ lock, fidelity);
268
+ 5. `boundedContextWorkspace.test.ts` (bounded context);
269
+ 6. `viewerIntegratedAcceptance.test.ts` (v0.8 integrated scenarios);
270
+ 7. `viewerShell.test.ts`, `viewerEvidenceShell.test.ts`, and
271
+ `pwaHardening.test.ts` (shell, index, PWA);
272
+ 8. the packed viewer smoke.
273
+ 3. Result: PASS
274
+ 4. Evidence: every listed suite passed unchanged except `pwaHardening`,
275
+ which gained the materialization route in its no-cache assertion.
276
+ 16. Scenario 16: v0.8.1 project workflow regression
277
+ 1. Requirement: `init`, `capture baseline`, `check baseline`, `view`, and
278
+ advanced low-level commands.
279
+ 2. Tests: `projectCheckWorkflow.test.ts`, `projectWorkflowViewer.test.ts`,
280
+ `tests/unit/cliProjectWorkflow.test.ts`; low-level
281
+ `cliObserve.test.ts`, `cliCompare.test.ts`, and
282
+ `cliFrontendContracts.test.ts`; the packed observation smoke (low-level
283
+ installed commands) and the packed viewer smoke (installed
284
+ `init`/`capture`/`check`/`view` with REVIEW_REQUIRED, FAIL, and PASS).
285
+ 3. Result: PASS
286
+ 4. Evidence: all suites pass. Annotation is never required for ordinary
287
+ project use. The packed v0.9 smoke also ran `init`, `capture baseline`,
288
+ and `check baseline --json` (deterministic REVIEW_REQUIRED with no
289
+ acceptance configured).
290
+ 17. Scenario 17: clean installed package
291
+ 1. Requirement: from the installed tarball only, project workflow,
292
+ project-aware authoring, runtime save and reload, promotion, contract
293
+ inspection, reference annotation, materialization, new reference
294
+ inspection, and standalone read-only safety.
295
+ 2. Test: `scripts/ci/runPackedV09AnnotationSmoke.mjs` against the exact
296
+ packed tarball.
297
+ 3. Result: PASS
298
+ 4. Evidence: see sections 13, 14, and 17. Every summary flag was true.
299
+
300
+ ## 6. Runtime annotation integrated proof
301
+
302
+ The runtime integrated test uses the real Node viewer server, the built React
303
+ viewer, and real Chromium pointer input. It draws a move rectangle over
304
+ `header`, a remove rectangle over `sidebar`, a free rectangle over `header`,
305
+ and a note. It associates only the first two, sets and confirms intent, and
306
+ saves. It reads the canonical manifest, reloads the page, reopens the
307
+ observation, and loads the saved annotation. The rendered ids and marks match
308
+ the canonical artifact exactly.
309
+
310
+ ## 7. Runtime intent/contract integrated proof
311
+
312
+ After reload, only the confirmed move item is selectable. Promotion returns
313
+ 201 with one clause. The persisted contract is read with the canonical
314
+ `readPerChangeContract`: `contractClass: change`, schema `1.0.0`, clause
315
+ `requested` `property-increases header.x`. Forced promotion of the remove item,
316
+ the free mark, and the note each returns 422, and no other contract exists.
317
+ After another reload the contract is a normal supported evidence-list entry
318
+ whose raw preview shows the clause.
319
+
320
+ ## 8. Reference annotation integrated proof
321
+
322
+ The reference integrated test runs in a real initialized project whose
323
+ configuration sets `acceptance.reference.approvedArtifact`. It opens the
324
+ approved reference, draws a rectangle, proposes `hero-new`, confirms, then
325
+ authors and confirms a preserved `region-measurement` requirement
326
+ (`header` to `hero-new`, `vertical-gap`, exact). It saves, checks the persisted
327
+ reference-image-pixel source, reloads, and reloads the saved annotation with
328
+ matching rendered geometry.
329
+
330
+ ## 9. Reference materialization integrated proof
331
+
332
+ Both confirmed items are selected and materialized. The response is 201 with
333
+ `lifecycle: imported`, `approvalRequired: true`, and supersession of the
334
+ approved id. The canonical reader shows regions `header`, `sidebar`,
335
+ `hero-new` and the measurement requirement last. Both source directories are
336
+ byte-identical, exactly one new reference directory exists, the project config
337
+ bytes are unchanged, and only one approved reference exists. After reload the
338
+ new reference opens in the normal reference workspace with `hero-new` rendered.
339
+
340
+ ## 10. Security integrated proof
341
+
342
+ 1. Real-browser unrelated origin: see scenario 13.
343
+ 2. Standalone read-only: the packed v0.9 smoke starts installed
344
+ `view --root <evidence-root>`. It proves `enabled: false`, 403 on all three
345
+ authoring routes even with a valid project token, no drawing or save
346
+ controls, no non-GET/HEAD page requests, and no evidence changes.
347
+ 3. `npm run test:security` still includes the four v0.9 security suites
348
+ (`viewerAuthoringSecurity`, `viewerAnnotationAuthoring`,
349
+ `viewerAnnotationContractPromotion`, `viewerAnnotationReferenceMaterialization`)
350
+ and `evidenceDiscoveryTempDirectories`. No suite was missing, so the script
351
+ was not changed.
352
+ 4. PWA: `pwaHardening.test.ts` and `viewerPwaBuild.test.ts` still prove no
353
+ `/api/` cache entries. The packed viewer smoke repeats this on the installed
354
+ package.
355
+
356
+ ## 11. Backward compatibility
357
+
358
+ 1. All pre-existing unit and browser suites pass unchanged.
359
+ 2. The only production source change in Prompt 7 is the `view --help` text in
360
+ `src/cli.ts` (see section 19). No command, flag, route, schema, or behavior
361
+ changed.
362
+ 3. Low-level commands, the v0.8 viewer, and the v0.8.1 project workflow pass in
363
+ source-tree tests and in the packed observation and viewer smokes.
364
+
365
+ ## 12. Packed candidate identity
366
+
367
+ 1. Package: `@dailephd/my-frontend-observer` `0.8.1`.
368
+ 2. Tarball filename: `dailephd-my-frontend-observer-0.8.1.tgz`.
369
+ 3. Candidate procedure (two-pass, as required):
370
+ 1. Pass A: after all source, test, CI, and documentation changes and a full
371
+ local validation, `npm run build` then `npm pack --json` produced
372
+ candidate A. All three packed smokes ran against it.
373
+ 2. This report was then updated with the Pass A results.
374
+ 3. Pass B: `npm run check:docs`, `npm run build`, and `npm pack --json`
375
+ produced the final candidate from the final tracked content, including
376
+ this report. All three packed smokes ran again against that exact
377
+ tarball.
378
+ 4. Pass A candidate: 361 files, package size 958.9 kB, unpacked size
379
+ 3.76 MB, SHA-256 `1733002bb83e92faf11eddc8a76d41badb31e6f067356d9de64c83af8b8a1749`. This SHA identifies candidate A only.
380
+ 5. The final candidate SHA-256 is not recorded in this report, because this
381
+ report is packaged under `docs` and embedding the hash would change the
382
+ tarball it describes. The final SHA-256 is printed in the Prompt 7 terminal
383
+ summary and kept in an untracked local validation note outside the package.
384
+
385
+ ## 13. Packed package contents
386
+
387
+ The packed v0.9 smoke verified that the installed package contains non-empty:
388
+
389
+ 1. `dist/index.js` and `dist/cli.js`;
390
+ 2. `dist/domain/visualAnnotation.js` and `dist/domain/visualAnnotationIdentity.js`;
391
+ 3. `dist/artifacts/visualAnnotationArtifactReader.js` and
392
+ `dist/artifacts/visualAnnotationArtifactWriter.js`;
393
+ 4. `dist/application/visualAnnotationPersistenceService.js`,
394
+ `visualAnnotationContractPromotionService.js`, and
395
+ `visualAnnotationReferenceMaterializationService.js`;
396
+ 5. `dist/viewerServer/annotationAuthoring.js`,
397
+ `annotationContractPromotion.js`, and `annotationReferenceMaterialization.js`;
398
+ 6. `dist/viewer/index.html` and `dist/viewer/sw.js`.
399
+
400
+ It also verified that `scripts/` is not packaged. Public exports resolved from
401
+ the bare specifier `@dailephd/my-frontend-observer`:
402
+ `VISUAL_ANNOTATION_ARTIFACT_KIND`, `VISUAL_ANNOTATION_SCHEMA_VERSION` (`1.0.0`),
403
+ `isValidVisualAnnotationArtifact`, `buildVisualAnnotationRequestIdentity`,
404
+ `buildVisualAnnotationInstanceIdentity`, `readVisualAnnotationArtifact`,
405
+ `writeVisualAnnotationArtifact`, `persistVisualAnnotation`, and
406
+ `materializeVisualAnnotationReference`. `promoteVisualAnnotationContract` is not
407
+ exported by current `src/index.ts`, so it is not treated as public. It was not
408
+ added, because Prompt 7 adds no new public surface.
409
+
410
+ ## 14. Installed-consumer purity
411
+
412
+ 1. The consumer is a fresh temporary directory outside the repository with its
413
+ own `package.json`. The exact tarball is installed with `npm install`.
414
+ 2. The installed CLI is resolved from the installed `package.json` `bin` and
415
+ must be inside the consumer's `node_modules`.
416
+ 3. A probe script inside the consumer resolves `@dailephd/my-frontend-observer`
417
+ and `playwright` with `import.meta.resolve`. Both must resolve inside the
418
+ consumer's `node_modules` (compared by realpath) and never into the
419
+ repository `src/` or `dist/`.
420
+ 4. Chromium is installed through the consumer-local Playwright CLI and launched
421
+ from the consumer-local Playwright module.
422
+ 5. Result: PASS for candidate A and for the final candidate.
423
+
424
+ ## 15. Packed observation smoke
425
+
426
+ `node scripts/ci/runPackedObservationSmoke.mjs <tarball> --out <summary>`
427
+ (unchanged script). Pass A: PASS (`pass: true`, including every v0.1 to v0.7 installed assertion, `packedNoRepoRootLeak`, and source immutability). It was rerun for the final candidate.
428
+
429
+ ## 16. Packed viewer smoke
430
+
431
+ `node scripts/ci/runPackedViewerSmoke.mjs <tarball> --out <summary>` (unchanged
432
+ script). Pass A: PASS (`result: PASS`, `viewerProtocolVersion: 1.3.0`, installed `check` REVIEW_REQUIRED then FAIL then PASS, alias correctness, traversal rejected, SVG overlay and reference view rendered, service worker registered, `/api/` never cached, server-down gate held). It was rerun for the final candidate. This smoke
433
+ owns the installed project workflow (`init`/`capture`/`check` REVIEW_REQUIRED,
434
+ FAIL, and PASS) and the project-aware viewer inspection proof, including
435
+ `/api/` no-cache and the server-down stale-evidence gate.
436
+
437
+ ## 17. Packed v0.9 annotation smoke
438
+
439
+ `node scripts/ci/runPackedV09AnnotationSmoke.mjs <tarball> --out <summary>`
440
+ (new). Pass A: PASS (`result: PASS`, every summary flag true). It was rerun for the final candidate.
441
+
442
+ This smoke owns the project-aware write proof and the standalone read-only
443
+ proof for v0.9. Its summary reported `viewerProtocolVersion: 1.3.0` and true
444
+ for `packageContentsPass`, `publicExportsPass`, `consumerPurityPass`,
445
+ `projectWorkflowPass`, `authoringSessionEnabled`, `runtimeAnnotationPass`,
446
+ `runtimePromotionPass`, `contractInspectionPass`, `referenceAnnotationPass`,
447
+ `referenceMaterializationPass`, `newReferenceInspectionPass`, and
448
+ `readOnlyBoundaryPass`. The summary contains no token, no absolute project
449
+ paths, and no note text.
450
+
451
+ Local classification:
452
+
453
+ 1. `LOCAL_PACKED_SMOKE`: PASS
454
+ 2. `CROSS_PLATFORM_WORKFLOW_WIRED`: PASS
455
+ 3. `CROSS_PLATFORM_WORKFLOW_EXECUTED`: NOT_RUN
456
+
457
+ ## 18. Cross-platform workflow wiring
458
+
459
+ `.github/workflows/pre-release-readiness.yml` changes:
460
+
461
+ 1. New matrix step "Packed v0.9 annotation smoke (installed tarball only, real
462
+ Chromium)" runs
463
+ `node scripts/ci/runPackedV09AnnotationSmoke.mjs "${{ needs.candidate.outputs.tarball }}" --out v09-annotation-smoke-summary.json`
464
+ with `shell: bash`, after the two existing smokes.
465
+ 2. The smoke artifact upload now also includes
466
+ `v09-annotation-smoke-summary.json`. `smoke-summary.json` and
467
+ `viewer-smoke-summary.json` are kept.
468
+
469
+ Validated by inspection (no local YAML parser or workflow validator exists in
470
+ the repository):
471
+
472
+ 1. The `candidate` job is unchanged. It still builds one tarball with
473
+ `npm pack --json` on Linux and Node 24 and freezes its SHA-256.
474
+ 2. The matrix still downloads the same artifact and verifies the SHA before any
475
+ smoke.
476
+ 3. The matrix is still `windows-latest`, `ubuntu-latest`, and `macos-latest`
477
+ with `fail-fast: false`.
478
+ 4. The new step uses the exact candidate tarball output. Indentation matches
479
+ the sibling steps, and the file contains no tabs.
480
+
481
+ The workflow was not run. Nothing was pushed.
482
+
483
+ ## 19. Documentation reconciliation
484
+
485
+ Documentation now describes the implemented, unreleased v0.9 state
486
+ consistently: published release `0.8.1`, v0.9 implementation complete and
487
+ validated locally, not released, cross-platform readiness pending, viewer
488
+ protocol `1.3.0`, annotation schema `1.0.0`.
489
+
490
+ 1. `README.md`: v0.9 visual annotation section, release status, and the
491
+ project-aware versus `--root` entry points.
492
+ 2. `CHANGELOG.md`: v0.9 additions under `[Unreleased]`. No `0.9.0` entry.
493
+ 3. `docs/ARCHITECTURE.md`: new "v0.9 visual annotation architecture" section
494
+ with ownership, coordinate domains, discovery, authoring security, the three
495
+ POST routes, and evaluator authority. Stale "v0.9 future" constraint
496
+ wording updated.
497
+ 4. `docs/COMMANDS.md`: `view` is the annotation entry point, `view --root` is
498
+ read-only, the added routes are listed, and the stale "accepts no write
499
+ methods" sentence is corrected. No annotation command was invented.
500
+ 5. `docs/CONTRACTS.md`: new "v0.9 visual annotation contract" section, and
501
+ stale "v0.9 still future" wording updated.
502
+ 6. `docs/CURRENT_STATE.md`: v0.9 status section (implementation complete, not
503
+ released), a note that the v0.8 GET/HEAD-only surface now has three POST
504
+ routes, updated "Not implemented" and "Next target".
505
+ 7. `docs/PROJECT_MILESTONES.md`: Milestone 9 implementation status line.
506
+ 8. `docs/PROJECT_OVERVIEW.md`: published `0.8.1` versus v0.9 implementation
507
+ complete, and the progression line.
508
+ 9. `docs/QUICKSTART.md`: concise visual annotation workflow.
509
+ 10. `docs/ROADMAP.md`: status wording only. "implementation has not started"
510
+ removed. The frozen v0.9 design and v0.10 are unchanged.
511
+ 11. `docs/SECURITY.md`: new "v0.9 local annotation write boundary" section, and
512
+ the stale "Read-only API" and "no evidence mutation" bullets corrected.
513
+ 12. `docs/WORKFLOWS.md`: runtime and reference visual flows, revisions, and
514
+ missing sources. The future-workflows heading was retitled.
515
+ 13. `docs/CI_CD.md`: v0.9 packaging section with the exact-candidate matrix
516
+ and the three packed smokes. It does not claim the matrix ran.
517
+ 14. `docs/DEVELOPMENT.md`: where authoring is available and where its proofs
518
+ live.
519
+ 15. `src/cli.ts` (`view --help` text only) and `tests/unit/cliView.test.ts`:
520
+ the help text said the server exposes "one minimal read-only status
521
+ endpoint" and "never writes to the supplied evidence root" for every mode.
522
+ That was stale after v0.9. It now says `--root` is read-only and the
523
+ project-aware session enables local annotation authoring. A regression
524
+ test covers the new text.
525
+
526
+ Not modified: `docs/plans/v0.9-implementation-plan.md`, all prior batch reports,
527
+ and the local skip-worktree architecture retrieval report.
528
+
529
+ ## 20. Version/release-state audit
530
+
531
+ 1. `package.json` version `0.8.1`. `package-lock.json` version and
532
+ `packages[""].version` `0.8.1`.
533
+ 2. No document says v0.9 is released or published, or that `0.9.0` is
534
+ available. `0.9.0` appears only as the future release to prepare.
535
+ 3. Viewer protocol `1.3.0`, visual annotation schema `1.0.0`, frontend contract
536
+ schema `1.0.0`, external-reference schema `1.0.0`. None changed in Prompt 7.
537
+ 4. No push, tag, publish, `npm version`, GitHub release, or release branch.
538
+
539
+ ## 21. Full regression validation
540
+
541
+ Pass A, run on Windows from the repository root after all tracked changes
542
+ except this report:
543
+
544
+ 1. `npm run typecheck`: PASS
545
+ 2. `npm run lint`: PASS. The first run found two `no-undef` errors for
546
+ `document` inside Playwright page closures in the new smoke script. They
547
+ were fixed with `globalThis.document`, and the rerun passed.
548
+ 3. `npm test`: PASS (84 files, 1379 tests)
549
+ 4. `npm run test:browser`: PASS (26 files, 235 tests, real Chromium)
550
+ 5. `npm run test:security`: PASS (unit: 16 files, 167 tests. Browser: 3 files,
551
+ 77 tests)
552
+ 6. `npm run build`: PASS
553
+ 7. `npm run check:docs`: PASS (17 required files)
554
+ 8. `npm pack --dry-run`: PASS
555
+
556
+ Focused runs before that: `tests/browser/v09IntegratedAcceptance.test.ts`
557
+ PASS (4 tests), `tests/unit/cliView.test.ts` PASS (21 tests), and all three
558
+ packed smokes PASS against a development tarball.
559
+
560
+ Pass B, for the final candidate: `npm run check:docs`, `npm run build`, and
561
+ `npm pack --json` were rerun, and all three packed smokes ran again. Pass B
562
+ results are reported in the terminal summary and the untracked validation note.
563
+
564
+ ## 22. Scope audit
565
+
566
+ 1. New v0.9 product feature added: false
567
+ 2. v0.10 behavior implemented: false. The diff adds no source editing,
568
+ coding-agent invocation, HTML or CSS generation, automatic approval,
569
+ automatic baseline replacement, or new PASS/FAIL semantics.
570
+ 3. Annotation schema changed: false
571
+ 4. Frontend contract schema changed: false
572
+ 5. External-reference schema changed: false
573
+ 6. Viewer protocol changed: false
574
+ 7. Runtime or reference promotion semantics changed: false
575
+ 8. Security model changed: false
576
+ 9. Package version changed: false
577
+ 10. Dependency changed: false
578
+ 11. Frozen implementation plan changed: false
579
+ 12. Prior batch reports changed: false
580
+
581
+ ## 23. Changed files
582
+
583
+ ### 23.1 Added
584
+
585
+ 1. `tests/browser/v09IntegratedAcceptance.test.ts`
586
+ 2. `scripts/ci/runPackedV09AnnotationSmoke.mjs`
587
+ 3. `docs/reports/v0.9-batch7-integrated-acceptance.md`
588
+
589
+ ### 23.2 Modified
590
+
591
+ 1. `.github/workflows/pre-release-readiness.yml`
592
+ 2. `src/cli.ts` (`view --help` text only)
593
+ 3. `tests/unit/cliView.test.ts`
594
+ 4. `README.md`
595
+ 5. `CHANGELOG.md`
596
+ 6. `docs/ARCHITECTURE.md`
597
+ 7. `docs/CI_CD.md`
598
+ 8. `docs/COMMANDS.md`
599
+ 9. `docs/CONTRACTS.md`
600
+ 10. `docs/CURRENT_STATE.md`
601
+ 11. `docs/DEVELOPMENT.md`
602
+ 12. `docs/PROJECT_MILESTONES.md`
603
+ 13. `docs/PROJECT_OVERVIEW.md`
604
+ 14. `docs/QUICKSTART.md`
605
+ 15. `docs/ROADMAP.md`
606
+ 16. `docs/SECURITY.md`
607
+ 17. `docs/WORKFLOWS.md`
608
+
609
+ ### 23.3 Generated paths
610
+
611
+ 1. Packed consumers and projects were created under the OS temporary directory
612
+ by the three smoke scripts and removed by them.
613
+ 2. Test temporary directories were removed by the test resource helpers.
614
+ 3. Tarballs were written to the repository root (ignored by `*.tgz`) and
615
+ deleted after use.
616
+ 4. Validation logs, smoke summaries, and the untracked validation note were
617
+ written under the ignored repository-local workflow root
618
+ `.my-dev-kit-workflow/adhoc/v09-batch7/`.
619
+ 5. `npm run build` refreshed the ignored `dist/`.
620
+
621
+ ## 24. Remaining risks
622
+
623
+ 1. The cross-platform matrix has not run for this candidate. Linux and macOS
624
+ behavior of the new smoke (for example Playwright `--with-deps` and path
625
+ realpath handling) is untested until the readiness workflow runs.
626
+ 2. The workflow YAML was validated by inspection only.
627
+ 3. PWA installation proof remains limited to the v0.8 level (no OS-level
628
+ install).
629
+ 4. `promoteVisualAnnotationContract` is not a public export. This matches the
630
+ current design but may need a decision before release.
631
+
632
+ ## 25. Final implementation state
633
+
634
+ 1. v0.8.1: latest published release.
635
+ 2. v0.9: implementation complete, integrated locally, packed candidate
636
+ validated locally on Windows, cross-platform pre-release workflow prepared,
637
+ not released.
638
+
639
+ ## 26. Next step
640
+
641
+ v0.9 pre-release readiness and controlled release preparation: push the
642
+ implementation-complete candidate, run the exact-candidate Windows/Linux/macOS
643
+ Pre-release readiness workflow, reconcile any cross-platform failures, then
644
+ prepare the v0.9.0 release separately.