@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,351 @@
|
|
|
1
|
+
# v0.9 Batch 1 Report: Visual Annotation Foundation
|
|
2
|
+
|
|
3
|
+
## 1. VERDICT
|
|
4
|
+
|
|
5
|
+
PASS_V0_9_BATCH1_VISUAL_ANNOTATION_FOUNDATION
|
|
6
|
+
|
|
7
|
+
## 2. Repository identity
|
|
8
|
+
|
|
9
|
+
1. Repository: `C:\Users\daile\Projects\my-frontend-observer`
|
|
10
|
+
2. Branch: `master`
|
|
11
|
+
3. Local HEAD at session start: `473713d240af09e752eeb8e00735738c4927b16d`
|
|
12
|
+
4. Starting HEAD for implementation: `59cfb6fd29a0c3c394d6115213edf92c1106104f`
|
|
13
|
+
(the expected v0.9 planning commit on `origin/master`)
|
|
14
|
+
5. Ending HEAD before the final commit: `59cfb6fd29a0c3c394d6115213edf92c1106104f`
|
|
15
|
+
6. Package version: `0.8.1` (unchanged in `package.json` and `package-lock.json`)
|
|
16
|
+
|
|
17
|
+
### 2.1 Preflight handling
|
|
18
|
+
|
|
19
|
+
The first preflight found local `master` three commits behind `origin/master`.
|
|
20
|
+
It also found one untracked local file,
|
|
21
|
+
`docs/reports/v0.9-architecture-retrieval.md`. That path is tracked on
|
|
22
|
+
`origin/master` with different content. The first run stopped with
|
|
23
|
+
`BLOCKED_V0_9_BATCH1_DIRTY_WORKTREE`.
|
|
24
|
+
|
|
25
|
+
The user then told the agent to keep the local copy, not delete it, and
|
|
26
|
+
continue. The agent did the following:
|
|
27
|
+
|
|
28
|
+
1. Copied the local file to
|
|
29
|
+
`.my-dev-kit-workflow/adhoc/preserved-local-docs/v0.9-architecture-retrieval.md`.
|
|
30
|
+
It checked that the SHA-256 of the copy matched the original. This folder is
|
|
31
|
+
ignored by Git.
|
|
32
|
+
2. Moved the original to
|
|
33
|
+
`.my-dev-kit-workflow/adhoc/preserved-local-docs/v0.9-architecture-retrieval.md.moved`.
|
|
34
|
+
3. Ran `git merge --ff-only origin/master`. This fast-forwarded `master` to `59cfb6f`.
|
|
35
|
+
4. Copied the local content back to `docs/reports/v0.9-architecture-retrieval.md`.
|
|
36
|
+
5. Ran `git update-index --skip-worktree docs/reports/v0.9-architecture-retrieval.md`.
|
|
37
|
+
Git now leaves the local copy alone and the worktree reports clean.
|
|
38
|
+
|
|
39
|
+
This commit does not include that file. To go back to the tracked version, run
|
|
40
|
+
`git update-index --no-skip-worktree docs/reports/v0.9-architecture-retrieval.md`.
|
|
41
|
+
|
|
42
|
+
## 3. Frozen scope implemented
|
|
43
|
+
|
|
44
|
+
1. `src/domain/visualAnnotation.ts` holds the frozen constants and all
|
|
45
|
+
annotation types: source, mark, association, intent, interpretation, item,
|
|
46
|
+
and artifact. It also holds the one canonical structural validator,
|
|
47
|
+
`isValidVisualAnnotationArtifact`, and the pure deterministic overlay
|
|
48
|
+
renderer, `renderVisualAnnotationOverlaySvg`.
|
|
49
|
+
2. `src/domain/visualAnnotationIdentity.ts` holds
|
|
50
|
+
`buildVisualAnnotationRequestIdentity`, a deterministic semantic SHA-256
|
|
51
|
+
identity. It also holds `buildVisualAnnotationInstanceIdentity`, a fresh
|
|
52
|
+
`randomBytes(16)` instance identity.
|
|
53
|
+
3. `src/artifacts/visualAnnotationArtifactWriter.ts` is an immutable, atomic,
|
|
54
|
+
manifest-last writer. It re-derives the overlay and verifies its digest
|
|
55
|
+
before writing.
|
|
56
|
+
4. `src/artifacts/visualAnnotationArtifactReader.ts` is the canonical reader.
|
|
57
|
+
It validates the manifest and checks that the owned overlay is a regular
|
|
58
|
+
file whose SHA-256 matches the manifest.
|
|
59
|
+
5. `src/application/visualAnnotationPersistenceService.ts` holds
|
|
60
|
+
`persistVisualAnnotation`, the one Batch 1 save use case.
|
|
61
|
+
6. `src/index.ts` adds the public Batch 1 exports.
|
|
62
|
+
|
|
63
|
+
## 4. Domain contract
|
|
64
|
+
|
|
65
|
+
1. Artifact kind: `my-frontend-observer/visual-annotation`
|
|
66
|
+
2. Schema version: `1.0.0`
|
|
67
|
+
3. Source contexts (2): `runtime-observation` and `external-reference`
|
|
68
|
+
4. Coordinate kinds: `runtime-css-px` for runtime sources and
|
|
69
|
+
`reference-image-px` for reference sources. A cross-domain coordinate kind
|
|
70
|
+
is rejected.
|
|
71
|
+
5. Mark kinds (5): `point`, `rectangle`, `line`, `arrow`, `note`
|
|
72
|
+
6. Intent kinds: `inspect`, `change`, `reference-region`,
|
|
73
|
+
`reference-requirement`, `asset-sensitive`. Runtime sources accept
|
|
74
|
+
`inspect` and `change`. Reference sources accept `inspect`,
|
|
75
|
+
`reference-region`, `reference-requirement`, and `asset-sensitive`.
|
|
76
|
+
7. Interpretation states: `uninterpreted`, `candidate`, `confirmed`
|
|
77
|
+
8. Item bound: `MAX_VISUAL_ANNOTATION_ITEMS = 100`
|
|
78
|
+
9. Note bound: `MAX_VISUAL_ANNOTATION_NOTE_LENGTH = 2000`
|
|
79
|
+
|
|
80
|
+
### 4.1 Canonical validators reused
|
|
81
|
+
|
|
82
|
+
1. Change categories use `isAuthoredChangeScopeCategory`. `unexpected` is not
|
|
83
|
+
a member, so it cannot be authored.
|
|
84
|
+
2. Expected-dependent mode uses `isValidExpectedDependentMode`. The mode is
|
|
85
|
+
required when the category is `expected-dependent` and must be absent
|
|
86
|
+
otherwise. This is the same rule `PerChangeClause` and
|
|
87
|
+
`RawReferenceRequirement` apply. Neither owning module exports the combined
|
|
88
|
+
check as a function, so Batch 1 applies the rule using the two exported
|
|
89
|
+
validators.
|
|
90
|
+
3. Contract primitives use `isValidContractPrimitive`.
|
|
91
|
+
4. Reference-region intent uses `isValidReferenceRegions([region], width, height)`.
|
|
92
|
+
This covers the region id pattern, rectangle validity, and the source image
|
|
93
|
+
bounds.
|
|
94
|
+
5. Reference-requirement intent uses `isValidRawReferenceRequirement`.
|
|
95
|
+
6. Relationship kinds come from `PAIRWISE_RELATIONSHIP_KINDS` and
|
|
96
|
+
`PAGE_LEVEL_RELATIONSHIP_KINDS`.
|
|
97
|
+
|
|
98
|
+
### 4.2 Local implementation choices
|
|
99
|
+
|
|
100
|
+
These choices were left open by the frozen plan and this prompt.
|
|
101
|
+
|
|
102
|
+
1. Every annotation object is a closed shape. Unknown fields are rejected, the
|
|
103
|
+
same way `isValidContractPrimitive` already rejects them. This is how the
|
|
104
|
+
validator rejects mixed forms, such as a candidate with `confirmedAt`, and
|
|
105
|
+
stray fields such as an alias or a viewer URL.
|
|
106
|
+
2. A runtime `runtime-relationship` with a pairwise kind needs two non-empty,
|
|
107
|
+
distinct targets. This matches `PairwiseLayoutRelationship`. A page-level
|
|
108
|
+
kind must not carry targets. This matches `PageLevelLayoutRelationship`.
|
|
109
|
+
3. A reference source with lifecycle `imported` must have
|
|
110
|
+
`imageOwnerReferenceId` equal to `referenceId`. A reference source with
|
|
111
|
+
lifecycle `approved` must name a different owning reference. This mirrors
|
|
112
|
+
the existing external-reference ownership model.
|
|
113
|
+
4. `annotationId` names the artifact directory. The validator requires it to
|
|
114
|
+
be a single safe path segment: no separators, no colon, no NUL, and not
|
|
115
|
+
`.` or `..`. `source.screenshot.path` follows the same bare-filename rule.
|
|
116
|
+
5. Invalid content given to the persistence service is refused with the
|
|
117
|
+
existing `invalid-request` diagnostic. No new diagnostic code was added.
|
|
118
|
+
6. Batch 1 does not check whether an associated target or region exists in
|
|
119
|
+
another artifact. It does not check `contractPrimitive` against the item's
|
|
120
|
+
association either. Those checks belong to later batches.
|
|
121
|
+
|
|
122
|
+
## 5. Identity contract
|
|
123
|
+
|
|
124
|
+
1. The request identity hashes exactly
|
|
125
|
+
`{ source, items, supersedes: supersedesAnnotationId ?? null }`. The hash is
|
|
126
|
+
built by sorting object keys recursively, keeping array order, serializing
|
|
127
|
+
to JSON, and taking the lowercase SHA-256 hex. The module has its own
|
|
128
|
+
private `canonicalize`, which follows the repository convention.
|
|
129
|
+
2. Excluded from the request identity: `createdAt`, the output location, cwd,
|
|
130
|
+
project root, alias, viewer port, HTTP handle, temporary directory, overlay
|
|
131
|
+
SHA, and `annotationId`. The function accepts none of these as inputs.
|
|
132
|
+
3. Instance identity is `${annotationRequestId}-${randomBytes(16).toString('hex')}`.
|
|
133
|
+
It is never based on a timestamp.
|
|
134
|
+
4. Supersession is carried forward as given. It is part of the request
|
|
135
|
+
identity, and the validator rejects an empty value or a value equal to
|
|
136
|
+
`annotationId`. Batch 1 does not resolve lineage.
|
|
137
|
+
|
|
138
|
+
## 6. Overlay contract
|
|
139
|
+
|
|
140
|
+
1. Owned filename: `annotation-overlay.svg`. The manifest `overlay.path` must
|
|
141
|
+
be exactly this value, and `overlay.format` must be `svg`.
|
|
142
|
+
2. The root element uses the source dimensions:
|
|
143
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="W" height="H" viewBox="0 0 W H">`.
|
|
144
|
+
The manifest `overlay.width` and `overlay.height` must equal the source
|
|
145
|
+
coordinate-space dimensions.
|
|
146
|
+
3. Determinism:
|
|
147
|
+
1. Output depends only on the source dimensions and the marks, rendered in
|
|
148
|
+
the persisted item order.
|
|
149
|
+
2. Style values are fixed constants.
|
|
150
|
+
3. Numbers are formatted with `String(n)`, and `-0` is written as `0`.
|
|
151
|
+
4. Lines end with `\n`.
|
|
152
|
+
5. The arrowhead is built with `Math.sqrt` vector math, not trigonometry.
|
|
153
|
+
6. Output never depends on interpretation state, item ids, timestamps,
|
|
154
|
+
random values, environment, locale, or the filesystem.
|
|
155
|
+
4. Mark mapping:
|
|
156
|
+
1. A point becomes a circle.
|
|
157
|
+
2. A rectangle becomes a rect.
|
|
158
|
+
3. A line becomes a line.
|
|
159
|
+
4. An arrow becomes a line plus a filled polygon arrowhead. A zero-length
|
|
160
|
+
arrow gets no arrowhead.
|
|
161
|
+
5. A note becomes a filled anchor circle plus a text element.
|
|
162
|
+
5. The SVG has no image, script, foreignObject, href, marker ids, CSS imports,
|
|
163
|
+
or event handlers. It never embeds the source image.
|
|
164
|
+
6. SHA-256 verification:
|
|
165
|
+
1. The service hashes the rendered UTF-8 bytes.
|
|
166
|
+
2. The writer re-renders the overlay and refuses to write if the digest
|
|
167
|
+
differs from `overlay.sha256`.
|
|
168
|
+
3. The reader hashes the bytes on disk and refuses them if the digest does
|
|
169
|
+
not match.
|
|
170
|
+
7. Text escaping: note text escapes `&`, `<`, `>`, `"`, and `'`. Characters
|
|
171
|
+
that XML 1.0 does not allow are replaced with U+FFFD in the overlay only.
|
|
172
|
+
The manifest keeps the authored text exactly as written.
|
|
173
|
+
|
|
174
|
+
## 7. Persistence contract
|
|
175
|
+
|
|
176
|
+
1. Final directory: `<outputLocation>/<annotationId>/`
|
|
177
|
+
2. Temporary directory: `<outputLocation>/.tmp-<annotationId>`
|
|
178
|
+
3. Write order:
|
|
179
|
+
1. Validate the artifact.
|
|
180
|
+
2. Render the overlay and verify its digest.
|
|
181
|
+
3. Refuse if the final directory already exists.
|
|
182
|
+
4. Remove this artifact's own stale temporary directory, if one exists.
|
|
183
|
+
5. Create the temporary directory.
|
|
184
|
+
6. Write `annotation-overlay.svg`.
|
|
185
|
+
7. Write `manifest.json`.
|
|
186
|
+
4. Atomic rename: the temporary directory is renamed to the final directory in
|
|
187
|
+
one `rename` call.
|
|
188
|
+
5. No overwrite: if the final directory already exists, the writer returns
|
|
189
|
+
`artifact-write-failure` and leaves the existing files untouched.
|
|
190
|
+
6. Failure cleanup: on any failure after the temporary directory is created,
|
|
191
|
+
the writer removes it and returns `artifact-write-failure`.
|
|
192
|
+
7. The writer never reads or copies source observation or reference bytes.
|
|
193
|
+
8. The service checks the output location with `normalizeOutputLocation`. It
|
|
194
|
+
uses `getProducerInfo()` and sets `provenance.origin` to `viewer`. It
|
|
195
|
+
writes exactly once.
|
|
196
|
+
|
|
197
|
+
## 8. Tests added
|
|
198
|
+
|
|
199
|
+
1. `tests/unit/visualAnnotationFixtures.ts` is a shared fixture helper, not a
|
|
200
|
+
test file.
|
|
201
|
+
2. `tests/unit/visualAnnotation.test.ts` covers:
|
|
202
|
+
1. The frozen constants.
|
|
203
|
+
2. A: a valid runtime artifact.
|
|
204
|
+
3. B: a valid reference artifact, both imported and approved.
|
|
205
|
+
4. An empty item list, and all five mark kinds.
|
|
206
|
+
5. C: cross-domain associations, and association shapes checked against
|
|
207
|
+
the relationship vocabularies.
|
|
208
|
+
6. D: cross-domain intents, and every intent valid in its own context.
|
|
209
|
+
7. Delegation to the canonical validators for primitives, regions,
|
|
210
|
+
requirements, category, and mode.
|
|
211
|
+
8. E: bounds for all out-of-frame and non-finite marks, freehand and
|
|
212
|
+
polygon rejection, and an edge-touching rectangle.
|
|
213
|
+
9. F: notes of 2000 characters (valid), 2001 characters (invalid), and
|
|
214
|
+
empty (invalid).
|
|
215
|
+
10. G: 100 items (valid) and 101 items (invalid).
|
|
216
|
+
11. H: duplicate and empty item ids.
|
|
217
|
+
12. I: interpretation states and malformed mixtures.
|
|
218
|
+
13. J: authored `unexpected` is rejected.
|
|
219
|
+
14. K: remove with a primitive is rejected, remove without one is accepted.
|
|
220
|
+
15. Malformed sources and artifact envelopes.
|
|
221
|
+
16. Overlay tests: root frame and item order, determinism, independence
|
|
222
|
+
from interpretation, no forbidden content, escaping of malicious text,
|
|
223
|
+
and a zero-length arrow.
|
|
224
|
+
3. `tests/unit/visualAnnotationIdentity.test.ts` covers:
|
|
225
|
+
1. The hex format of the request identity.
|
|
226
|
+
2. The same content gives the same identity.
|
|
227
|
+
3. Key insertion order does not change the identity.
|
|
228
|
+
4. Item order does change it.
|
|
229
|
+
5. Changes to the source, coordinates, association, interpretation, or
|
|
230
|
+
supersession change it.
|
|
231
|
+
6. Timestamp and output location are excluded.
|
|
232
|
+
7. Instance identity is fresh on every call.
|
|
233
|
+
4. `tests/unit/visualAnnotationArtifactWriter.test.ts` covers:
|
|
234
|
+
1. A successful write, with the exact directory name, `manifest.json`, and
|
|
235
|
+
`annotation-overlay.svg`.
|
|
236
|
+
2. Reader round trips for runtime and reference artifacts.
|
|
237
|
+
3. Refusal to overwrite an existing directory.
|
|
238
|
+
4. No source bytes copied into the annotation directory.
|
|
239
|
+
5. No temporary directory after success, including a stale one.
|
|
240
|
+
6. No temporary directory after a filesystem failure.
|
|
241
|
+
7. Refusal on an overlay SHA mismatch.
|
|
242
|
+
5. `tests/unit/visualAnnotationArtifactWriterFailure.test.ts` covers the
|
|
243
|
+
section 19 failure cases:
|
|
244
|
+
1. Case 1: an invalid artifact is refused.
|
|
245
|
+
2. Case 2: an existing final directory is left unchanged.
|
|
246
|
+
3. Case 3: the manifest write fails after the overlay write. The test
|
|
247
|
+
checks write order, that no artifact appears, and that temp is cleaned.
|
|
248
|
+
4. Case 4: the atomic rename fails.
|
|
249
|
+
5. Case 5: malformed JSON, plus a missing manifest.
|
|
250
|
+
6. Case 6: a structurally invalid artifact and an unsupported schema version.
|
|
251
|
+
7. Case 7: a missing overlay, plus an overlay path that is a directory.
|
|
252
|
+
8. Case 8: an overlay SHA mismatch.
|
|
253
|
+
9. Case 9: malicious note text is persisted as escaped SVG, and the
|
|
254
|
+
manifest text is preserved.
|
|
255
|
+
6. `tests/unit/visualAnnotationPersistence.test.ts` covers:
|
|
256
|
+
1. Runtime persistence: identity, producer, provenance, overlay metadata,
|
|
257
|
+
overlay SHA, and a reader round trip.
|
|
258
|
+
2. External-reference persistence.
|
|
259
|
+
3. Saving the same content twice gives the same request identity and a
|
|
260
|
+
fresh `annotationId`.
|
|
261
|
+
4. `supersedesAnnotationId` is carried forward, and the prior artifact's
|
|
262
|
+
bytes are unchanged.
|
|
263
|
+
5. Invalid content, an empty supersedes value, and unsafe output locations
|
|
264
|
+
are refused, and nothing is written.
|
|
265
|
+
|
|
266
|
+
The focused run passed: 5 test files and 59 tests.
|
|
267
|
+
|
|
268
|
+
## 9. Validation
|
|
269
|
+
|
|
270
|
+
Every command below was actually run on Windows in the repository root.
|
|
271
|
+
|
|
272
|
+
1. `npm run typecheck`: PASS (exit 0)
|
|
273
|
+
2. `npm run lint`: PASS (exit 0)
|
|
274
|
+
3. `npm test`: PASS (73 test files and 1239 tests passed)
|
|
275
|
+
4. `npm run build`: PASS (exit 0, TypeScript build plus viewer Vite/PWA build)
|
|
276
|
+
5. `npm run check:docs`: PASS ("Documentation check passed (17 required files).")
|
|
277
|
+
6. `npm pack --dry-run`: PASS (333 files, 856.2 kB package size). The five new
|
|
278
|
+
`dist` modules are included. No agent-control files are included.
|
|
279
|
+
|
|
280
|
+
Additional check: after the build, `node` imported `dist/index.js`. It
|
|
281
|
+
resolved all the new public functions and constants with the frozen values.
|
|
282
|
+
|
|
283
|
+
Skipped: browser tests (`npm run test:browser`) and packed clean-consumer
|
|
284
|
+
proof. Batch 1 changes no browser, viewer, CLI, or package-entry behavior, and
|
|
285
|
+
this prompt does not require them.
|
|
286
|
+
|
|
287
|
+
## 10. Scope audit
|
|
288
|
+
|
|
289
|
+
1. viewer source changed: false
|
|
290
|
+
2. viewer server changed: false
|
|
291
|
+
3. CLI changed: false
|
|
292
|
+
4. project workflow changed: false
|
|
293
|
+
5. contract primitives changed: false
|
|
294
|
+
6. external-reference schema changed: false
|
|
295
|
+
7. package version changed: false
|
|
296
|
+
|
|
297
|
+
No dependency was added or changed. No POST route, UI, CLI command, contract
|
|
298
|
+
promotion, reference materialization, or project authoring support was added.
|
|
299
|
+
|
|
300
|
+
## 11. Changed files
|
|
301
|
+
|
|
302
|
+
1. `src/domain/visualAnnotation.ts` (added)
|
|
303
|
+
2. `src/domain/visualAnnotationIdentity.ts` (added)
|
|
304
|
+
3. `src/artifacts/visualAnnotationArtifactWriter.ts` (added)
|
|
305
|
+
4. `src/artifacts/visualAnnotationArtifactReader.ts` (added)
|
|
306
|
+
5. `src/application/visualAnnotationPersistenceService.ts` (added)
|
|
307
|
+
6. `src/index.ts` (modified, exports only)
|
|
308
|
+
7. `tests/unit/visualAnnotationFixtures.ts` (added)
|
|
309
|
+
8. `tests/unit/visualAnnotation.test.ts` (added)
|
|
310
|
+
9. `tests/unit/visualAnnotationIdentity.test.ts` (added)
|
|
311
|
+
10. `tests/unit/visualAnnotationArtifactWriter.test.ts` (added)
|
|
312
|
+
11. `tests/unit/visualAnnotationArtifactWriterFailure.test.ts` (added)
|
|
313
|
+
12. `tests/unit/visualAnnotationPersistence.test.ts` (added)
|
|
314
|
+
13. `docs/reports/v0.9-batch1-visual-annotation-foundation.md` (added)
|
|
315
|
+
|
|
316
|
+
### 11.1 Additional public exports
|
|
317
|
+
|
|
318
|
+
These go beyond the minimum export list:
|
|
319
|
+
|
|
320
|
+
1. `VISUAL_ANNOTATION_OVERLAY_PATH`
|
|
321
|
+
2. `isValidVisualAnnotationContent`, the content half of the artifact
|
|
322
|
+
validator. The service uses it before deriving identity.
|
|
323
|
+
3. `VISUAL_ANNOTATION_MANIFEST_FILENAME` and `VISUAL_ANNOTATION_OVERLAY_FILENAME`
|
|
324
|
+
4. `computeVisualAnnotationOverlaySha256`, shared by the writer, reader, and
|
|
325
|
+
service.
|
|
326
|
+
5. Result and options types: `PersistedVisualAnnotationResult`,
|
|
327
|
+
`WriteVisualAnnotationArtifactOptions`, `ReadVisualAnnotationArtifactResult`,
|
|
328
|
+
`PersistVisualAnnotationOptions`, `ApplicationPersistVisualAnnotationResult`.
|
|
329
|
+
|
|
330
|
+
### 11.2 Generated paths
|
|
331
|
+
|
|
332
|
+
1. `dist/` was rebuilt by `npm run build`. It is ignored by Git.
|
|
333
|
+
2. `.my-dev-kit-workflow/adhoc/preserved-local-docs/` holds the preserved
|
|
334
|
+
local retrieval report. It is ignored by Git.
|
|
335
|
+
3. Unit tests create temporary directories with `mkdtemp` under the OS temp
|
|
336
|
+
directory, following the existing test convention. Each test removes its
|
|
337
|
+
own directories.
|
|
338
|
+
4. Validation logs were written to the session scratchpad, outside the
|
|
339
|
+
repository.
|
|
340
|
+
|
|
341
|
+
### 11.3 Remaining risks
|
|
342
|
+
|
|
343
|
+
1. The local retrieval report is hidden from Git by `skip-worktree`. A later
|
|
344
|
+
pull that changes the tracked version of that file will stop until the
|
|
345
|
+
flag is cleared.
|
|
346
|
+
2. Resolving targets and regions across artifacts, and checking revision
|
|
347
|
+
lineage, are deferred to later batches by design.
|
|
348
|
+
|
|
349
|
+
## 12. Remaining next step
|
|
350
|
+
|
|
351
|
+
v0.9 Prompt 2 — Viewer discovery, project authoring boundary, and secure POST API
|