@dailephd/my-frontend-observer 0.8.1 → 0.9.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 (111) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +109 -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 +78 -1
  79. package/docs/COMMANDS.md +44 -4
  80. package/docs/CONTRACTS.md +78 -8
  81. package/docs/CURRENT_STATE.md +224 -35
  82. package/docs/DEVELOPMENT.md +38 -3
  83. package/docs/PROJECT_DESCRIPTION.md +4 -1
  84. package/docs/PROJECT_MILESTONES.md +32 -0
  85. package/docs/PROJECT_OVERVIEW.md +58 -17
  86. package/docs/QUICKSTART.md +52 -39
  87. package/docs/RELEASE.md +17 -11
  88. package/docs/ROADMAP.md +458 -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/plans/v0.9.1-implementation-plan.md +468 -0
  93. package/docs/reports/v0.9-architecture-retrieval.md +567 -0
  94. package/docs/reports/v0.9-batch1-visual-annotation-foundation.md +351 -0
  95. package/docs/reports/v0.9-batch2-viewer-annotation-authoring-boundary.md +438 -0
  96. package/docs/reports/v0.9-batch3-runtime-screenshot-annotation-authoring.md +412 -0
  97. package/docs/reports/v0.9-batch4-external-reference-annotation-authoring.md +452 -0
  98. package/docs/reports/v0.9-batch5-runtime-intent-contract-promotion.md +535 -0
  99. package/docs/reports/v0.9-batch6-reference-materialization.md +514 -0
  100. package/docs/reports/v0.9-batch7-integrated-acceptance.md +644 -0
  101. package/docs/reports/v0.9-demo-foundation.md +589 -0
  102. package/docs/reports/v0.9-final-pre-release-readiness.md +209 -0
  103. package/docs/reports/v0.9-final-readiness-corrections.md +530 -0
  104. package/docs/reports/v0.9-pre-release-readiness.md +170 -0
  105. package/docs/reports/v0.9-tutorial-end-to-end-acceptance.md +980 -0
  106. package/docs/reports/v0.9-tutorial-integration.md +731 -0
  107. package/docs/reports/v0.9.1-batch1-pwa-hard-gate-isolation.md +359 -0
  108. package/docs/reports/v0.9.1-batch2-hard-gate-validation-integration.md +262 -0
  109. package/docs/reports/v0.9.1-pre-release-readiness.md +206 -0
  110. package/package.json +3 -2
  111. package/dist/viewer/assets/index-D98S1_2d.js +0 -9
