@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.
- package/CHANGELOG.md +57 -0
- package/README.md +107 -7
- package/dist/application/projectWorkflowService.d.ts +18 -1
- package/dist/application/projectWorkflowService.js +40 -2
- package/dist/application/projectWorkflowService.js.map +1 -1
- package/dist/application/visualAnnotationContractPromotionService.d.ts +41 -0
- package/dist/application/visualAnnotationContractPromotionService.js +143 -0
- package/dist/application/visualAnnotationContractPromotionService.js.map +1 -0
- package/dist/application/visualAnnotationPersistenceService.d.ts +34 -0
- package/dist/application/visualAnnotationPersistenceService.js +68 -0
- package/dist/application/visualAnnotationPersistenceService.js.map +1 -0
- package/dist/application/visualAnnotationReferenceMaterializationService.d.ts +53 -0
- package/dist/application/visualAnnotationReferenceMaterializationService.js +194 -0
- package/dist/application/visualAnnotationReferenceMaterializationService.js.map +1 -0
- package/dist/artifacts/visualAnnotationArtifactReader.d.ts +19 -0
- package/dist/artifacts/visualAnnotationArtifactReader.js +66 -0
- package/dist/artifacts/visualAnnotationArtifactReader.js.map +1 -0
- package/dist/artifacts/visualAnnotationArtifactWriter.d.ts +42 -0
- package/dist/artifacts/visualAnnotationArtifactWriter.js +85 -0
- package/dist/artifacts/visualAnnotationArtifactWriter.js.map +1 -0
- package/dist/cli.js +464 -454
- package/dist/cli.js.map +1 -1
- package/dist/domain/visualAnnotation.d.ts +217 -0
- package/dist/domain/visualAnnotation.js +584 -0
- package/dist/domain/visualAnnotation.js.map +1 -0
- package/dist/domain/visualAnnotationIdentity.d.ts +17 -0
- package/dist/domain/visualAnnotationIdentity.js +47 -0
- package/dist/domain/visualAnnotationIdentity.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/projectWorkflow/projectPaths.d.ts +9 -0
- package/dist/projectWorkflow/projectPaths.js +21 -0
- package/dist/projectWorkflow/projectPaths.js.map +1 -1
- package/dist/viewer/assets/{index-CN_yb9Uf.css → index-BN41MI7m.css} +1 -1
- package/dist/viewer/assets/index-CkKXnlrI.js +9 -0
- package/dist/viewer/index.html +2 -2
- package/dist/viewer/sw.js +1 -1
- package/dist/viewerServer/annotationAuthoring.d.ts +64 -0
- package/dist/viewerServer/annotationAuthoring.js +230 -0
- package/dist/viewerServer/annotationAuthoring.js.map +1 -0
- package/dist/viewerServer/annotationContractPromotion.d.ts +51 -0
- package/dist/viewerServer/annotationContractPromotion.js +105 -0
- package/dist/viewerServer/annotationContractPromotion.js.map +1 -0
- package/dist/viewerServer/annotationReferenceMaterialization.d.ts +40 -0
- package/dist/viewerServer/annotationReferenceMaterialization.js +91 -0
- package/dist/viewerServer/annotationReferenceMaterialization.js.map +1 -0
- package/dist/viewerServer/authoringSecurity.d.ts +59 -0
- package/dist/viewerServer/authoringSecurity.js +112 -0
- package/dist/viewerServer/authoringSecurity.js.map +1 -0
- package/dist/viewerServer/evidence/annotationView.d.ts +28 -0
- package/dist/viewerServer/evidence/annotationView.js +43 -0
- package/dist/viewerServer/evidence/annotationView.js.map +1 -0
- package/dist/viewerServer/evidence/classify.d.ts +3 -1
- package/dist/viewerServer/evidence/classify.js +12 -0
- package/dist/viewerServer/evidence/classify.js.map +1 -1
- package/dist/viewerServer/evidence/discovery.d.ts +2 -0
- package/dist/viewerServer/evidence/discovery.js +6 -0
- package/dist/viewerServer/evidence/discovery.js.map +1 -1
- package/dist/viewerServer/evidence/handles.js +1 -0
- package/dist/viewerServer/evidence/handles.js.map +1 -1
- package/dist/viewerServer/evidence/index.d.ts +29 -0
- package/dist/viewerServer/evidence/index.js +43 -1
- package/dist/viewerServer/evidence/index.js.map +1 -1
- package/dist/viewerServer/evidence/mediaResolver.d.ts +1 -1
- package/dist/viewerServer/evidence/mediaResolver.js +28 -2
- package/dist/viewerServer/evidence/mediaResolver.js.map +1 -1
- package/dist/viewerServer/evidence/projection.d.ts +5 -1
- package/dist/viewerServer/evidence/projection.js +19 -0
- package/dist/viewerServer/evidence/projection.js.map +1 -1
- package/dist/viewerServer/httpServer.d.ts +13 -2
- package/dist/viewerServer/httpServer.js +278 -4
- package/dist/viewerServer/httpServer.js.map +1 -1
- package/dist/viewerServer/viewerService.d.ts +8 -0
- package/dist/viewerServer/viewerService.js +38 -2
- package/dist/viewerServer/viewerService.js.map +1 -1
- package/docs/ARCHITECTURE.md +108 -21
- package/docs/CI_CD.md +57 -1
- package/docs/COMMANDS.md +44 -4
- package/docs/CONTRACTS.md +78 -8
- package/docs/CURRENT_STATE.md +157 -35
- package/docs/DEVELOPMENT.md +8 -3
- package/docs/PROJECT_DESCRIPTION.md +4 -1
- package/docs/PROJECT_MILESTONES.md +4 -0
- package/docs/PROJECT_OVERVIEW.md +41 -17
- package/docs/QUICKSTART.md +52 -39
- package/docs/RELEASE.md +16 -11
- package/docs/ROADMAP.md +406 -66
- package/docs/SECURITY.md +71 -14
- package/docs/WORKFLOWS.md +151 -23
- package/docs/plans/v0.9-implementation-plan.md +1529 -0
- package/docs/reports/v0.9-architecture-retrieval.md +567 -0
- package/docs/reports/v0.9-batch1-visual-annotation-foundation.md +351 -0
- package/docs/reports/v0.9-batch2-viewer-annotation-authoring-boundary.md +438 -0
- package/docs/reports/v0.9-batch3-runtime-screenshot-annotation-authoring.md +412 -0
- package/docs/reports/v0.9-batch4-external-reference-annotation-authoring.md +452 -0
- package/docs/reports/v0.9-batch5-runtime-intent-contract-promotion.md +535 -0
- package/docs/reports/v0.9-batch6-reference-materialization.md +514 -0
- package/docs/reports/v0.9-batch7-integrated-acceptance.md +644 -0
- package/docs/reports/v0.9-demo-foundation.md +589 -0
- package/docs/reports/v0.9-final-pre-release-readiness.md +209 -0
- package/docs/reports/v0.9-final-readiness-corrections.md +530 -0
- package/docs/reports/v0.9-pre-release-readiness.md +170 -0
- package/docs/reports/v0.9-tutorial-end-to-end-acceptance.md +980 -0
- package/docs/reports/v0.9-tutorial-integration.md +731 -0
- package/package.json +2 -2
- package/dist/viewer/assets/index-D98S1_2d.js +0 -9
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# v0.9 Batch 4 Report: External-Reference Annotation Authoring
|
|
2
|
+
|
|
3
|
+
## 1. VERDICT
|
|
4
|
+
|
|
5
|
+
PASS_V0_9_BATCH4_EXTERNAL_REFERENCE_ANNOTATION_AUTHORING
|
|
6
|
+
|
|
7
|
+
## 2. Repository identity
|
|
8
|
+
|
|
9
|
+
1. Repository: `C:\Users\daile\Projects\my-frontend-observer`
|
|
10
|
+
2. Branch: `master`
|
|
11
|
+
3. Starting HEAD: `9d8169b653b087a581ef38a04f97bfab5a252aae`
|
|
12
|
+
4. Ending HEAD before the final commit: `9d8169b653b087a581ef38a04f97bfab5a252aae`
|
|
13
|
+
5. Package version: `0.8.1` (unchanged in `package.json` and `package-lock.json`)
|
|
14
|
+
|
|
15
|
+
## 3. Prompt 3 entry gate
|
|
16
|
+
|
|
17
|
+
1. Prompt 3 verdict: `PASS_V0_9_BATCH3_RUNTIME_SCREENSHOT_ANNOTATION_AUTHORING`
|
|
18
|
+
2. Prompt 3 commit: `9d8169b653b087a581ef38a04f97bfab5a252aae`
|
|
19
|
+
3. Runtime annotation UI: implemented
|
|
20
|
+
4. Prompt 2 save API: unchanged
|
|
21
|
+
5. Viewer protocol: `1.1.0`
|
|
22
|
+
6. Preflight found a clean tracked worktree on `master` at the required HEAD.
|
|
23
|
+
7. `git ls-files -v docs/reports/v0.9-architecture-retrieval.md` printed `S`
|
|
24
|
+
at entry and before commit. The `skip-worktree` state was preserved and the
|
|
25
|
+
file was not restored, overwritten, or committed. No pull, rebase, reset,
|
|
26
|
+
or clean was run.
|
|
27
|
+
8. No Prompt 1 to 3 API conflict and no domain contract defect were found.
|
|
28
|
+
No file under `src/` changed.
|
|
29
|
+
|
|
30
|
+
## 4. Imported/approved reference source handling
|
|
31
|
+
|
|
32
|
+
1. The source frame is `image.width`/`image.height` for an imported
|
|
33
|
+
reference and `sourceReference.image.width`/`height` for an approved one.
|
|
34
|
+
These are the same values the reference SVG already uses for its viewBox.
|
|
35
|
+
2. The browser sends only `{ sourceHandle, parentAnnotationHandle?, items }`.
|
|
36
|
+
The Prompt 2 server builds `referenceId`, `referenceRequestId`,
|
|
37
|
+
`lifecycle`, `imageOwnerReferenceId`, and `imageSha256`.
|
|
38
|
+
3. The annotation is tied to whichever reference the user opened.
|
|
39
|
+
Browser-verified:
|
|
40
|
+
1. An imported annotation has `lifecycle: imported`, the imported
|
|
41
|
+
`referenceId`, and the image owner equal to itself.
|
|
42
|
+
2. An approved annotation has `lifecycle: approved`, the approved
|
|
43
|
+
`referenceId`, and `imageOwnerReferenceId` equal to the imported
|
|
44
|
+
`sourceReference.referenceId`.
|
|
45
|
+
3. Neither is redirected to the other.
|
|
46
|
+
|
|
47
|
+
## 5. Reference annotation discovery
|
|
48
|
+
|
|
49
|
+
1. The Prompt 3 discovery hook was generalized into `useSourceAnnotations`
|
|
50
|
+
(in `useRuntimeAnnotations.ts`). `useRuntimeAnnotations` is now a thin
|
|
51
|
+
wrapper with unchanged behavior.
|
|
52
|
+
2. New `viewer/src/hooks/useReferenceAnnotations.ts` finds candidates through
|
|
53
|
+
`/api/index` by `relatedIds.sourceReferenceId`. It keeps a candidate only
|
|
54
|
+
when `/api/annotations/:handle/view` reports `source.status === available`,
|
|
55
|
+
`source.family` equal to the current reference family, and `source.handle`
|
|
56
|
+
equal to the current reference handle. That check is
|
|
57
|
+
`annotationViewBelongsToSource`.
|
|
58
|
+
3. Labels, image dimensions, `referenceRequestId` alone, region ids, and image
|
|
59
|
+
hashes are never used to attach an annotation.
|
|
60
|
+
|
|
61
|
+
## 6. Shared annotation infrastructure reuse
|
|
62
|
+
|
|
63
|
+
Reused unchanged:
|
|
64
|
+
|
|
65
|
+
1. `AnnotationLayer`
|
|
66
|
+
2. `useAnnotationPointerInteraction`
|
|
67
|
+
3. `sourceCoordinates.screenPointToSvgSource`
|
|
68
|
+
4. `annotationGeometry`
|
|
69
|
+
5. `useAuthoringSession`
|
|
70
|
+
6. `useZoomPan`, in the reference pane's existing controlled mode
|
|
71
|
+
|
|
72
|
+
Small generic refactors, with runtime behavior preserved and all Prompt 3
|
|
73
|
+
tests still passing:
|
|
74
|
+
|
|
75
|
+
1. `useRuntimeAnnotationDraft.ts` now exports `useAnnotationDraft(sourceHandle)`.
|
|
76
|
+
`useRuntimeAnnotationDraft` is an alias of it.
|
|
77
|
+
2. The 404 save message says "source evidence" instead of "source
|
|
78
|
+
observation". The existing tests check "no longer exists", which is
|
|
79
|
+
unchanged.
|
|
80
|
+
3. `AnnotationToolbar` makes its zoom controls optional through `zoom?` and
|
|
81
|
+
`zoomLabel`, because the reference pane already renders its own
|
|
82
|
+
`ZoomControls`.
|
|
83
|
+
4. New `AnnotationPanelSections.tsx` holds the session notice, saved list, and
|
|
84
|
+
draft lifecycle. It was extracted from `RuntimeAnnotationPanel` with
|
|
85
|
+
identical markup and used by both panels.
|
|
86
|
+
|
|
87
|
+
No reference-specific layer, coordinate helper, pointer interaction, or
|
|
88
|
+
toolbar was created.
|
|
89
|
+
|
|
90
|
+
## 7. Reference-image coordinate behavior
|
|
91
|
+
|
|
92
|
+
1. All drawing and moving uses the shared CTM transform in the reference SVG's
|
|
93
|
+
own viewBox, which is reference-image pixels.
|
|
94
|
+
2. The candidate viewport, CSS pixels, devicePixelRatio, the reference/candidate
|
|
95
|
+
coordinate scale, and bindings are never used for persisted geometry.
|
|
96
|
+
3. Browser-verified at exact reference-image coordinates:
|
|
97
|
+
1. A rectangle drawn in reverse from 250,200 to 50,80 persists as
|
|
98
|
+
50, 80, 200, 120.
|
|
99
|
+
2. Zoomed and panned drawings persist their intended coordinates.
|
|
100
|
+
3. A drawing made while the view is locked persists reference pixels, not
|
|
101
|
+
values mapped through the 0.25 lock scale.
|
|
102
|
+
|
|
103
|
+
## 8. Interaction modes
|
|
104
|
+
|
|
105
|
+
1. The same closed set is used: `select`, `pan`, `point`, `rectangle`,
|
|
106
|
+
`line`, `arrow`, `note`. No region, requirement, or asset mode exists.
|
|
107
|
+
Those are interpretations of a selected mark.
|
|
108
|
+
2. `ReferenceRegionOverlaySvg` gains three optional props: `annotationLayer`,
|
|
109
|
+
`regionsInteractive` (default `true`), and `interactionClassName`. Callers
|
|
110
|
+
that pass none of them are unchanged.
|
|
111
|
+
3. Per mode:
|
|
112
|
+
1. Select: region selection plus mark selection and move.
|
|
113
|
+
2. Pan: `useZoomPan` handlers only.
|
|
114
|
+
3. Drawing modes: drawing only. Region pointer selection is off, but region
|
|
115
|
+
keyboard selection stays available.
|
|
116
|
+
4. Behavior change, recorded deliberately: the reference pane now pans only
|
|
117
|
+
in Pan mode. Before this batch a zoomed reference pane also panned on a
|
|
118
|
+
drag in its default state. This matches the Prompt 3 rule that a select
|
|
119
|
+
drag never pans. The candidate pane is unchanged.
|
|
120
|
+
5. Layout fix found by the browser tests. The reference workspace is a
|
|
121
|
+
fixed-height scrolling flex column, so its panes row could shrink, and the
|
|
122
|
+
details section, now taller with the annotation panel, was painted over the
|
|
123
|
+
lower part of the reference image. The fix is
|
|
124
|
+
`.reference-workspace > * { flex-shrink: 0; }`.
|
|
125
|
+
|
|
126
|
+
## 9. Reference region association
|
|
127
|
+
|
|
128
|
+
1. Drawing over a region never associates it.
|
|
129
|
+
2. With a draft item selected and a region selected (pointer in Select mode,
|
|
130
|
+
or keyboard), "Associate region <id>" sets
|
|
131
|
+
`{ kind: 'reference-region', regionId }`. "Clear association" removes it.
|
|
132
|
+
3. Selecting a region never associates automatically.
|
|
133
|
+
|
|
134
|
+
## 10. Reference relationship association
|
|
135
|
+
|
|
136
|
+
1. Options come only from `referenceView.regionRelationships.pairwiseRelationships`,
|
|
137
|
+
the canonical server derivation.
|
|
138
|
+
2. "Associate relationship" sets
|
|
139
|
+
`{ kind: 'reference-relationship', subjectRegion, relatedRegion, relationship }`.
|
|
140
|
+
3. Lines and arrows never imply a relationship. Nothing is derived in React.
|
|
141
|
+
|
|
142
|
+
## 11. Region create candidate
|
|
143
|
+
|
|
144
|
+
1. Available only for a selected rectangle, with a "Proposed region ID" input
|
|
145
|
+
(`maxLength=64`) and a hint about the allowed characters.
|
|
146
|
+
2. The id is never rewritten, lowercased, or replaced.
|
|
147
|
+
3. Blocked when:
|
|
148
|
+
1. the id is empty or does not match `^[A-Za-z0-9_-]{1,64}$`;
|
|
149
|
+
2. it duplicates a source region (case-insensitive);
|
|
150
|
+
3. it duplicates another draft create (case-insensitive);
|
|
151
|
+
4. source regions plus other distinct draft creates already reach 20
|
|
152
|
+
(`MAX_REFERENCE_REGIONS`, mirrored).
|
|
153
|
+
4. The candidate is
|
|
154
|
+
`{ kind: 'reference-region', mode: 'create', region: { id, rectangle } }`,
|
|
155
|
+
using the exact mark geometry.
|
|
156
|
+
5. The preview renders a dashed candidate rectangle labeled
|
|
157
|
+
"candidate new <id> (<state>)".
|
|
158
|
+
|
|
159
|
+
## 12. Region refine candidate
|
|
160
|
+
|
|
161
|
+
1. Requires a selected rectangle and a selected existing region. The user
|
|
162
|
+
clicks "Refine selected region <id>".
|
|
163
|
+
2. The candidate is `mode: 'refine'` with the same region id and the mark
|
|
164
|
+
geometry. The item is also explicitly associated with that region.
|
|
165
|
+
3. The preview shows the original source rectangle and the candidate
|
|
166
|
+
replacement, each with its own distinct class. The source region keeps
|
|
167
|
+
rendering with its original geometry.
|
|
168
|
+
4. A summary line reads "Existing source regions: N · Candidate creates: N ·
|
|
169
|
+
Candidate refinements: N" and is marked as not the final region set.
|
|
170
|
+
|
|
171
|
+
## 13. Informational and asset-sensitive intent
|
|
172
|
+
|
|
173
|
+
1. "Mark informational" gives `candidate { kind: 'inspect' }`.
|
|
174
|
+
2. "Mark asset-sensitive" gives `{ kind: 'asset-sensitive' }`.
|
|
175
|
+
3. "Mark asset-sensitive for region <id>" requires an explicitly selected
|
|
176
|
+
region and gives `{ kind: 'asset-sensitive', regionId }`.
|
|
177
|
+
4. None of these create a requirement, a PASS/FAIL result, or a contract
|
|
178
|
+
clause.
|
|
179
|
+
|
|
180
|
+
## 14. Candidate reference requirements
|
|
181
|
+
|
|
182
|
+
1. Categories are exactly `requested`, `expected-dependent`, `protected`, and
|
|
183
|
+
`preserved`. `expected-dependent` requires `required` or `permitted`. For
|
|
184
|
+
other categories the mode is absent, even if one was chosen earlier.
|
|
185
|
+
2. Subjects:
|
|
186
|
+
1. `region-property` takes an existing or draft-proposed region and one of
|
|
187
|
+
the 8 canonical properties. A tolerance is required.
|
|
188
|
+
2. `region-relationship` takes only a canonical server relationship,
|
|
189
|
+
selected by index. No tolerance is allowed. Candidate-created regions
|
|
190
|
+
never appear, because they have no derived relationships.
|
|
191
|
+
3. `region-measurement` takes two distinct known regions and one of the 6
|
|
192
|
+
canonical measurements. A tolerance is required. No measured value is
|
|
193
|
+
ever computed or stored.
|
|
194
|
+
3. Tolerance kinds are `exact`, `absolute-reference-px` (labeled
|
|
195
|
+
"reference-image pixels"), and `percent`. Amounts must be finite and
|
|
196
|
+
between 0 and 100.
|
|
197
|
+
4. "Set candidate requirement" is disabled with a visible reason until the
|
|
198
|
+
form is complete. It sets
|
|
199
|
+
`candidate { kind: 'reference-requirement', requirement }` with the
|
|
200
|
+
canonical `RawReferenceRequirement` shape.
|
|
201
|
+
5. The panel lists "Candidate annotation region proposals" and "Candidate
|
|
202
|
+
annotation requirements" separately from the source regions and
|
|
203
|
+
requirements shown by the unchanged reference inspector.
|
|
204
|
+
|
|
205
|
+
## 15. Confirmation workflow
|
|
206
|
+
|
|
207
|
+
1. "Confirm reference intent" is enabled only for a candidate. It sets
|
|
208
|
+
`{ state: 'confirmed', intent, confirmedAt: new Date().toISOString() }`.
|
|
209
|
+
2. Saving never confirms. Browser-verified: a candidate stays a candidate
|
|
210
|
+
after save.
|
|
211
|
+
3. The selected item always shows its interpretation state as text and the
|
|
212
|
+
exact intent structure as JSON before and after confirmation.
|
|
213
|
+
4. Confirmation was proven in the browser for all four families:
|
|
214
|
+
`reference-region`, `reference-requirement`, `inspect`, and
|
|
215
|
+
`asset-sensitive`.
|
|
216
|
+
|
|
217
|
+
## 16. Confirmation invalidation
|
|
218
|
+
|
|
219
|
+
1. Every reference draft edit passes through `applyReferenceItemEdit`. A
|
|
220
|
+
rectangle's region intent is first synchronized to the rectangle geometry.
|
|
221
|
+
2. If the item was confirmed and its meaning changed, it becomes a candidate
|
|
222
|
+
without `confirmedAt`. Meaning covers the mark, the association, and the
|
|
223
|
+
intent.
|
|
224
|
+
3. Setting a new intent (region id or mode, requirement fields, tolerance,
|
|
225
|
+
asset region) always produces a candidate.
|
|
226
|
+
4. Browser-verified:
|
|
227
|
+
1. Moving a confirmed candidate region synchronizes its rectangle, drops it
|
|
228
|
+
to candidate, and a later reconfirmation gets a new `confirmedAt`.
|
|
229
|
+
2. Changing a confirmed requirement's tolerance requires reconfirmation.
|
|
230
|
+
3. Changing a confirmed item's association requires reconfirmation.
|
|
231
|
+
5. Unit-verified: note text edits and asset-region changes also invalidate,
|
|
232
|
+
and a no-op edit keeps confirmation.
|
|
233
|
+
|
|
234
|
+
## 17. Save/reload/revision
|
|
235
|
+
|
|
236
|
+
1. Saving uses the unchanged Prompt 2 `POST /api/annotations`. On 201 the
|
|
237
|
+
canonical view is reloaded, the draft is replaced, the parent is set,
|
|
238
|
+
dirty is cleared, and the saved list is refreshed.
|
|
239
|
+
2. Failures use the shared bounded messages, keep the draft, and are never
|
|
240
|
+
retried.
|
|
241
|
+
3. Browser-verified reload: an approved-reference annotation containing a
|
|
242
|
+
plain mark, a region candidate, a confirmed requirement, and an
|
|
243
|
+
asset-sensitive candidate comes back with the same annotation id, item ids,
|
|
244
|
+
marks, and interpretations. The view equals the persisted artifact, and
|
|
245
|
+
the source handle is exactly the approved reference with media role
|
|
246
|
+
`source-image`.
|
|
247
|
+
4. Browser-verified revision: B supersedes A, item ids are kept, A's manifest
|
|
248
|
+
bytes are unchanged, and B has a fresh id.
|
|
249
|
+
5. After a reload the token is re-acquired and no draft is recovered.
|
|
250
|
+
|
|
251
|
+
## 18. Source immutability
|
|
252
|
+
|
|
253
|
+
1. Browser tests snapshot every file in the imported and approved reference
|
|
254
|
+
directories, meaning the manifests and the image.
|
|
255
|
+
2. The snapshots are compared after drawing, candidate create, candidate
|
|
256
|
+
refine, requirement authoring, confirmation, save, and revision. They were
|
|
257
|
+
byte-identical in each test.
|
|
258
|
+
3. Reference-family artifact count is unchanged, no manifest contains
|
|
259
|
+
`supersedesReferenceId`, and only visual-annotation artifacts are added.
|
|
260
|
+
4. No import, approval, materialization, or reference-write call exists in
|
|
261
|
+
the viewer.
|
|
262
|
+
|
|
263
|
+
## 19. Binding/view-lock regression
|
|
264
|
+
|
|
265
|
+
1. View lock (browser):
|
|
266
|
+
1. With a compatible candidate locked, zooming the reference pane still
|
|
267
|
+
moves the candidate view.
|
|
268
|
+
2. Drawing on the reference then leaves the candidate viewBox unchanged and
|
|
269
|
+
puts no annotation marks in the candidate pane.
|
|
270
|
+
3. The bound `header → header` binding row is unchanged.
|
|
271
|
+
4. The persisted rectangle is in reference pixels with no association.
|
|
272
|
+
2. Equal names (browser): the reference region `header` and the runtime
|
|
273
|
+
target `header`, with no declaration, never cross-highlight. The explicit
|
|
274
|
+
association is `reference-region header`, and no `runtime-target` appears
|
|
275
|
+
anywhere in the artifact.
|
|
276
|
+
3. Explicit binding cross-highlight (browser): reference `header` highlights
|
|
277
|
+
the candidate `header`, and candidate `sidebar` highlights reference
|
|
278
|
+
`sidebar`. Associating an annotation with `header` leaves both highlights
|
|
279
|
+
unchanged, and the association persists separately.
|
|
280
|
+
4. The existing `referenceCandidateWorkspace`, `referenceBindingFidelityWorkspace`,
|
|
281
|
+
and `referenceCorrectionWorkflow` browser suites pass unchanged.
|
|
282
|
+
|
|
283
|
+
## 20. Browser tests
|
|
284
|
+
|
|
285
|
+
New `tests/browser/referenceAnnotationAuthoring.test.ts` has 19 real-Chromium
|
|
286
|
+
tests, using the existing reference fixtures and the Prompt 2/3
|
|
287
|
+
`TestResources`/`readManifest` helpers.
|
|
288
|
+
|
|
289
|
+
1. Availability: the project-aware toolbar and Save are present. The
|
|
290
|
+
standalone viewer is read-only, region selection still works, and no
|
|
291
|
+
non-GET request is sent.
|
|
292
|
+
2. Imported reference: rectangle plus note, exact coordinates, imported source
|
|
293
|
+
identity, and dimensions.
|
|
294
|
+
3. Approved reference: all five mark kinds, approved identity, and the
|
|
295
|
+
imported image owner.
|
|
296
|
+
4. Zoom and pan coordinates, with pan and draw exclusive.
|
|
297
|
+
5. View lock regression.
|
|
298
|
+
6. No equal-name binding, plus explicit region association (keyboard region
|
|
299
|
+
selection).
|
|
300
|
+
7. Explicit relationship association.
|
|
301
|
+
8. Binding cross-highlight separate from association.
|
|
302
|
+
9. Region create candidate: duplicate id refused, preview, confirm, move
|
|
303
|
+
invalidates and syncs geometry, reconfirm, source byte-identical.
|
|
304
|
+
10. Region refine candidate: original and candidate preview, source region
|
|
305
|
+
unchanged, association set, source byte-identical.
|
|
306
|
+
11. Informational and asset-sensitive intent (with and without a region), plus
|
|
307
|
+
confirmation.
|
|
308
|
+
12. Region-property requirement (protected, `header` width,
|
|
309
|
+
absolute-reference-px 4), confirmed, source requirements unchanged.
|
|
310
|
+
13. Expected-dependent mode required, and omitted for other categories.
|
|
311
|
+
14. Region-relationship requirement from a canonical relationship, no
|
|
312
|
+
tolerance, and no candidate-region relationship offered.
|
|
313
|
+
15. Region-measurement requirement (vertical-gap, percent), with an
|
|
314
|
+
out-of-range amount refused, and invalidation on tolerance and
|
|
315
|
+
association change.
|
|
316
|
+
16. No auto requirement from drawn geometry, and save never confirms.
|
|
317
|
+
17. Save and reload.
|
|
318
|
+
18. Revision, no materialization, source byte-identical.
|
|
319
|
+
19. Keyboard selection of marks and regions, and keyboard-operated intent and
|
|
320
|
+
confirm controls.
|
|
321
|
+
|
|
322
|
+
Test-harness notes:
|
|
323
|
+
|
|
324
|
+
1. The reference SVG is inside scrolling containers. Gestures first scroll the
|
|
325
|
+
SVG into view and then compute both client points from the SVG CTM. This
|
|
326
|
+
is how the flex-shrink overlap was found.
|
|
327
|
+
2. No test performs an out-of-band canonical write while the page refreshes
|
|
328
|
+
evidence.
|
|
329
|
+
3. The file passed on repeated runs.
|
|
330
|
+
|
|
331
|
+
## 21. Unit tests
|
|
332
|
+
|
|
333
|
+
New `tests/unit/viewerReferenceAnnotationModel.test.ts` (18 tests) covers:
|
|
334
|
+
|
|
335
|
+
1. Create and refine construction, including rejection for non-rectangles.
|
|
336
|
+
2. Case-insensitive and pattern id blocking, the region maximum, and an item
|
|
337
|
+
re-creating its own id.
|
|
338
|
+
3. Geometry synchronization.
|
|
339
|
+
4. Region summary and requirement region choices.
|
|
340
|
+
5. Confirmation.
|
|
341
|
+
6. Invalidation by move, association, note text, and asset region, and no
|
|
342
|
+
invalidation on a no-op edit.
|
|
343
|
+
7. Informational and asset-sensitive shapes.
|
|
344
|
+
8. Region-property, relationship, and measurement requirement construction.
|
|
345
|
+
9. Expected-dependent mode rules and tolerance bounds.
|
|
346
|
+
10. Exact-family membership and association labels.
|
|
347
|
+
|
|
348
|
+
Several built items are also checked against the canonical
|
|
349
|
+
`isValidVisualAnnotationContent`, which proves the viewer's structures are
|
|
350
|
+
accepted by the domain validator.
|
|
351
|
+
|
|
352
|
+
## 22. Regression validation
|
|
353
|
+
|
|
354
|
+
Every command below was run on Windows in the repository root.
|
|
355
|
+
|
|
356
|
+
1. `npm run typecheck`: PASS
|
|
357
|
+
2. `npm run lint`: PASS
|
|
358
|
+
3. `npm test`: PASS (78 files, 1316 tests)
|
|
359
|
+
4. `npm run build`: PASS
|
|
360
|
+
5. `npm run test:browser`: PASS (23 files, 221 tests, real Chromium). This
|
|
361
|
+
includes `runtimeAnnotationAuthoring`, `referenceCandidateWorkspace`,
|
|
362
|
+
`referenceBindingFidelityWorkspace`, `referenceCorrectionWorkflow`,
|
|
363
|
+
`pwaHardening`, and `observationSvgWorkspace`.
|
|
364
|
+
6. `npm run test:security`: PASS (unit: 13 files, 143 tests. Browser: 3 files,
|
|
365
|
+
77 tests)
|
|
366
|
+
7. `npm run check:docs`: PASS
|
|
367
|
+
8. `npm pack --dry-run`: PASS (345 files, 900.7 kB)
|
|
368
|
+
|
|
369
|
+
## 23. Security regression
|
|
370
|
+
|
|
371
|
+
1. No server, domain, artifact, or application file changed.
|
|
372
|
+
2. Host, Origin, token, body-size, path, symlink, method, and PWA no-cache
|
|
373
|
+
tests pass.
|
|
374
|
+
3. The reference UI keeps the token in React memory only.
|
|
375
|
+
4. A source search of the new reference viewer files found no storage API,
|
|
376
|
+
`console` call, `dangerouslySetInnerHTML`, or reference import, approval,
|
|
377
|
+
or materialization call.
|
|
378
|
+
|
|
379
|
+
## 24. Known deferred writer/discovery race
|
|
380
|
+
|
|
381
|
+
This risk is carried forward unchanged from Prompt 3. It is not fixed and
|
|
382
|
+
Prompt 4 does not own it.
|
|
383
|
+
|
|
384
|
+
1. On Windows, the canonical artifact writers' atomic directory rename can
|
|
385
|
+
fail with `EPERM` if viewer evidence discovery is reading inside the
|
|
386
|
+
writer's `.tmp-<id>` directory at that moment.
|
|
387
|
+
2. It needs a concurrent evidence refresh during a save.
|
|
388
|
+
3. `src/artifacts/*` and `src/viewerServer/evidence/discovery.ts` were not
|
|
389
|
+
modified.
|
|
390
|
+
4. Prompt 4 tests perform no out-of-band canonical write while the page
|
|
391
|
+
refreshes evidence.
|
|
392
|
+
|
|
393
|
+
## 25. Scope audit
|
|
394
|
+
|
|
395
|
+
1. server authoring API changed: false
|
|
396
|
+
2. annotation artifact schema changed: false
|
|
397
|
+
3. external-reference artifact schema changed: false
|
|
398
|
+
4. source reference mutated: false
|
|
399
|
+
5. reference materialization implemented: false
|
|
400
|
+
6. reference approval implemented: false
|
|
401
|
+
7. runtime contract promotion implemented: false
|
|
402
|
+
8. runtime intent confirmation implemented: false
|
|
403
|
+
9. ContractPrimitive vocabulary changed: false
|
|
404
|
+
10. project config schema changed: false
|
|
405
|
+
11. alias catalog schema changed: false
|
|
406
|
+
12. package version changed: false
|
|
407
|
+
13. dependency changed: false
|
|
408
|
+
|
|
409
|
+
Runtime annotation semantics are unchanged: new runtime items stay
|
|
410
|
+
`uninterpreted`, and the runtime panel has no intent or confirmation
|
|
411
|
+
controls.
|
|
412
|
+
|
|
413
|
+
## 26. Changed files
|
|
414
|
+
|
|
415
|
+
### 26.1 Added
|
|
416
|
+
|
|
417
|
+
1. `viewer/src/annotation/referenceIntent.ts`
|
|
418
|
+
2. `viewer/src/components/ReferenceAnnotationPanel.tsx`
|
|
419
|
+
3. `viewer/src/components/CandidateRegionPreviewLayer.tsx` (display-only
|
|
420
|
+
candidate region preview inside the reference SVG)
|
|
421
|
+
4. `viewer/src/components/AnnotationPanelSections.tsx` (shared panel
|
|
422
|
+
sections extracted from the runtime panel)
|
|
423
|
+
5. `viewer/src/hooks/useReferenceAnnotations.ts`
|
|
424
|
+
6. `viewer/src/hooks/useReferenceAnnotationDraft.ts`
|
|
425
|
+
7. `tests/browser/referenceAnnotationAuthoring.test.ts`
|
|
426
|
+
8. `tests/unit/viewerReferenceAnnotationModel.test.ts`
|
|
427
|
+
9. `docs/reports/v0.9-batch4-external-reference-annotation-authoring.md`
|
|
428
|
+
|
|
429
|
+
### 26.2 Modified
|
|
430
|
+
|
|
431
|
+
1. `viewer/src/components/ReferenceWorkspace.tsx`
|
|
432
|
+
2. `viewer/src/components/ReferenceRegionOverlaySvg.tsx`
|
|
433
|
+
3. `viewer/src/components/AnnotationToolbar.tsx` (optional zoom controls)
|
|
434
|
+
4. `viewer/src/components/RuntimeAnnotationPanel.tsx` (uses the shared
|
|
435
|
+
sections, with identical markup)
|
|
436
|
+
5. `viewer/src/hooks/useRuntimeAnnotationDraft.ts` (generic
|
|
437
|
+
`useAnnotationDraft`)
|
|
438
|
+
6. `viewer/src/hooks/useRuntimeAnnotations.ts` (generic
|
|
439
|
+
`useSourceAnnotations`)
|
|
440
|
+
7. `viewer/src/styles/index.css`
|
|
441
|
+
8. `viewer/src/types/reference.ts` (type-only `RawReferenceRequirement`
|
|
442
|
+
re-export)
|
|
443
|
+
|
|
444
|
+
### 26.3 Generated paths
|
|
445
|
+
|
|
446
|
+
1. `dist/` was rebuilt. It is ignored.
|
|
447
|
+
2. Tests create and remove temporary directories under the OS temp directory.
|
|
448
|
+
3. Validation logs went to the session scratchpad.
|
|
449
|
+
|
|
450
|
+
## 27. Remaining next step
|
|
451
|
+
|
|
452
|
+
v0.9 Prompt 5 — Intent interpretation, confirmation, and canonical change-contract promotion
|