@@ -0,0 +1,1529 @@
1
+ # v0.9 Implementation Plan — Human Visual Annotation and Design-Intent Capture
2
+
3
+ ## 1. Status and authority
4
+
5
+ This document is the frozen concrete implementation plan for
6
+ `my-frontend-observer` v0.9.
7
+
8
+ It was created during v0.9 version-start planning after reviewing the current
9
+ v0.8.1 documentation, `docs/ROADMAP.md`, `docs/PROJECT_MILESTONES.md`, the
10
+ frozen v0.8 and v0.8.1 plans, and the current v0.8.1 source architecture.
11
+ The source inspection is preserved in
12
+ `docs/reports/v0.9-architecture-retrieval.md`.
13
+
14
+ The architecture retrieval inspected source commit
15
+ `473713d240af09e752eeb8e00735738c4927b16d`. Current `master` later advanced
16
+ to `f57737585734ca72f173986b7ba0dd35c5734cea`; the intervening commit changed
17
+ documentation only, so no production source, viewer source, test, package, or
18
+ artifact-schema ownership used by this plan changed.
19
+
20
+ This document governs v0.9 implementation scope, architecture, public and
21
+ internal contracts, batch order, and validation expectations unless the user
22
+ explicitly revises it.
23
+
24
+ This is planning authority only. It does not prove that any v0.9 batch has been
25
+ implemented. Actual implementation and release state remains owned by repository
26
+ evidence and `docs/CURRENT_STATE.md`.
27
+
28
+ The package remains `0.8.1` until a separate release-preparation workflow
29
+ explicitly changes it after implementation and pre-release validation.
30
+
31
+ ## 2. Version objective
32
+
33
+ Add structured visual human intent to the existing Observer system through the
34
+ local viewer.
35
+
36
+ A user must be able to annotate either:
37
+
38
+ 1. an existing runtime observation screenshot, or
39
+ 2. an existing external visual reference.
40
+
41
+ Those annotations must survive save/reload while preserving the exact canonical
42
+ source identity and source coordinate system.
43
+
44
+ The annotation workflow must support explicit interpretation and confirmation
45
+ before visual marks become strong design requirements.
46
+
47
+ Confirmed annotation intent must feed the existing canonical contract and
48
+ external-reference systems rather than introduce a second change-semantics,
49
+ reference, or PASS/FAIL system.
50
+
51
+ v0.9 does not edit application source, generate code from images, or complete
52
+ the full coding-agent correction loop planned for v0.10.
53
+
54
+ ## 3. Frozen version-start decisions
55
+
56
+ ### 3.1 New persisted annotation evidence family
57
+
58
+ v0.9 introduces one new persisted artifact family:
59
+
60
+ ```text
61
+ VisualAnnotationArtifact
62
+ artifactKind: my-frontend-observer/visual-annotation
63
+ schemaVersion: 1.0.0
64
+ ```
65
+
66
+ Annotations must not be added as mutable fields to `ObservationArtifact`,
67
+ `ExternalReferenceArtifact`, `ComparisonArtifact`, frontend contracts, or
68
+ contract evaluation artifacts.
69
+
70
+ Observations and external references remain immutable evidence. Every explicit
71
+ annotation save creates a new immutable annotation artifact instance.
72
+
73
+ ### 3.2 Source contexts remain separate
74
+
75
+ A visual annotation has exactly one source context:
76
+
77
+ ```text
78
+ runtime-observation
79
+ ```
80
+
81
+ or:
82
+
83
+ ```text
84
+ external-reference
85
+ ```
86
+
87
+ Runtime observation coordinates are viewport CSS pixels.
88
+ External-reference coordinates are reference-image pixels.
89
+
90
+ The two coordinate and identity domains must never be collapsed.
91
+ A reference-region ID must never be treated as a runtime-target name.
92
+ A mutable project alias such as `baseline` or `current` must never become
93
+ persisted annotation provenance.
94
+
95
+ ### 3.3 First persisted drawing set
96
+
97
+ The v0.9 persisted mark vocabulary is exactly:
98
+
99
+ ```text
100
+ point
101
+ rectangle
102
+ line
103
+ arrow
104
+ note
105
+ ```
106
+
107
+ `select` and `pan` are interaction modes, not persisted annotation evidence.
108
+
109
+ Do not add freehand drawing, polygons, Bezier paths, paint strokes, masks, OCR,
110
+ computer-vision segmentation, or arbitrary SVG markup in v0.9.
111
+
112
+ ### 3.4 First human intent set
113
+
114
+ The first human-facing intent operations are:
115
+
116
+ ```text
117
+ inspect
118
+ move
119
+ resize
120
+ remove
121
+ preserve
122
+ ```
123
+
124
+ External-reference annotation additionally supports:
125
+
126
+ ```text
127
+ reference-region
128
+ reference-requirement
129
+ asset-sensitive
130
+ ```
131
+
132
+ These labels describe human intent. They do not create a second evaluator.
133
+
134
+ Where an operation can be represented through the current canonical contract or
135
+ reference vocabulary, a confirmed interpretation stores that canonical
136
+ proposal. Where the current vocabulary cannot express the operation, the
137
+ annotation may still preserve the confirmed human intent, but promotion must
138
+ remain visibly unsupported.
139
+
140
+ v0.9 must not add a new frontend-contract primitive solely to make every drawing
141
+ evaluable.
142
+
143
+ ### 3.5 Current canonical contract vocabulary remains authoritative
144
+
145
+ Runtime annotation may promote only into the current `ContractPrimitive`
146
+ vocabulary.
147
+
148
+ Relevant current primitives include:
149
+
150
+ ```text
151
+ property-increases
152
+ property-decreases
153
+ property-unchanged-within-tolerance
154
+ relationship-unchanged
155
+ target-width-within-bound
156
+ target-visible
157
+ target-not-clipped
158
+ targets-do-not-overlap
159
+ target-wider-than
160
+ target-follows-vertically
161
+ target-fits-inside
162
+ ```
163
+
164
+ The current runtime geometry properties available for increase/decrease or
165
+ preservation are:
166
+
167
+ ```text
168
+ x
169
+ y
170
+ width
171
+ height
172
+ ```
173
+
174
+ Examples:
175
+
176
+ ```text
177
+ move right
178
+ → property-increases(target, x)
179
+
180
+ move up
181
+ → property-decreases(target, y)
182
+
183
+ resize wider
184
+ → property-increases(target, width)
185
+
186
+ preserve height
187
+ → property-unchanged-within-tolerance(target, height, tolerance)
188
+
189
+ preserve an existing relationship
190
+ → relationship-unchanged(...)
191
+ ```
192
+
193
+ A `remove` annotation is representable human intent in v0.9, but the current
194
+ contract vocabulary has no `target-absent` primitive. Therefore:
195
+
196
+ ```text
197
+ remove
198
+ → may be saved
199
+ → may be explicitly confirmed
200
+ → must report "not promotable by current canonical contract vocabulary"
201
+ → must not fabricate an equivalent contract clause
202
+ ```
203
+
204
+ ### 3.6 Existing authored categories remain authoritative
205
+
206
+ When annotation is promoted to design intent, reuse exactly:
207
+
208
+ ```text
209
+ requested
210
+ expected-dependent
211
+ protected
212
+ preserved
213
+ ```
214
+
215
+ `unexpected` remains evaluator output and cannot be authored through annotation.
216
+ For `expected-dependent`, the existing `required` / `permitted` mode remains
217
+ mandatory.
218
+
219
+ No annotation-specific requested/protected/preserved vocabulary may be created.
220
+
221
+ ### 3.7 External-reference requirements reuse the current reference model
222
+
223
+ Confirmed external-reference design requirements must use the existing
224
+ `RawReferenceRequirement` and `ReferenceRequirementSubject` models.
225
+
226
+ Current subject kinds remain:
227
+
228
+ ```text
229
+ region-property
230
+ region-relationship
231
+ region-measurement
232
+ ```
233
+
234
+ Current reference coordinates remain reference-image pixels. Current reference
235
+ tolerances remain:
236
+
237
+ ```text
238
+ exact
239
+ absolute-reference-px
240
+ percent
241
+ ```
242
+
243
+ They must never be silently reinterpreted as CSS pixels.
244
+
245
+ ### 3.8 Save is explicit and immutable
246
+
247
+ v0.9 does not autosave canonical annotation evidence.
248
+
249
+ The editing workflow is:
250
+
251
+ ```text
252
+ load source
253
+ → edit in-memory draft
254
+ → explicit Save
255
+ → new immutable VisualAnnotationArtifact
256
+ ```
257
+
258
+ Editing a previously saved annotation creates another artifact:
259
+
260
+ ```text
261
+ old annotation artifact
262
+ → explicit revision
263
+ → new annotation artifact with supersedesAnnotationId
264
+ ```
265
+
266
+ The previous artifact remains unchanged.
267
+
268
+ ### 3.9 Confirmation is explicit
269
+
270
+ A drawing is not automatically a requirement.
271
+
272
+ Each annotation item carries one of:
273
+
274
+ ```text
275
+ uninterpreted
276
+ candidate
277
+ confirmed
278
+ ```
279
+
280
+ Only `confirmed` interpretations may be selected for canonical promotion.
281
+ Geometry may be used to present a candidate interpretation, but a suggestion
282
+ does not become confirmed intent automatically.
283
+
284
+ Freeform overlap with a target or region does not create a binding.
285
+
286
+ ### 3.10 Authoring entry point
287
+
288
+ Normal v0.9 authoring uses the existing project-aware viewer:
289
+
290
+ ```text
291
+ my-frontend-observer view
292
+ ```
293
+
294
+ The advanced form remains supported:
295
+
296
+ ```text
297
+ my-frontend-observer view --root <evidence-root>
298
+ ```
299
+
300
+ but arbitrary-root viewer use remains read-only unless it is operating through
301
+ the normal initialized-project context.
302
+
303
+ Do not add a new top-level `annotate` workflow command.
304
+
305
+ ### 3.11 Narrow viewer write boundary
306
+
307
+ v0.8 is GET/HEAD-only. v0.9 introduces POST only for the bounded
308
+ annotation-authoring operations defined by this plan.
309
+
310
+ Do not add PUT, PATCH, DELETE, arbitrary filesystem write, source-file write, or
311
+ artifact replacement endpoints.
312
+
313
+ Existing evidence remains immutable.
314
+
315
+ ### 3.12 Annotated-image derivation
316
+
317
+ The structured manifest is the annotation authority.
318
+
319
+ Each saved annotation artifact also owns one deterministic derived overlay:
320
+
321
+ ```text
322
+ annotation-overlay.svg
323
+ ```
324
+
325
+ The overlay:
326
+
327
+ - uses the same source-native coordinate frame recorded by the artifact;
328
+ - contains only system-generated SVG from validated annotation marks;
329
+ - does not contain arbitrary user SVG or HTML;
330
+ - does not copy the source screenshot/reference image;
331
+ - is not an independent interpretation or evidence engine.
332
+
333
+ The manifest stores its relative reference and SHA-256 digest.
334
+
335
+ The viewer reconstructs annotated imagery as:
336
+
337
+ ```text
338
+ canonical source image
339
+ +
340
+ annotation-overlay.svg
341
+ ```
342
+
343
+ The structured annotation data remains authoritative if the overlay disagrees.
344
+
345
+ ## 4. Frozen domain contract
346
+
347
+ Exact helper names may follow repository conventions, but the ownership and
348
+ semantics below are frozen.
349
+
350
+ ### 4.1 Constants
351
+
352
+ ```ts
353
+ export const VISUAL_ANNOTATION_ARTIFACT_KIND =
354
+ 'my-frontend-observer/visual-annotation' as const;
355
+
356
+ export const VISUAL_ANNOTATION_SCHEMA_VERSION = '1.0.0' as const;
357
+
358
+ export const MAX_VISUAL_ANNOTATION_ITEMS = 100;
359
+ export const MAX_VISUAL_ANNOTATION_NOTE_LENGTH = 2000;
360
+ ```
361
+
362
+ ### 4.2 Source identity
363
+
364
+ Conceptual source contract:
365
+
366
+ ```ts
367
+ type VisualAnnotationSource =
368
+ | {
369
+ kind: 'runtime-observation';
370
+ observationId: string;
371
+ requestId: string;
372
+ observationSchemaVersion: string;
373
+ screenshot: { path: string };
374
+ coordinateSpace: {
375
+ kind: 'runtime-css-px';
376
+ width: number;
377
+ height: number;
378
+ };
379
+ }
380
+ | {
381
+ kind: 'external-reference';
382
+ referenceId: string;
383
+ referenceRequestId: string;
384
+ referenceSchemaVersion: string;
385
+ lifecycle: 'imported' | 'approved';
386
+ imageOwnerReferenceId: string;
387
+ imageSha256: string;
388
+ coordinateSpace: {
389
+ kind: 'reference-image-px';
390
+ width: number;
391
+ height: number;
392
+ };
393
+ };
394
+ ```
395
+
396
+ Reuse existing canonical source-reference types where that preserves exactly the
397
+ same semantics.
398
+
399
+ Do not persist mutable aliases, absolute artifact paths, browser evidence
400
+ handles, viewer URLs, or viewer ports as source identity.
401
+
402
+ ### 4.3 Mark geometry
403
+
404
+ ```ts
405
+ type VisualAnnotationMark =
406
+ | { kind: 'point'; x: number; y: number }
407
+ | { kind: 'rectangle'; x: number; y: number; width: number; height: number }
408
+ | {
409
+ kind: 'line';
410
+ start: { x: number; y: number };
411
+ end: { x: number; y: number };
412
+ }
413
+ | {
414
+ kind: 'arrow';
415
+ start: { x: number; y: number };
416
+ end: { x: number; y: number };
417
+ }
418
+ | {
419
+ kind: 'note';
420
+ anchor: { x: number; y: number };
421
+ text: string;
422
+ };
423
+ ```
424
+
425
+ Coordinates must be finite. Rectangle width and height must be positive.
426
+ Saved annotation geometry must lie within its source frame because v0.9
427
+ annotation describes visible source-image evidence.
428
+
429
+ This rule does not change existing runtime target evidence, which may
430
+ legitimately extend outside the captured viewport.
431
+
432
+ ### 4.4 Explicit source-domain associations
433
+
434
+ Runtime associations:
435
+
436
+ ```ts
437
+ type RuntimeAnnotationAssociation =
438
+ | { kind: 'runtime-target'; target: string }
439
+ | {
440
+ kind: 'runtime-relationship';
441
+ relationshipKind: PairwiseRelationshipKind | PageLevelRelationshipKind;
442
+ subjectTarget?: string;
443
+ relatedTarget?: string;
444
+ };
445
+ ```
446
+
447
+ Reference associations:
448
+
449
+ ```ts
450
+ type ReferenceAnnotationAssociation =
451
+ | { kind: 'reference-region'; regionId: string }
452
+ | {
453
+ kind: 'reference-relationship';
454
+ subjectRegion: string;
455
+ relatedRegion: string;
456
+ relationship: PairwiseRelationshipKind;
457
+ };
458
+ ```
459
+
460
+ Associations come from explicit user selection of known structured evidence.
461
+
462
+ Do not infer association from name similarity, rectangle overlap, nearest
463
+ element, visual proximity, or drawing containment.
464
+
465
+ A free drawing without explicit structured association remains unbound.
466
+
467
+ ### 4.5 Interpretation state
468
+
469
+ ```ts
470
+ type VisualAnnotationInterpretation =
471
+ | { state: 'uninterpreted' }
472
+ | { state: 'candidate'; intent: VisualAnnotationIntent }
473
+ | {
474
+ state: 'confirmed';
475
+ intent: VisualAnnotationIntent;
476
+ confirmedAt: string;
477
+ };
478
+ ```
479
+
480
+ ### 4.6 Intent
481
+
482
+ Conceptually:
483
+
484
+ ```ts
485
+ type VisualAnnotationIntent =
486
+ | { kind: 'inspect' }
487
+ | {
488
+ kind: 'change';
489
+ operation: 'move' | 'resize' | 'remove' | 'preserve';
490
+ category: AuthoredChangeScopeCategory;
491
+ expectedDependentMode?: ExpectedDependentMode;
492
+ contractPrimitive?: ContractPrimitive;
493
+ }
494
+ | {
495
+ kind: 'reference-region';
496
+ mode: 'create' | 'refine';
497
+ region: ReferenceRegion;
498
+ }
499
+ | {
500
+ kind: 'reference-requirement';
501
+ requirement: RawReferenceRequirement;
502
+ }
503
+ | {
504
+ kind: 'asset-sensitive';
505
+ regionId?: string;
506
+ };
507
+ ```
508
+
509
+ Rules:
510
+
511
+ - `inspect` is informational and never becomes a contract clause.
512
+ - `asset-sensitive` is informational metadata in v0.9 and never becomes a
513
+ hidden acceptance criterion.
514
+ - confirmed `move`, `resize`, or `preserve` requires an existing valid
515
+ `ContractPrimitive` before contract promotion.
516
+ - confirmed `remove` must not fabricate a contract primitive.
517
+ - `reference-region`, `reference-requirement`, and `asset-sensitive` are valid
518
+ only for external-reference source context.
519
+ - runtime contract proposals are valid only for runtime-observation source
520
+ context.
521
+ - every contract primitive, authored category, expected-dependent mode,
522
+ `ReferenceRegion`, and `RawReferenceRequirement` must be validated through
523
+ its existing canonical validator.
524
+
525
+ ### 4.7 Annotation item
526
+
527
+ ```ts
528
+ interface VisualAnnotationItem {
529
+ annotationItemId: string;
530
+ mark: VisualAnnotationMark;
531
+ association?: RuntimeAnnotationAssociation | ReferenceAnnotationAssociation;
532
+ interpretation: VisualAnnotationInterpretation;
533
+ }
534
+ ```
535
+
536
+ `annotationItemId` is generated by Observer when an item is first created and
537
+ remains stable when that logical item is carried into a later annotation
538
+ revision. It is not derived from geometry.
539
+
540
+ ### 4.8 Artifact
541
+
542
+ Conceptually:
543
+
544
+ ```ts
545
+ interface VisualAnnotationArtifact {
546
+ artifactKind: typeof VISUAL_ANNOTATION_ARTIFACT_KIND;
547
+ schemaVersion: typeof VISUAL_ANNOTATION_SCHEMA_VERSION;
548
+
549
+ annotationRequestId: string;
550
+ annotationId: string;
551
+ supersedesAnnotationId?: string;
552
+
553
+ producer: {
554
+ name: string;
555
+ version: string;
556
+ };
557
+
558
+ source: VisualAnnotationSource;
559
+ items: VisualAnnotationItem[];
560
+
561
+ overlay: {
562
+ path: 'annotation-overlay.svg';
563
+ format: 'svg';
564
+ width: number;
565
+ height: number;
566
+ sha256: string;
567
+ };
568
+
569
+ provenance: {
570
+ createdAt: string;
571
+ origin: 'viewer';
572
+ };
573
+ }
574
+ ```
575
+
576
+ ## 5. Identity and revision rules
577
+
578
+ ### 5.1 Request identity
579
+
580
+ `annotationRequestId` is deterministic and includes canonical semantic content:
581
+
582
+ ```text
583
+ source canonical identity
584
+ source coordinate domain and dimensions
585
+ items
586
+ associations
587
+ interpretations
588
+ supersedesAnnotationId when present
589
+ ```
590
+
591
+ It excludes:
592
+
593
+ ```text
594
+ createdAt
595
+ output directory
596
+ project root
597
+ mutable alias
598
+ viewer port
599
+ HTTP evidence handle
600
+ temporary path
601
+ ```
602
+
603
+ ### 5.2 Instance identity
604
+
605
+ `annotationId` is fresh for every persisted instance.
606
+
607
+ Saving identical semantic annotation content twice may produce the same
608
+ `annotationRequestId` but different `annotationId` values.
609
+
610
+ ### 5.3 Revision lineage
611
+
612
+ A revision contains `supersedesAnnotationId` pointing from the new artifact to
613
+ the previous artifact. The previous artifact is never changed.
614
+
615
+ ### 5.4 Revision conflicts
616
+
617
+ The authoring API must reject stale revision attempts rather than silently
618
+ overwrite newer work.
619
+
620
+ Saving a revision sends the canonical parent annotation ID. If that parent
621
+ already has a later accepted child in the same active lineage, return an
622
+ explicit conflict response.
623
+
624
+ Do not choose a winner by timestamp. If malformed historical evidence has
625
+ multiple heads, expose the branch conflict and require explicit user choice.
626
+
627
+ ## 6. Persistence architecture
628
+
629
+ Add the established repository pattern:
630
+
631
+ ```text
632
+ src/domain/visualAnnotation.ts
633
+ src/domain/visualAnnotationIdentity.ts
634
+ src/artifacts/visualAnnotationArtifactWriter.ts
635
+ src/artifacts/visualAnnotationArtifactReader.ts
636
+ src/application/visualAnnotationPersistenceService.ts
637
+ ```
638
+
639
+ The writer must:
640
+
641
+ 1. validate the domain artifact;
642
+ 2. derive the final immutable directory from `annotationId`;
643
+ 3. refuse an existing final directory;
644
+ 4. write through a sibling temporary directory;
645
+ 5. deterministically generate `annotation-overlay.svg`;
646
+ 6. compute/store its SHA-256;
647
+ 7. write `manifest.json`;
648
+ 8. atomically rename the temporary directory;
649
+ 9. remove temporary output on failure.
650
+
651
+ The reader must parse the manifest, use the one canonical annotation validator,
652
+ reject unsupported schema versions, verify required owned overlay media, and
653
+ fail closed on unsafe media references.
654
+
655
+ The annotation writer must not read or modify the source observation/reference.
656
+
657
+ ## 7. Managed project layout
658
+
659
+ Extend project-managed evidence with:
660
+
661
+ ```text
662
+ .frontend-observer/
663
+ catalog.json
664
+ evidence/
665
+ observations/
666
+ annotations/
667
+ contracts/
668
+ references/
669
+ ```
670
+
671
+ Existing evidence paths remain valid. Do not migrate or relocate historical
672
+ evidence simply to create these directories.
673
+
674
+ New annotation artifacts use:
675
+
676
+ ```text
677
+ .frontend-observer/evidence/annotations/<annotationId>/
678
+ ```
679
+
680
+ New annotation-promoted change contracts use:
681
+
682
+ ```text
683
+ .frontend-observer/evidence/contracts/<contractId>/
684
+ ```
685
+
686
+ New annotation-authored external-reference revisions use:
687
+
688
+ ```text
689
+ .frontend-observer/evidence/references/<referenceId>/
690
+ ```
691
+
692
+ All paths remain project-relative and portable.
693
+ No annotation alias catalog is introduced in v0.9.
694
+
695
+ ## 8. Viewer discovery and read model
696
+
697
+ Extend current evidence discovery/classification explicitly for
698
+ `my-frontend-observer/visual-annotation`.
699
+
700
+ Add the canonical reader branch and metadata projection.
701
+
702
+ Bounded annotation metadata may include:
703
+
704
+ ```text
705
+ annotationId
706
+ annotationRequestId
707
+ source kind
708
+ source canonical ID
709
+ supersedesAnnotationId
710
+ item count
711
+ confirmation summary
712
+ ```
713
+
714
+ Full annotation items remain on-demand.
715
+
716
+ Add an annotation view projection that resolves:
717
+
718
+ ```text
719
+ annotation artifact
720
+ → canonical source evidence
721
+ → source media
722
+ → existing structured target/relationship/region evidence
723
+ ```
724
+
725
+ The viewer server may project these values. It must not reinterpret confirmed
726
+ intent or implement a second annotation semantic engine.
727
+
728
+ ## 9. Viewer authoring security boundary
729
+
730
+ Authoring changes the v0.8 read-only boundary, so v0.9 adds a deliberately small
731
+ write surface.
732
+
733
+ ### 9.1 Authoring capability
734
+
735
+ `startViewer` exposes annotation authoring only when started from a valid
736
+ initialized project with a known project root and managed evidence root.
737
+ Standalone arbitrary-root viewing remains read-only.
738
+
739
+ ### 9.2 Session capability token
740
+
741
+ At viewer startup, generate one cryptographically random in-memory authoring
742
+ token.
743
+
744
+ The token:
745
+
746
+ - is not persisted;
747
+ - is not stored in a cookie;
748
+ - is not embedded in service-worker cache;
749
+ - expires when the viewer server exits.
750
+
751
+ The live viewer obtains it only through the current local server boundary.
752
+ Every authoring POST requires it in a dedicated header.
753
+
754
+ ### 9.3 Same-origin enforcement
755
+
756
+ Every authoring POST additionally requires:
757
+
758
+ - exact expected loopback `Origin`;
759
+ - expected `Host`;
760
+ - JSON content type;
761
+ - bounded request body size;
762
+ - valid session token.
763
+
764
+ Do not enable permissive CORS.
765
+
766
+ ### 9.4 Method surface
767
+
768
+ Existing GET/HEAD routes remain unchanged.
769
+ POST is accepted only for explicit authoring endpoints.
770
+ PUT, PATCH, and DELETE remain unsupported.
771
+
772
+ ## 10. Authoring API
773
+
774
+ Use a small responsibility-based API surface, conceptually:
775
+
776
+ ```text
777
+ POST /api/annotations
778
+ POST /api/annotations/:handle/promote-contract
779
+ POST /api/annotations/:handle/materialize-reference
780
+ ```
781
+
782
+ Exact route names may follow current viewer-server conventions, but do not
783
+ expand the public surface beyond these responsibilities.
784
+
785
+ ### 10.1 Save annotation
786
+
787
+ The request supplies a source evidence handle, optional parent annotation
788
+ handle, and bounded annotation items.
789
+
790
+ The server resolves handles to canonical artifacts. The client never supplies
791
+ an arbitrary filesystem path.
792
+
793
+ The application service constructs canonical source references and identities
794
+ and persists one immutable artifact.
795
+
796
+ ### 10.2 Promote runtime intent
797
+
798
+ Contract promotion takes one saved annotation artifact and explicit selected
799
+ confirmed annotation item IDs.
800
+
801
+ Reject:
802
+
803
+ ```text
804
+ unconfirmed item
805
+ unsupported item
806
+ wrong source context
807
+ invalid existing primitive
808
+ missing configured baseline requirements
809
+ ```
810
+
811
+ Build one normal `PerChangeContract` using existing authored categories,
812
+ expected-dependent modes, `ContractPrimitive`, contract identity, and contract
813
+ persistence owners.
814
+
815
+ Supporting evidence should point back to the relevant persisted annotation
816
+ item/source evidence through the existing `EvidenceReference` mechanism.
817
+
818
+ The annotation system must not evaluate the contract itself.
819
+
820
+ ### 10.3 Activate promoted contract for project check
821
+
822
+ When project configuration already contains the required contract acceptance
823
+ configuration and baseline artifact, explicit promotion may atomically update
824
+ only:
825
+
826
+ ```text
827
+ acceptance.contract.changeArtifact
828
+ ```
829
+
830
+ to the newly persisted project-relative change-contract path.
831
+
832
+ Do not change the configured baseline. Do not add a baseline automatically. Do
833
+ not silently enable contract acceptance when the project did not configure one.
834
+
835
+ If required project configuration is absent, persist the change contract but
836
+ report that it is not active for `check` until project acceptance configuration
837
+ is explicitly supplied.
838
+
839
+ ### 10.4 Materialize external-reference intent
840
+
841
+ External-reference promotion takes one saved external-reference annotation
842
+ artifact and selected confirmed `reference-region` and/or
843
+ `reference-requirement` items.
844
+
845
+ Read the canonical source external reference and its canonical image bytes.
846
+ Construct a new imported `ExternalReferenceArtifact` using the existing
847
+ external-reference import/persistence service.
848
+
849
+ The new revision:
850
+
851
+ - reuses the original image content;
852
+ - carries forward unchanged regions/requirements/applicability unless explicitly
853
+ replaced through confirmed annotation intent;
854
+ - adds confirmed regions;
855
+ - replaces an existing region only when the user explicitly confirmed
856
+ `mode: refine` for that region ID;
857
+ - adds selected requirements through existing `RawReferenceRequirement`
858
+ construction;
859
+ - sets `supersedesReferenceId` to the selected source reference;
860
+ - receives new canonical reference request/instance identities.
861
+
862
+ It does not mutate the old reference, automatically approve the new reference,
863
+ or update configured approved-reference acceptance.
864
+
865
+ The UI must expose the existing explicit approval workflow as the next step.
866
+
867
+ ## 11. Reference-region authoring rules
868
+
869
+ ### Create
870
+
871
+ A rectangle becomes a reference region only through explicit interpretation.
872
+ The user supplies or accepts a valid region ID. Because the rectangle is already
873
+ in reference-image pixels, no coordinate conversion occurs.
874
+
875
+ ### Refine
876
+
877
+ The user explicitly selects an existing region. The new reference revision
878
+ retains the same region ID and replaces that region's rectangle with the
879
+ confirmed rectangle. Only the new external-reference artifact contains the
880
+ revised geometry.
881
+
882
+ ### Relationship requirements
883
+
884
+ Relationships remain derived by the existing canonical
885
+ `deriveReferenceRegionRelationships` function.
886
+
887
+ The annotation UI may let the user select one supported derived relationship
888
+ and turn it into a candidate `RawReferenceRequirement`. The annotation layer
889
+ must not create a second relationship engine.
890
+
891
+ ## 12. Rendering and coordinate rules
892
+
893
+ ### 12.1 Runtime observations
894
+
895
+ Annotations render inside the same runtime screenshot SVG coordinate frame
896
+ already used by `TargetOverlaySvg`.
897
+
898
+ Do not create another runtime coordinate transform.
899
+ Runtime annotations remain viewport CSS pixels with no device-pixel-ratio
900
+ multiplication.
901
+
902
+ ### 12.2 External references
903
+
904
+ Annotations render inside the same reference-image SVG coordinate frame already
905
+ used by `ReferenceRegionOverlaySvg`.
906
+
907
+ Reference annotations remain reference-image pixels.
908
+
909
+ ### 12.3 Shared annotation layer
910
+
911
+ Add one reusable presentation layer such as:
912
+
913
+ ```text
914
+ viewer/src/components/AnnotationLayer.tsx
915
+ ```
916
+
917
+ It should render a `<g>` layer inside the existing source SVG rather than create
918
+ an independently transformed screenshot/reference canvas.
919
+
920
+ The existing workspace owns the viewBox and zoom/pan state. The annotation layer
921
+ receives source-native coordinates.
922
+
923
+ ### 12.4 Pointer conversion
924
+
925
+ Extract/reuse one helper for screen-pointer to SVG-source-coordinate conversion
926
+ from current `useZoomPan` `getScreenCTM().inverse()` behavior.
927
+
928
+ Do not create one coordinate implementation for panning and another for drawing.
929
+
930
+ ### 12.5 Navigation versus drawing
931
+
932
+ The toolbar has explicit interaction modes:
933
+
934
+ ```text
935
+ select
936
+ pan
937
+ point
938
+ rectangle
939
+ line
940
+ arrow
941
+ note
942
+ ```
943
+
944
+ Drawing modes consume drawing pointer gestures. Pan mode consumes drag-to-pan
945
+ gestures. The same drag must never be interpreted simultaneously as both.
946
+
947
+ ## 13. Interpretation and confirmation workflow
948
+
949
+ For each mark:
950
+
951
+ ```text
952
+ draw/select
953
+ → optional explicit structured association
954
+ → choose intent
955
+ → show candidate canonical interpretation
956
+ → explicit Confirm
957
+ → save immutable annotation revision
958
+ ```
959
+
960
+ For runtime move/resize/preserve proposals, show the exact candidate
961
+ `ContractPrimitive` before confirmation.
962
+
963
+ Example:
964
+
965
+ ```text
966
+ Move workspace right
967
+
968
+ Candidate:
969
+ category: requested
970
+ primitive:
971
+ kind: property-increases
972
+ target: workspace
973
+ property: x
974
+ ```
975
+
976
+ The user confirms that structured meaning. The arrow itself is not the
977
+ contract.
978
+
979
+ For reference requirements, show the exact category, subject, and tolerance
980
+ before confirmation.
981
+
982
+ An annotation with no reliable association remains useful visual/narrative
983
+ evidence but cannot be promoted into a canonical requirement requiring a
984
+ structured subject.
985
+
986
+ ## 14. Conflict policy
987
+
988
+ v0.9 does not introduce a new semantic conflict engine.
989
+
990
+ ### Revision conflict
991
+
992
+ Handled by annotation revision lineage. Stale edits fail explicitly.
993
+
994
+ ### Contract conflict
995
+
996
+ Promotion builds an ordinary per-change contract. Existing contract validation
997
+ and evaluation remains authoritative for clause conflicts.
998
+
999
+ ### Reference requirement conflict
1000
+
1001
+ Existing reference requirement validation and adequacy derivation remains
1002
+ authoritative.
1003
+
1004
+ ### Unsupported interpretation
1005
+
1006
+ A confirmed human intent that has no current canonical mapping is not a conflict
1007
+ and is not a pass. Report it as:
1008
+
1009
+ ```text
1010
+ confirmed but not canonically promotable
1011
+ ```
1012
+
1013
+ with a bounded reason. `remove` is the initial required example.
1014
+
1015
+ ## 15. Implementation sequence
1016
+
1017
+ Implement v0.9 in exactly seven ordered implementation prompts. Each prompt
1018
+ assumes earlier prompts are implemented and merged.
1019
+
1020
+ ### Batch 1 — Visual annotation domain, identity, persistence, and overlay derivation
1021
+
1022
+ #### Goal
1023
+
1024
+ Implement the canonical annotation evidence family independently of viewer
1025
+ authoring UI.
1026
+
1027
+ #### Production scope
1028
+
1029
+ Add:
1030
+
1031
+ ```text
1032
+ src/domain/visualAnnotation.ts
1033
+ src/domain/visualAnnotationIdentity.ts
1034
+ src/artifacts/visualAnnotationArtifactWriter.ts
1035
+ src/artifacts/visualAnnotationArtifactReader.ts
1036
+ src/application/visualAnnotationPersistenceService.ts
1037
+ ```
1038
+
1039
+ Implement artifact/schema constants, the runtime/reference source union, five
1040
+ mark kinds, association types, interpretation state, frozen intent vocabulary,
1041
+ source-domain validation, bounded counts/text, coordinate validation,
1042
+ deterministic request identity, fresh instance identity, forward-only
1043
+ supersession, deterministic overlay SVG, immutable atomic persistence, reader
1044
+ validation, and public `src/index.ts` exports.
1045
+
1046
+ #### Mandatory tests
1047
+
1048
+ Cover:
1049
+
1050
+ - valid runtime artifact;
1051
+ - valid reference artifact;
1052
+ - invalid cross-domain association;
1053
+ - invalid/out-of-frame annotation geometry;
1054
+ - note length/count bounds;
1055
+ - candidate versus confirmed interpretation;
1056
+ - invalid authored `unexpected`;
1057
+ - deterministic request identity;
1058
+ - timestamp/output-path exclusion from request identity;
1059
+ - fresh instance identity;
1060
+ - writer/reader round trip;
1061
+ - no overwrite;
1062
+ - temporary-directory cleanup;
1063
+ - overlay determinism and SHA-256;
1064
+ - malicious text escaping in generated SVG;
1065
+ - supersession preservation.
1066
+
1067
+ #### Gate
1068
+
1069
+ A structured runtime or reference annotation can be constructed, validated,
1070
+ persisted immutably, read back, and rendered as the same deterministic overlay
1071
+ without any viewer mutation route.
1072
+
1073
+ ### Batch 2 — Viewer discovery, project authoring boundary, and secure POST API
1074
+
1075
+ #### Goal
1076
+
1077
+ Make annotation evidence visible and establish the secure local write boundary.
1078
+
1079
+ #### Production scope
1080
+
1081
+ Extend evidence classification, metadata projection, on-demand annotation
1082
+ loading, media resolution for `annotation-overlay.svg`, annotation/source view
1083
+ projection, and project-aware viewer startup.
1084
+
1085
+ Implement:
1086
+
1087
+ - authoring enabled only in initialized project mode;
1088
+ - in-memory session capability token;
1089
+ - strict same-origin/Host checks;
1090
+ - JSON-only bounded request bodies;
1091
+ - annotation save POST;
1092
+ - source-handle to canonical-source resolution;
1093
+ - optional parent annotation revision;
1094
+ - stale revision conflict response;
1095
+ - no arbitrary client-supplied write path;
1096
+ - standalone `view --root` remains read-only.
1097
+
1098
+ #### Mandatory tests
1099
+
1100
+ Cover annotation family classification, unsupported/malformed annotation,
1101
+ source resolution, missing source, overlay media serving, traversal/symlink
1102
+ containment, project-mode authoring, standalone read-only behavior, missing or
1103
+ incorrect token, wrong Origin, unsupported methods, oversized/invalid request,
1104
+ valid save, stale revision conflict, and unchanged prior artifact.
1105
+
1106
+ #### Gate
1107
+
1108
+ A project-aware viewer can save and reload an immutable annotation artifact
1109
+ through a secured local POST boundary while previous GET/HEAD inspection
1110
+ behavior remains unchanged.
1111
+
1112
+ ### Batch 3 — Runtime screenshot annotation authoring
1113
+
1114
+ #### Goal
1115
+
1116
+ Allow a human to create, edit, save, and reload annotations directly on a
1117
+ runtime observation.
1118
+
1119
+ #### Production scope
1120
+
1121
+ Add the annotation toolbar and shared annotation layer.
1122
+
1123
+ Support interaction modes:
1124
+
1125
+ ```text
1126
+ select
1127
+ pan
1128
+ point
1129
+ rectangle
1130
+ line
1131
+ arrow
1132
+ note
1133
+ ```
1134
+
1135
+ Integrate with `ObservationWorkspace`, `TargetOverlaySvg`, target selection,
1136
+ relationship views, and current zoom/pan.
1137
+
1138
+ Implement explicit runtime associations through existing target/relationship
1139
+ selection only.
1140
+
1141
+ Implement in-memory draft editing:
1142
+
1143
+ ```text
1144
+ create
1145
+ select
1146
+ move annotation mark
1147
+ edit note
1148
+ delete unsaved draft mark
1149
+ cancel
1150
+ save
1151
+ ```
1152
+
1153
+ Deleting a draft mark does not delete historical persisted evidence.
1154
+
1155
+ #### Mandatory browser tests
1156
+
1157
+ Prove exact runtime CSS-pixel geometry, zoom/pan pointer mapping, no DPR
1158
+ conversion, explicit target association, no overlap auto-binding, save/reload,
1159
+ alias-to-canonical source resolution, alias replacement not rebinding saved
1160
+ annotation, source-unavailable behavior, and keyboard/pointer usability.
1161
+
1162
+ #### Gate
1163
+
1164
+ A user can annotate an observation, save it, reload, and see the same marks
1165
+ associated with the same canonical observation and explicit runtime
1166
+ associations.
1167
+
1168
+ ### Batch 4 — External-reference annotation and reference-region authoring
1169
+
1170
+ #### Goal
1171
+
1172
+ Provide the same structured authoring flow in reference-image coordinates and
1173
+ add explicit region creation/refinement.
1174
+
1175
+ #### Production scope
1176
+
1177
+ Integrate the annotation layer into `ReferenceWorkspace`,
1178
+ `ReferenceRegionOverlaySvg`, existing reference-region selection, relationship
1179
+ projection, and zoom/pan/view-lock behavior.
1180
+
1181
+ Support reference point/rectangle/line/arrow/note marks, explicit
1182
+ region/relationship association, candidate region creation, candidate region
1183
+ refinement, `asset-sensitive` informational intent, and informational versus
1184
+ candidate-requirement distinction.
1185
+
1186
+ Do not materialize a new reference artifact yet. That belongs to Batch 6.
1187
+
1188
+ #### Mandatory browser tests
1189
+
1190
+ Prove exact reference-image coordinates, zoom/pan coordinate correctness,
1191
+ reference-region/runtime-target identity separation, no equal-name auto-binding,
1192
+ region create/refine preview, unchanged source artifact, binding
1193
+ cross-highlighting remaining separate from annotation association, and
1194
+ save/reload preserving canonical reference source identity.
1195
+
1196
+ #### Gate
1197
+
1198
+ A user can annotate an imported or approved reference, create/refine candidate
1199
+ regions, save/reload, and retain the exact selected canonical reference source
1200
+ without mutating it.
1201
+
1202
+ ### Batch 5 — Intent interpretation, confirmation, and canonical change-contract promotion
1203
+
1204
+ #### Goal
1205
+
1206
+ Turn explicitly confirmed runtime visual intent into the existing per-change
1207
+ contract model.
1208
+
1209
+ #### Production scope
1210
+
1211
+ Add interpretation UI for:
1212
+
1213
+ ```text
1214
+ inspect
1215
+ move
1216
+ resize
1217
+ remove
1218
+ preserve
1219
+ ```
1220
+
1221
+ Add category selection for the four existing authored categories and show the
1222
+ exact canonical proposal before confirmation.
1223
+
1224
+ Implement supported mappings through existing `ContractPrimitive` values.
1225
+ Implement an annotation-to-contract application service and persist through the
1226
+ existing frontend contract persistence owner.
1227
+
1228
+ Promote only explicitly selected confirmed annotations.
1229
+
1230
+ Support explicit activation through existing project acceptance configuration
1231
+ when a baseline contract is already configured.
1232
+
1233
+ `remove` is confirmed annotation intent but is not canonically promotable in
1234
+ v0.9. Do not extend the primitive vocabulary merely to make it promotable.
1235
+
1236
+ #### Mandatory tests
1237
+
1238
+ Cover at least:
1239
+
1240
+ - move right -> `property-increases x`;
1241
+ - move left -> `property-decreases x`;
1242
+ - move down -> `property-increases y`;
1243
+ - resize wider -> `property-increases width`;
1244
+ - preserve property -> `property-unchanged-within-tolerance`;
1245
+ - preserve relationship -> `relationship-unchanged`;
1246
+ - expected-dependent requires its existing mode;
1247
+ - `unexpected` cannot be authored;
1248
+ - inspect is not promotable;
1249
+ - remove reports unsupported canonical mapping;
1250
+ - unconfirmed candidate cannot promote;
1251
+ - unbound mark cannot fabricate a target;
1252
+ - only selected confirmed items enter the contract;
1253
+ - contract persists through the canonical service;
1254
+ - active baseline IDs come from explicit configured evidence;
1255
+ - configured baseline is never replaced;
1256
+ - existing evaluator remains authoritative.
1257
+
1258
+ #### Gate
1259
+
1260
+ At least one move/resize case and one preserve case can travel:
1261
+
1262
+ ```text
1263
+ visual mark
1264
+ → explicit association
1265
+ → candidate structured interpretation
1266
+ → explicit confirmation
1267
+ → normal PerChangeContract
1268
+ ```
1269
+
1270
+ with no annotation-specific contract evaluator.
1271
+
1272
+ ### Batch 6 — Canonical external-reference region/requirement materialization
1273
+
1274
+ #### Goal
1275
+
1276
+ Turn explicitly confirmed reference annotation into a new immutable external
1277
+ reference revision through the existing reference model.
1278
+
1279
+ #### Production scope
1280
+
1281
+ Implement reference materialization for selected confirmed:
1282
+
1283
+ ```text
1284
+ reference-region create
1285
+ reference-region refine
1286
+ reference-requirement
1287
+ ```
1288
+
1289
+ Reuse `RawReferenceRequirement`, `ReferenceRequirementSubject`,
1290
+ `AuthoredChangeScopeCategory`, and `ReferenceRequirementTolerance`.
1291
+
1292
+ Use existing region relationship derivation for selectable relationship
1293
+ subjects.
1294
+
1295
+ Read original image bytes from the canonical image owner through the existing
1296
+ safe reference/media boundary. Persist a new imported external reference through
1297
+ the canonical reference persistence service. Set explicit supersession.
1298
+
1299
+ Never auto-approve or alter project configured approved-reference acceptance.
1300
+
1301
+ #### Mandatory tests
1302
+
1303
+ Prove region creation, region refinement, preservation of unchanged regions and
1304
+ requirements, selected requirement addition, no auto-requirements from visible
1305
+ geometry, applicability preservation, image byte/hash preservation, old
1306
+ artifact immutability, fresh new reference identity, explicit supersession,
1307
+ resulting imported lifecycle, normal existing adequacy/relationship behavior,
1308
+ and no approval side effect.
1309
+
1310
+ #### Gate
1311
+
1312
+ A user can turn selected confirmed reference annotations into a normal new
1313
+ imported external-reference revision that can subsequently use the existing
1314
+ approval and fidelity workflow.
1315
+
1316
+ ### Batch 7 — Integrated acceptance, packaging, documentation, and regression
1317
+
1318
+ #### Goal
1319
+
1320
+ Prove v0.9 as one packaged feature without pulling v0.10 source editing or
1321
+ correction orchestration forward.
1322
+
1323
+ #### Required integrated scenarios
1324
+
1325
+ 1. Runtime observation annotation: select observation -> draw/note -> save ->
1326
+ reload.
1327
+ 2. Canonical identity: annotate alias `current` -> replace alias -> saved
1328
+ annotation still points to the original observation.
1329
+ 3. Move intent: arrow + target -> move candidate -> explicit confirmation ->
1330
+ canonical per-change clause.
1331
+ 4. Preserve intent -> confirmed canonical preserved clause.
1332
+ 5. Unsupported remove saves/reloads but cannot fabricate a contract.
1333
+ 6. Ambiguous/free drawing remains visual evidence and cannot silently become a
1334
+ strong requirement.
1335
+ 7. External-reference annotation -> save -> reload in reference-image
1336
+ coordinates.
1337
+ 8. Confirmed reference-region creation -> new imported reference revision.
1338
+ 9. Region refinement -> new revision while old reference remains unchanged.
1339
+ 10. Confirmed selected property/relationship/measurement requirement becomes a
1340
+ normal external-reference requirement.
1341
+ 11. Informational inspect/note/asset-sensitive annotation stays non-contractual.
1342
+ 12. Stale annotation revision is rejected rather than overwriting newer
1343
+ evidence.
1344
+ 13. Unrelated browser origin cannot POST annotation writes.
1345
+ 14. Missing source is reported honestly while annotation evidence remains
1346
+ inspectable.
1347
+ 15. Existing v0.8 viewer inspection remains functional.
1348
+ 16. Existing `init`, `capture`, `check`, and project-aware `view` remain
1349
+ functional.
1350
+ 17. Annotation create/reload and promoted-contract inspection work from a clean
1351
+ installed npm package.
1352
+
1353
+ #### Documentation reconciliation
1354
+
1355
+ Update implementation-facing documentation as appropriate after implementation:
1356
+
1357
+ ```text
1358
+ README.md
1359
+ CHANGELOG.md
1360
+ docs/ARCHITECTURE.md
1361
+ docs/COMMANDS.md
1362
+ docs/CONTRACTS.md
1363
+ docs/CURRENT_STATE.md
1364
+ docs/PROJECT_MILESTONES.md
1365
+ docs/PROJECT_OVERVIEW.md
1366
+ docs/QUICKSTART.md
1367
+ docs/ROADMAP.md
1368
+ docs/SECURITY.md
1369
+ docs/WORKFLOWS.md
1370
+ ```
1371
+
1372
+ Do not mark v0.9 released during implementation. Release-state changes belong
1373
+ to the later release-preparation workflow.
1374
+
1375
+ #### Gate
1376
+
1377
+ A packed candidate demonstrates both annotation source contexts, persistence,
1378
+ explicit confirmation, runtime contract promotion, reference region/requirement
1379
+ materialization, source immutability, security boundaries, and backward
1380
+ compatibility.
1381
+
1382
+ ## 16. Cross-batch invariants
1383
+
1384
+ Every implementation prompt must preserve these rules.
1385
+
1386
+ 1. Observations remain immutable.
1387
+ 2. External references remain immutable.
1388
+ 3. Annotation save creates new immutable evidence.
1389
+ 4. Mutable aliases never become annotation identity.
1390
+ 5. Runtime CSS pixels remain distinct from reference-image pixels.
1391
+ 6. Annotation geometry never silently establishes runtime/reference binding.
1392
+ 7. Viewer geometry overlap never silently establishes target/region ownership.
1393
+ 8. Drawing alone never becomes a contract.
1394
+ 9. Confirmation is required before promotion.
1395
+ 10. `unexpected` remains derived, never authored.
1396
+ 11. Existing contract primitives remain authoritative.
1397
+ 12. Existing reference requirement vocabulary remains authoritative.
1398
+ 13. Existing relationship derivation remains authoritative.
1399
+ 14. Existing contract evaluation remains authoritative.
1400
+ 15. Existing reference adequacy/compatibility/fidelity engines remain
1401
+ authoritative.
1402
+ 16. Reference-fidelity PASS cannot override an active contract failure.
1403
+ 17. Original source evidence is not rewritten during annotation.
1404
+ 18. New external-reference revisions are not automatically approved.
1405
+ 19. Annotation is optional for ordinary `capture`, `check`, and coding-agent
1406
+ workflows.
1407
+ 20. Observer never edits application source.
1408
+ 21. Observer does not generate HTML/CSS/application code from images.
1409
+ 22. Viewer POST may write only canonical Observer/project evidence explicitly
1410
+ authorized by this plan.
1411
+ 23. Browser/PWA caching must not make stale annotation/evidence API responses
1412
+ authoritative.
1413
+ 24. Historical annotation revisions remain available.
1414
+ 25. Unsupported intent is shown honestly rather than approximated into a
1415
+ different requirement.
1416
+
1417
+ ## 17. Version-wide validation
1418
+
1419
+ Every batch runs the focused tests it introduces.
1420
+
1421
+ Before declaring implementation complete, run at minimum:
1422
+
1423
+ ```text
1424
+ npm run typecheck
1425
+ npm run lint
1426
+ npm test
1427
+ npm run test:browser
1428
+ npm run build
1429
+ npm run check:docs
1430
+ ```
1431
+
1432
+ Also run all existing security/package checks used by the current pre-release
1433
+ workflow.
1434
+
1435
+ The final packed-candidate proof must verify that the package includes annotation
1436
+ domain/application/artifact compiled output, updated public exports, viewer
1437
+ server authoring code, annotation viewer assets, generated viewer bundle, and
1438
+ packed viewer smoke coverage.
1439
+
1440
+ Cross-platform validation must continue on the same supported Windows, Linux,
1441
+ and macOS surfaces used by the current release workflow.
1442
+
1443
+ ## 18. Explicit v0.9 exclusions
1444
+
1445
+ The following do not belong in v0.9:
1446
+
1447
+ ```text
1448
+ application source editing
1449
+ automatic coding-agent execution
1450
+ full correction-loop orchestration
1451
+ image-to-code
1452
+ raster-to-HTML
1453
+ raster-to-CSS
1454
+ automatic target discovery
1455
+ automatic reference/runtime binding
1456
+ automatic region detection
1457
+ OCR-driven requirements
1458
+ computer-vision segmentation
1459
+ freehand drawing
1460
+ arbitrary SVG input
1461
+ annotation collaboration
1462
+ accounts
1463
+ cloud synchronization
1464
+ database storage
1465
+ comment threads
1466
+ automatic reference approval
1467
+ automatic baseline approval
1468
+ automatic baseline replacement
1469
+ automatic approved-reference replacement
1470
+ new PASS/FAIL semantics
1471
+ annotation-only contract categories
1472
+ annotation-only reference requirement categories
1473
+ silent mapping of unsupported intent
1474
+ ```
1475
+
1476
+ The full human-to-coding-agent correction workflow remains v0.10.
1477
+
1478
+ ## 19. Prompt count and implementation order
1479
+
1480
+ The frozen implementation sequence is exactly seven prompts:
1481
+
1482
+ ```text
1483
+ Prompt 1
1484
+ Visual annotation domain, identity, persistence, overlay derivation
1485
+
1486
+ Prompt 2
1487
+ Viewer discovery, secure authoring boundary, annotation save API
1488
+
1489
+ Prompt 3
1490
+ Runtime screenshot annotation authoring
1491
+
1492
+ Prompt 4
1493
+ External-reference annotation and reference-region authoring
1494
+
1495
+ Prompt 5
1496
+ Interpretation, confirmation, canonical change-contract promotion
1497
+
1498
+ Prompt 6
1499
+ Canonical external-reference region/requirement materialization
1500
+
1501
+ Prompt 7
1502
+ Integrated acceptance, packaging, documentation, regression
1503
+ ```
1504
+
1505
+ Do not combine later prompts into an earlier batch merely because files are
1506
+ nearby.
1507
+
1508
+ Do not start Prompt 2 until Prompt 1 passes its gate.
1509
+
1510
+ Do not start contract/reference promotion until the persisted annotation
1511
+ contract and both coordinate-domain authoring flows are independently proven.
1512
+
1513
+ The dependency progression is:
1514
+
1515
+ ```text
1516
+ canonical annotation evidence
1517
+ ↓
1518
+ secure persistence through viewer
1519
+ ↓
1520
+ runtime visual authoring
1521
+ ↓
1522
+ reference visual authoring
1523
+ ↓
1524
+ confirmed canonical change intent
1525
+ ↓
1526
+ confirmed canonical reference intent
1527
+ ↓
1528
+ integrated packaged v0.9
1529
+ ```