@dailephd/my-frontend-observer 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +107 -7
  3. package/dist/application/projectWorkflowService.d.ts +18 -1
  4. package/dist/application/projectWorkflowService.js +40 -2
  5. package/dist/application/projectWorkflowService.js.map +1 -1
  6. package/dist/application/visualAnnotationContractPromotionService.d.ts +41 -0
  7. package/dist/application/visualAnnotationContractPromotionService.js +143 -0
  8. package/dist/application/visualAnnotationContractPromotionService.js.map +1 -0
  9. package/dist/application/visualAnnotationPersistenceService.d.ts +34 -0
  10. package/dist/application/visualAnnotationPersistenceService.js +68 -0
  11. package/dist/application/visualAnnotationPersistenceService.js.map +1 -0
  12. package/dist/application/visualAnnotationReferenceMaterializationService.d.ts +53 -0
  13. package/dist/application/visualAnnotationReferenceMaterializationService.js +194 -0
  14. package/dist/application/visualAnnotationReferenceMaterializationService.js.map +1 -0
  15. package/dist/artifacts/visualAnnotationArtifactReader.d.ts +19 -0
  16. package/dist/artifacts/visualAnnotationArtifactReader.js +66 -0
  17. package/dist/artifacts/visualAnnotationArtifactReader.js.map +1 -0
  18. package/dist/artifacts/visualAnnotationArtifactWriter.d.ts +42 -0
  19. package/dist/artifacts/visualAnnotationArtifactWriter.js +85 -0
  20. package/dist/artifacts/visualAnnotationArtifactWriter.js.map +1 -0
  21. package/dist/cli.js +464 -454
  22. package/dist/cli.js.map +1 -1
  23. package/dist/domain/visualAnnotation.d.ts +217 -0
  24. package/dist/domain/visualAnnotation.js +584 -0
  25. package/dist/domain/visualAnnotation.js.map +1 -0
  26. package/dist/domain/visualAnnotationIdentity.d.ts +17 -0
  27. package/dist/domain/visualAnnotationIdentity.js +47 -0
  28. package/dist/domain/visualAnnotationIdentity.js.map +1 -0
  29. package/dist/index.d.ts +11 -0
  30. package/dist/index.js +6 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/projectWorkflow/projectPaths.d.ts +9 -0
  33. package/dist/projectWorkflow/projectPaths.js +21 -0
  34. package/dist/projectWorkflow/projectPaths.js.map +1 -1
  35. package/dist/viewer/assets/{index-CN_yb9Uf.css → index-BN41MI7m.css} +1 -1
  36. package/dist/viewer/assets/index-CkKXnlrI.js +9 -0
  37. package/dist/viewer/index.html +2 -2
  38. package/dist/viewer/sw.js +1 -1
  39. package/dist/viewerServer/annotationAuthoring.d.ts +64 -0
  40. package/dist/viewerServer/annotationAuthoring.js +230 -0
  41. package/dist/viewerServer/annotationAuthoring.js.map +1 -0
  42. package/dist/viewerServer/annotationContractPromotion.d.ts +51 -0
  43. package/dist/viewerServer/annotationContractPromotion.js +105 -0
  44. package/dist/viewerServer/annotationContractPromotion.js.map +1 -0
  45. package/dist/viewerServer/annotationReferenceMaterialization.d.ts +40 -0
  46. package/dist/viewerServer/annotationReferenceMaterialization.js +91 -0
  47. package/dist/viewerServer/annotationReferenceMaterialization.js.map +1 -0
  48. package/dist/viewerServer/authoringSecurity.d.ts +59 -0
  49. package/dist/viewerServer/authoringSecurity.js +112 -0
  50. package/dist/viewerServer/authoringSecurity.js.map +1 -0
  51. package/dist/viewerServer/evidence/annotationView.d.ts +28 -0
  52. package/dist/viewerServer/evidence/annotationView.js +43 -0
  53. package/dist/viewerServer/evidence/annotationView.js.map +1 -0
  54. package/dist/viewerServer/evidence/classify.d.ts +3 -1
  55. package/dist/viewerServer/evidence/classify.js +12 -0
  56. package/dist/viewerServer/evidence/classify.js.map +1 -1
  57. package/dist/viewerServer/evidence/discovery.d.ts +2 -0
  58. package/dist/viewerServer/evidence/discovery.js +6 -0
  59. package/dist/viewerServer/evidence/discovery.js.map +1 -1
  60. package/dist/viewerServer/evidence/handles.js +1 -0
  61. package/dist/viewerServer/evidence/handles.js.map +1 -1
  62. package/dist/viewerServer/evidence/index.d.ts +29 -0
  63. package/dist/viewerServer/evidence/index.js +43 -1
  64. package/dist/viewerServer/evidence/index.js.map +1 -1
  65. package/dist/viewerServer/evidence/mediaResolver.d.ts +1 -1
  66. package/dist/viewerServer/evidence/mediaResolver.js +28 -2
  67. package/dist/viewerServer/evidence/mediaResolver.js.map +1 -1
  68. package/dist/viewerServer/evidence/projection.d.ts +5 -1
  69. package/dist/viewerServer/evidence/projection.js +19 -0
  70. package/dist/viewerServer/evidence/projection.js.map +1 -1
  71. package/dist/viewerServer/httpServer.d.ts +13 -2
  72. package/dist/viewerServer/httpServer.js +278 -4
  73. package/dist/viewerServer/httpServer.js.map +1 -1
  74. package/dist/viewerServer/viewerService.d.ts +8 -0
  75. package/dist/viewerServer/viewerService.js +38 -2
  76. package/dist/viewerServer/viewerService.js.map +1 -1
  77. package/docs/ARCHITECTURE.md +108 -21
  78. package/docs/CI_CD.md +57 -1
  79. package/docs/COMMANDS.md +44 -4
  80. package/docs/CONTRACTS.md +78 -8
  81. package/docs/CURRENT_STATE.md +157 -35
  82. package/docs/DEVELOPMENT.md +8 -3
  83. package/docs/PROJECT_DESCRIPTION.md +4 -1
  84. package/docs/PROJECT_MILESTONES.md +4 -0
  85. package/docs/PROJECT_OVERVIEW.md +41 -17
  86. package/docs/QUICKSTART.md +52 -39
  87. package/docs/RELEASE.md +16 -11
  88. package/docs/ROADMAP.md +406 -66
  89. package/docs/SECURITY.md +71 -14
  90. package/docs/WORKFLOWS.md +151 -23
  91. package/docs/plans/v0.9-implementation-plan.md +1529 -0
  92. package/docs/reports/v0.9-architecture-retrieval.md +567 -0
  93. package/docs/reports/v0.9-batch1-visual-annotation-foundation.md +351 -0
  94. package/docs/reports/v0.9-batch2-viewer-annotation-authoring-boundary.md +438 -0
  95. package/docs/reports/v0.9-batch3-runtime-screenshot-annotation-authoring.md +412 -0
  96. package/docs/reports/v0.9-batch4-external-reference-annotation-authoring.md +452 -0
  97. package/docs/reports/v0.9-batch5-runtime-intent-contract-promotion.md +535 -0
  98. package/docs/reports/v0.9-batch6-reference-materialization.md +514 -0
  99. package/docs/reports/v0.9-batch7-integrated-acceptance.md +644 -0
  100. package/docs/reports/v0.9-demo-foundation.md +589 -0
  101. package/docs/reports/v0.9-final-pre-release-readiness.md +209 -0
  102. package/docs/reports/v0.9-final-readiness-corrections.md +530 -0
  103. package/docs/reports/v0.9-pre-release-readiness.md +170 -0
  104. package/docs/reports/v0.9-tutorial-end-to-end-acceptance.md +980 -0
  105. package/docs/reports/v0.9-tutorial-integration.md +731 -0
  106. package/package.json +2 -2
  107. package/dist/viewer/assets/index-D98S1_2d.js +0 -9
@@ -0,0 +1,567 @@
1
+ # v0.9 Architecture Retrieval
2
+
3
+ ## 1. VERDICT
4
+
5
+ `PASS_V0_9_ARCHITECTURE_RETRIEVAL_COMPLETE`
6
+
7
+ This is a current-source inspection report for planning only. It does not select
8
+ or recommend a v0.9 architecture.
9
+
10
+ ## 2. Repository identity
11
+
12
+ - Repository: `C:\Users\daile\Projects\my-frontend-observer` (the working copy
13
+ available in this environment; repository instructions identify the logical
14
+ repository as `Z:\Users\newuser\Projects\my-frontend-observer`).
15
+ - Branch: `master`.
16
+ - HEAD: `473713d240af09e752eeb8e00735738c4927b16d`.
17
+ - Package version: `0.8.1`.
18
+ - Preflight worktree: clean. The initial `git status --short` produced no
19
+ entries.
20
+ - No commit, push, reset, checkout, stash, or clean operation was performed.
21
+
22
+ ## 3. my-dev-kit retrieval evidence
23
+
24
+ ### Index
25
+
26
+ - Existing same-repository/version indexes found before indexing: none under
27
+ `.my-dev-kit-context/indexes/`.
28
+ - Removed or replaced older indexes: none.
29
+ - Installed/published command version: `@dailephd/my-dev-kit 1.12.3`.
30
+ - Fresh index path:
31
+ `.my-dev-kit-context/indexes/my-frontend-observer-v0.8.1-20260916T202252`.
32
+ - The CLI contract supports repeated `--src`; one invocation covered both
33
+ production roots:
34
+
35
+ ```text
36
+ npx --yes @dailephd/my-dev-kit index --root . --src src --src viewer --out .my-dev-kit-context/indexes/my-frontend-observer-v0.8.1-20260916T202252 --json
37
+ ```
38
+
39
+ - Index result: 126 TypeScript files, 1,170 symbols, 2,168 edges; syntax,
40
+ frontend semantic, and frontend reachability artifacts completed without
41
+ errors. Data-model and classification analyzers reported warnings but did
42
+ not prevent the index from being produced.
43
+
44
+ ### Retrieval commands and selected nodes
45
+
46
+ - Retrieval help commands used:
47
+ `npx --yes @dailephd/my-dev-kit search --help`, `lookup --help`,
48
+ `slice --help`, and `source --help`.
49
+ - Search commands, all against the fresh index, were:
50
+ `search --query artifactWriter`, `ExternalReferenceArtifact`,
51
+ `FrontendContractEvaluationArtifact`, `projectBoundedAgentContext`,
52
+ `TargetOverlaySvg`, `ReferenceRegionOverlaySvg`, `ReferenceWorkspace`,
53
+ `useZoomPan`, `deriveCoordinateScale`, `ReferenceRegion`,
54
+ `AuthoredChangeScopeCategory`, and `projectWorkflow`, each with
55
+ `--limit 10 --json`.
56
+ - Selected search node IDs included:
57
+ - `symbol:src/domain/frontendContractEvaluationArtifact.ts#FrontendContractEvaluationArtifact`
58
+ - `symbol:src/domain/externalReferenceRegions.ts#ReferenceRegion`
59
+ - `symbol:src/domain/frontendContracts.ts#AuthoredChangeScopeCategory`
60
+ - `symbol:src/artifacts/externalReferenceArtifactWriter.ts#writeExternalReferenceArtifact`
61
+ - `symbol:viewer/src/components/TargetOverlaySvg.tsx#TargetOverlaySvg`
62
+ - `symbol:viewer/src/components/ReferenceRegionOverlaySvg.tsx#ReferenceRegionOverlaySvg`
63
+ - `symbol:viewer/src/hooks/useZoomPan.ts#useZoomPan`
64
+ - `symbol:src/viewerServer/viewerService.ts#startViewer`
65
+ - `symbol:src/projectWorkflow/aliasCatalog.ts#AliasCatalog`
66
+ - `symbol:src/domain/boundedAgentContextProjection.ts#projectBoundedAgentContext`
67
+ - Lookup commands used for the writer, viewer startup, both SVG components,
68
+ and `ReferenceRegion`, with `--depth 2 --json`.
69
+ - Slice commands used for the external-reference writer, viewer startup, and
70
+ reference overlay, with `--depth 2 --direction both --json`; the overlay
71
+ slice also used `--include-event-handlers`.
72
+ - Source commands retrieved exact symbols/ranges for the artifact domain,
73
+ external-reference writer, viewer startup, both workspaces and overlays,
74
+ zoom/pan, contract vocabulary, alias catalog, and evidence discovery.
75
+ Three attempted source node names did not exist (`writeArtifact`,
76
+ `persistExternalReference`, `ProjectConfig`, and `discoverEvidence` in the
77
+ attempted symbol spelling); the owning exported symbols were then inspected
78
+ by bounded file/range retrieval.
79
+ - Exact source command form was:
80
+ `npx --yes @dailephd/my-dev-kit source --index <index> --node <selected-node> --include-local-deps --max-bundle-lines <bound> --format plain`.
81
+ - Whole-file fallback count for production or test source: `0`. Bounded
82
+ retrieval and line-ranged source inspection answered the questions. The full
83
+ `agents.txt` read was repository operating-instruction reading, not a
84
+ production/test fallback.
85
+
86
+ ## 4. Existing artifact-family architecture
87
+
88
+ ### Domain and validation owners
89
+
90
+ - Observation domain/schema: `src/domain/schema.ts`; `ObservationArtifact`,
91
+ `isValidObservationArtifact`, `ARTIFACT_KIND`, and `SCHEMA_VERSION`.
92
+ - Observation identity: `src/domain/identity.ts#buildRequestIdentity` is
93
+ deterministic SHA-256 over semantic request configuration; output location,
94
+ timeout, timestamps, and runtime results are excluded. Fresh instance
95
+ identity is `buildObservationIdentity`.
96
+ - Comparison domain/engine/identity: `src/domain/comparison.ts`,
97
+ `src/domain/comparisonEngine.ts`, and `src/domain/comparisonIdentity.ts`.
98
+ Comparison persistence is `src/artifacts/comparisonArtifactWriter.ts` and
99
+ `comparisonArtifactReader.ts`.
100
+ - Frontend baseline/per-change contracts: `src/domain/frontendContracts.ts`.
101
+ It owns `PersistentBaselineContract`, `PerChangeContract`, primitive and
102
+ clause representations, structural validators, and the shared contract kind
103
+ and schema version.
104
+ - Contract identity: `src/domain/frontendContractIdentity.ts` owns
105
+ `buildFrontendContractRequestIdentity`, fresh
106
+ `buildFrontendContractInstanceIdentity`, clause identity, and evaluation
107
+ request identity.
108
+ - Contract evaluation artifact: `src/domain/frontendContractEvaluationArtifact.ts`
109
+ owns `FrontendContractEvaluationArtifact`, its schema/kind, builder, and
110
+ structural validator. The artifact references baseline/contract, before/after
111
+ observations, comparison request identity, verdict, clause results, and
112
+ unexpected changes.
113
+ - External reference domain: `src/domain/externalReference.ts`, with identity
114
+ in `src/domain/externalReferenceIdentity.ts`. `ExternalReferenceArtifact` is
115
+ the imported/approved lifecycle union. Request identity includes image
116
+ content/dimensions, supersession, and supplied regions/requirements/
117
+ applicability; instance identity adds fresh random bytes.
118
+
119
+ ### Readers, writers, application seams, CLI, and exports
120
+
121
+ - Observation writer/reader: `src/artifacts/artifactWriter.ts#writeObservationArtifact`
122
+ and `src/artifacts/artifactReader.ts#readObservationArtifact`; the writer
123
+ persists `manifest.json` and `screenshot.png`.
124
+ - Comparison writer/reader: `src/artifacts/comparisonArtifactWriter.ts#writeComparisonArtifact`
125
+ and `src/artifacts/comparisonArtifactReader.ts#readComparisonArtifact`.
126
+ - Contract writer/reader: `src/artifacts/frontendContractArtifactWriter.ts#writePersistentBaselineContract`,
127
+ `writePerChangeContract`, `frontendContractArtifactReader.ts#readPersistentBaselineContract`,
128
+ and `readPerChangeContract`.
129
+ - Evaluation writer/reader:
130
+ `src/artifacts/frontendContractEvaluationArtifactWriter.ts#writeFrontendContractEvaluationArtifact`
131
+ and `frontendContractEvaluationArtifactReader.ts#readFrontendContractEvaluationArtifact`.
132
+ - External reference writer/reader:
133
+ `src/artifacts/externalReferenceArtifactWriter.ts#writeExternalReferenceArtifact`
134
+ and `externalReferenceArtifactReader.ts#readExternalReferenceArtifact`.
135
+ - Application persistence seams:
136
+ `src/application/observationPersistence.ts`, `comparisonService.ts`,
137
+ `frontendContractPersistenceService.ts`,
138
+ `frontendContractEvaluationService.ts`, and
139
+ `externalReferencePersistenceService.ts`. The latter is the canonical
140
+ `importExternalReference`/approval use case and calls the identity, domain
141
+ validation, reader, and writer owners.
142
+ - CLI integration and dispatch are in `src/cli.ts`. The current commands
143
+ include `observe`, `compare`, `approve-baseline`, `save-change-contract`,
144
+ `evaluate-contract`, `import-reference`, `approve-reference`,
145
+ `evaluate-reference-fidelity`, plus project `init`, `capture`, `check`, and
146
+ `view`.
147
+ - Public library exports are in `src/index.ts`. The current file exports domain
148
+ types/validators/builders and contract/reference artifact readers/writers;
149
+ it is the public export boundary rather than an implementation layer.
150
+
151
+ ### Persistence pattern
152
+
153
+ All established artifact writers validate before writing, derive a final
154
+ directory from the fresh instance ID, refuse an existing final directory, write
155
+ to a sibling `.tmp-<id>` directory, write `manifest.json` (and observation
156
+ media where owned), then atomically rename the temporary directory. On failure,
157
+ the temporary directory is removed. Readers parse and structurally validate the
158
+ manifest; they do not silently coerce unsupported versions.
159
+
160
+ ### Tests
161
+
162
+ - `tests/unit/artifactWriter.test.ts` suite `artifactWriter` protects complete
163
+ observation roots, required media, round trips, and no-overwrite behavior.
164
+ - `tests/unit/artifactWriterFailure.test.ts` protects invalid input and
165
+ filesystem failure handling.
166
+ - `tests/browser/artifactPersistence.test.ts` protects real-browser/CLI
167
+ persistence paths.
168
+ - `tests/unit/comparisonIdentity.test.ts`, `comparisonPersistence.test.ts`,
169
+ `comparisonArtifactWriterFailure.test.ts`, and
170
+ `tests/unit/frontendContractIdentity.test.ts` protect deterministic identity,
171
+ fresh instance IDs, persistence, and failure behavior.
172
+ - `tests/unit/frontendContracts.test.ts`, `frontendContractPersistence.test.ts`,
173
+ `frontendContractEvaluation.test.ts`, and `frontendContractEvaluationArtifact.test.ts`
174
+ protect structural clauses, persistence service behavior, evaluation, and
175
+ artifact validation.
176
+ - `tests/unit/externalReferenceIdentity.test.ts`,
177
+ `externalReferenceArtifactWriter.test.ts`,
178
+ `externalReferencePersistence.test.ts`, and
179
+ `tests/browser/referenceCorrectionWorkflow.test.ts` protect reference
180
+ identity, writer/reader behavior, import/approval/supersession, and the
181
+ real workflow.
182
+
183
+ An annotation artifact is not assumed here. The existing extension options are
184
+ to reuse an existing family only if its domain contract actually fits, or add a
185
+ new family following the same domain-validator/identity-reader-writer/
186
+ application/CLI/export/test pattern.
187
+
188
+ ## 5. Existing viewer-server architecture
189
+
190
+ - Startup/application seam: `src/viewerServer/viewerService.ts#startViewer`.
191
+ It validates the root, selects built assets via `defaultViewerAssetsRoot`,
192
+ passes session-only bindings/context/alias metadata into
193
+ `createViewerServer`, and listens only on `127.0.0.1` using
194
+ `src/viewerServer/port.ts`.
195
+ - HTTP routing: `src/viewerServer/httpServer.ts#handleRequest`.
196
+ Only `GET` and `HEAD` are accepted; other methods receive `405` and
197
+ `Allow: GET, HEAD`. The server serves status/index/artifact/media APIs,
198
+ relationship, comparison, evaluation, reference, candidate, binding, and
199
+ fidelity/context routes, plus the static viewer shell.
200
+ - Evidence discovery/indexing: `src/viewerServer/evidence/discovery.ts#discoverManifests`
201
+ finds bounded `manifest.json` files; `evidence/index.ts#buildEvidenceIndexMetadata`
202
+ rebuilds metadata on every request, limits records, classifies, and projects
203
+ metadata. `loadArtifactByHandle` performs on-demand full loading and
204
+ revalidation.
205
+ - Classification: `src/viewerServer/evidence/classify.ts#classifyManifest`.
206
+ Supported families are observation, comparison, baseline contract, change
207
+ contract, contract evaluation, imported external reference, and approved
208
+ external reference. It dispatches to the canonical reader for each family;
209
+ the reader remains the structural authority. New persisted families are not
210
+ discovered automatically: classification requires an explicit kind/version
211
+ branch, reader, and family projection.
212
+ - Handles and containment: `evidence/handles.ts` creates/decodes opaque
213
+ evidence-relative handles; `evidence/pathSafety.ts#resolveContainedDir` and
214
+ `resolveContainedFile` fail closed on traversal, separators, NULs, and
215
+ absolute escape. `mediaResolver.ts#resolveMedia` restricts roles and uses
216
+ `lstat` to reject non-regular files and symlink-like escapes.
217
+ - Media resolution: `evidence/mediaResolver.ts#resolveMedia` resolves
218
+ observation `screenshot`, imported-reference `image`, and approved-reference
219
+ `source-image`. Approved source image resolution uses the canonical logical
220
+ `referenceId` to rediscover the imported artifact; it does not treat a stored
221
+ path as provenance.
222
+ - Observation relationship route: `httpServer.ts` dispatches
223
+ `/api/observations/:handle/relationships` to
224
+ `evidence/observationView.ts#getObservationRelationships`, which invokes the
225
+ canonical relationship derivation once for the selected observation.
226
+ - Comparison/evaluation routes: `/api/comparisons/:handle/view` and
227
+ `/api/evaluations/:handle/view` dispatch to `comparisonView.ts` and
228
+ `evaluationView.ts`. They resolve canonical artifacts and linked evidence;
229
+ they do not recompute comparison or contract evaluation in the browser.
230
+ - Reference route: `/api/references/:handle/view` dispatches to
231
+ `referenceView.ts#getReferenceView`, which invokes exactly the canonical
232
+ `deriveReferenceRegionRelationships` and
233
+ `deriveReferenceRequirementAdequacy` functions over persisted regions and
234
+ requirements. These results are ephemeral projections, not persisted.
235
+ - Candidate route: `/api/references/:reference/candidate/:candidate/view`
236
+ invokes canonical compatibility and coordinate/fidelity support in
237
+ `referenceView.ts`; it also discovers referenced evaluation handles.
238
+ - Binding route: `/api/references/:reference/candidate/:candidate/bindings`
239
+ invokes `isValidReferenceRuntimeBindingDeclarations` and
240
+ `evaluateReferenceRuntimeBindings` using startup-supplied session input.
241
+ - Fidelity route: `/api/references/:reference/candidate/:candidate/fidelity`
242
+ invokes `getReferenceFidelity`, which uses the canonical
243
+ `deriveCoordinateScale` and `evaluateReferenceCandidateFidelity` path.
244
+ - Context route: `src/viewerServer/context.ts` classifies a supplied
245
+ bounded-agent-context artifact at startup; the viewer does not rebuild it.
246
+
247
+ The one-canonical-engine rule is visible in these server call sites: the
248
+ viewer server may resolve, call, and project supplied evidence, but it is not a
249
+ second relationship, compatibility, binding, fidelity, bounded-context, or
250
+ runtime/static-correlation engine. Viewer routes are read-only and session
251
+ bindings/context are not persisted.
252
+
253
+ Closest server tests are `tests/unit/viewerServer.test.ts`,
254
+ `viewerEvidenceServer.test.ts`, `referenceViewerServer.test.ts`,
255
+ `contextViewerServer.test.ts`, `paths.test.ts`, and `evidenceDiscovery.test.ts`.
256
+
257
+ ## 6. Runtime screenshot coordinate architecture
258
+
259
+ - `viewer/src/components/ObservationWorkspace.tsx#ObservationWorkspace` owns
260
+ presentation selection (`selected`), overlay toggles, ordered targets, the
261
+ screenshot media URL, and the relationship hook. Selection resets when the
262
+ artifact handle changes.
263
+ - `viewer/src/observation/targetOrder.ts#orderedTargets` owns deterministic
264
+ target ordering.
265
+ - `viewer/src/components/TargetOverlaySvg.tsx#TargetOverlaySvg` renders the
266
+ screenshot and target geometry. Its `viewBox` is
267
+ `0 0 requestConfig.viewport.width requestConfig.viewport.height`; the
268
+ viewport is the captured CSS-pixel frame. The `<image>` fills that frame and
269
+ target `geometry.x/y/width/height` is used unchanged.
270
+ - No `devicePixelRatio` multiplication, rounding, or clamping is performed.
271
+ Out-of-frame geometry remains evidence and is only clipped by SVG display
272
+ overflow. Missing/partial geometry does not receive a fabricated rectangle.
273
+ - Selection and highlighting are UI-only props: `selected` drives
274
+ `aria-pressed` and the selected class; optional `highlightNames` is a visual
275
+ secondary emphasis. Click and Enter/Space keyboard handlers call `onSelect`.
276
+ - `viewer/src/hooks/useZoomPan.ts#useZoomPan` owns presentation zoom/pan. It
277
+ uses scale `1..8`, step `1.25`, derives viewBox from frame dimensions and
278
+ focal point, resets uncontrolled state on frame changes, and maps pointer
279
+ coordinates with `getScreenCTM().inverse()`. Pan begins only after a 3-screen-
280
+ pixel drag threshold; focal points clamp to the frame. `ZoomPanBinding` is a
281
+ rendering-only subset passed to the SVG leaf.
282
+
283
+ Closest protection is `tests/browser/observationSvgWorkspace.test.ts`, covering
284
+ screenshot/media loading, exact rectangles, unresolved targets, selection in
285
+ both directions, relationship connectors, and aspect-ratio/viewBox alignment.
286
+ Zoom/pan coverage is in `tests/browser/observationComparison.test.ts`,
287
+ `referenceCandidateWorkspace.test.ts`, and the focused viewer workspace
288
+ suites; the hook’s direct unit coverage is in the corresponding viewer hook
289
+ test locations where present.
290
+
291
+ ## 7. External-reference coordinate architecture
292
+
293
+ - `src/domain/externalReferenceRegions.ts#ReferenceRegion` is the canonical
294
+ authored region: `{id, rectangle:{x,y,width,height}}`.
295
+ - Reference coordinates are reference-image pixels, origin at the image
296
+ top-left, with fractional values permitted. They are never CSS pixels.
297
+ `isValidReferenceRegionRectangle` rejects non-finite, negative, or nonpositive
298
+ values; `isValidReferenceRegions` bounds count, deduplicates IDs
299
+ case-insensitively, and rejects rectangles outside image dimensions. Derived
300
+ right/bottom/centers are recomputed, not persisted.
301
+ - `viewer/src/components/ReferenceWorkspace.tsx#ReferenceWorkspace` owns
302
+ selected region, candidate handle/target selection, overlay toggles,
303
+ optional evaluation selection, explicit binding highlights, and view lock.
304
+ It resets presentation state when the reference handle changes.
305
+ - `viewer/src/components/ReferenceRegionOverlaySvg.tsx#ReferenceRegionOverlaySvg`
306
+ uses `viewBox="0 0 imageWidth imageHeight"`, renders the reference image at
307
+ those dimensions, and renders `region.rectangle` unchanged. Its IDs are
308
+ `data-region-id` values and are not runtime target names.
309
+ - The reference overlay has separate `requirementRegionIds` and
310
+ `highlightRegionIds` presentation props. A bound cross-selection highlights
311
+ the other domain without changing that domain’s primary interactive
312
+ selection.
313
+ - Reference and runtime views share the `useZoomPan` interaction machinery,
314
+ but each supplies its own frame dimensions and SVG coordinate domain.
315
+ `deriveCoordinateScale` in `src/domain/externalReferenceFidelity.ts` is the
316
+ canonical cross-domain mapping used by fidelity evaluation; it is not a
317
+ reason to merge region identity with target identity.
318
+
319
+ Closest tests are `tests/browser/referenceCandidateWorkspace.test.ts`,
320
+ `referenceBindingFidelityWorkspace.test.ts`, `referenceCorrectionWorkflow.test.ts`,
321
+ and `tests/unit/referenceViewerServer.test.ts`. They protect image/region
322
+ selection, explicit binding cross-highlighting, no implicit equal-name binding,
323
+ zoom/pan/view lock, and server-side canonical derivation.
324
+
325
+ ## 8. Reference-region / requirement / binding / fidelity architecture
326
+
327
+ - Regions are explicit user/configuration input carried in imported and approved
328
+ external-reference artifacts. Rectangle geometry is persisted; derived
329
+ geometry and region relationships are not.
330
+ - Region relationships are derived by
331
+ `src/domain/externalReferenceRegionRelationships.ts#deriveReferenceRegionRelationships`.
332
+ - Requirements are explicit design intent over regions. Their domain is
333
+ `src/domain/externalReferenceRequirements.ts`; requirement identity is in
334
+ `externalReferenceRequirementIdentity.ts`, and adequacy is derived by
335
+ `deriveReferenceRequirementAdequacy`. Requirement categories reuse
336
+ `AuthoredChangeScopeCategory`; `unexpected` cannot be authored.
337
+ - Applicability is explicit external-reference input owned by
338
+ `src/domain/externalReferenceApplicability.ts` and participates in reference
339
+ identity. It is not inferred by the viewer.
340
+ - Bindings are session/configuration input owned by
341
+ `src/domain/externalReferenceRuntimeBinding.ts`. The viewer startup receives
342
+ declarations, validates/evaluates them per selected pair, and does not
343
+ persist them. Binding identity is therefore not an artifact identity.
344
+ - Compatibility is derived by `externalReferenceCompatibility.ts`.
345
+ - Coordinate scale and fidelity are derived by
346
+ `externalReferenceFidelity.ts`; fidelity is not the same as compatibility,
347
+ adequacy, or binding status.
348
+ - Imported and approved reference artifacts are persisted; region relationships,
349
+ adequacy, compatibility, binding evaluation, coordinate mapping, and fidelity
350
+ are derived on demand or evaluation-artifact output, depending on workflow.
351
+ - `externalReferencePersistenceService.ts` validates and persists authored
352
+ regions/requirements/applicability as part of import/approval. Approval carries
353
+ these fields forward from imported evidence; it does not mutate the prior
354
+ artifact.
355
+
356
+ ## 9. Existing contract/change-scope architecture
357
+
358
+ - Owner: `src/domain/frontendContracts.ts`.
359
+ - Authored categories are exactly `requested`, `expected-dependent`, `protected`,
360
+ and `preserved`; `unexpected` is only a derived evaluator classification.
361
+ - Contract primitives are a closed vocabulary in `CONTRACT_PRIMITIVE_KINDS`.
362
+ Clauses carry primitive-specific subjects and optional bounded tolerances.
363
+ - `PersistentBaselineContract` and `PerChangeContract` share the artifact kind
364
+ and schema but are structurally distinct and are selected by their
365
+ `contractClass`/validator shape.
366
+ - Baseline approval is owned by
367
+ `src/application/frontendContractPersistenceService.ts#approveAndPersistBaseline`.
368
+ Per-change persistence is `persistPerChangeContract`. Both validate with the
369
+ domain validator and delegate to the artifact writer; no viewer operation
370
+ constructs or approves contracts.
371
+ - Evaluation is owned by
372
+ `src/application/frontendContractEvaluationService.ts` and the canonical
373
+ domain evaluator. The evaluation artifact persists clause results and
374
+ unexpected changes, but a failure verdict is a valid artifact, not a write
375
+ failure.
376
+ - Viewer display is projection/UI only: `src/viewerServer/evidence/evaluationView.ts`,
377
+ `viewer/src/components/EvaluationWorkspace.tsx`, and clause-target helpers.
378
+ - There is no existing public function that turns arbitrary annotation input
379
+ into a confirmed contract intent. The existing public service accepts already
380
+ structured/authored baseline or per-change contracts and deliberately keeps
381
+ approval separate from observation, comparison, and evaluation.
382
+
383
+ ## 10. v0.8.1 project/alias architecture
384
+
385
+ - Project configuration: `src/projectWorkflow/projectConfig.ts` owns
386
+ `frontend-observer.json`, schema versions `1.0.0`/`1.1.0`, project targets,
387
+ default baseline, and optional acceptance paths. It delegates target/request
388
+ validation to `normalizeRequest` and rejects non-portable or escaping paths.
389
+ - Project discovery: `src/projectWorkflow/projectDiscovery.ts` discovers the
390
+ nearest project config; `src/application/projectWorkflowService.ts` owns
391
+ initialization, named capture, replacement, and viewer state loading.
392
+ - Managed paths: `src/projectWorkflow/projectPaths.ts` derives
393
+ `.frontend-observer/catalog.json`, `.frontend-observer/evidence`, and
394
+ `.frontend-observer/evidence/observations` from one project root.
395
+ - Alias catalog: `src/projectWorkflow/aliasCatalog.ts` stores schema `1.0.0`
396
+ records containing alias, canonical `observationId`, canonical `requestId`,
397
+ and `relativeArtifactDir`. It is atomically written and validated for safe
398
+ relative directories.
399
+ - Aliases are selectors, not persisted artifact identities. The canonical
400
+ observation directory and its `observationId` remain authoritative. Replacement
401
+ creates a fresh observation instance and leaves the prior directory intact;
402
+ the catalog changes which current artifact the alias selects.
403
+ - Viewer startup receives ephemeral
404
+ `ViewerAliasMetadata`; `buildEvidenceIndexMetadata` attaches an alias only to
405
+ the matching observation relative directory. Artifact handles and logical IDs
406
+ remain canonical.
407
+ - `view` discovers project evidence when `--root` is omitted. `init`, `capture`,
408
+ and `check` dispatch through `src/cli.ts` to application/project workflow
409
+ owners rather than embedding persistence semantics.
410
+ - A future artifact could be placed under the project evidence root only by
411
+ using a canonical artifact-relative directory and identity; the alias catalog
412
+ must not be used as provenance. The current evidence classifier does not
413
+ accept arbitrary new persisted families without explicit classification and
414
+ reader branches.
415
+
416
+ ## 11. Persistence/lifecycle precedents
417
+
418
+ - Observation, comparison, contract, evaluation, and external-reference writers
419
+ use immutable per-instance directories, sibling temporary directories, atomic
420
+ rename, no-overwrite checks, and cleanup on failure.
421
+ - Request/logical identity is deterministic from canonical semantic content;
422
+ instance identity is fresh and opaque. Timestamps are not used as the sole
423
+ instance identity.
424
+ - External reference import and approval support an explicit `supersedes`
425
+ reference. `externalReferencePersistenceService.ts` reads the superseded
426
+ artifact to resolve its logical ID, while the writer writes a new artifact.
427
+ - Contract baseline approval preserves an authored `supersedesBaselineId` and
428
+ never mutates or removes the prior baseline. Evaluation preserves source
429
+ references and creates a fresh `evaluationId`.
430
+ - Alias replacement updates the alias catalog only; previous canonical artifact
431
+ directories remain unchanged.
432
+ - There is no current forward-pointer mutation in artifact manifests beyond
433
+ explicit supersession/reference fields, and no writer silently replaces prior
434
+ evidence.
435
+
436
+ ## 12. Closest test architecture
437
+
438
+ - A. Structural validation: `tests/unit/schema.test.ts`,
439
+ `comparison.test.ts`, `frontendContracts.test.ts`,
440
+ `externalReference.test.ts`, and `frontendContractEvaluationArtifact.test.ts`.
441
+ Protect required fields, versions, closed vocabularies, geometry, and
442
+ lifecycle validation.
443
+ - B. Identity determinism: `tests/unit/identity.test.ts`,
444
+ `comparisonIdentity.test.ts`, `frontendContractIdentity.test.ts`, and
445
+ `externalReferenceIdentity.test.ts`. Protect semantic hashing, array order,
446
+ exclusion of paths/timestamps, and fresh instance IDs.
447
+ - C. Writer/reader round trip: `tests/unit/artifactWriter.test.ts`,
448
+ `comparisonPersistence.test.ts`, `frontendContractPersistence.test.ts`,
449
+ `externalReferencePersistence.test.ts`, and
450
+ `tests/browser/artifactPersistence.test.ts`.
451
+ - D. Application persistence service: `tests/unit/observationPersistence.test.ts`,
452
+ `comparisonPersistence.test.ts`, `frontendContractPersistence.test.ts`, and
453
+ `externalReferencePersistence.test.ts`.
454
+ - E. CLI parsing/orchestration: `tests/unit/cli.test.ts`,
455
+ `cliFrontendContracts.test.ts`, `cliExternalReference.test.ts`,
456
+ `cliEvaluateReferenceFidelity.test.ts`, and `cliProjectWorkflow.test.ts`.
457
+ - F. Viewer discovery/classification: `tests/unit/evidenceDiscovery.test.ts`.
458
+ Protect deterministic manifest discovery, family classification, honest
459
+ malformed/unsupported states, metadata-only indexing, and no arbitrary-file
460
+ inclusion.
461
+ - G. Path containment: `tests/unit/paths.test.ts`,
462
+ `tests/unit/viewerEvidenceServer.test.ts`, and `tests/unit/policy.test.ts`.
463
+ Protect portable paths, root containment, symlink handling, and method/error
464
+ boundaries.
465
+ - H. Runtime SVG selection/highlighting: `tests/browser/observationSvgWorkspace.test.ts`.
466
+ Protect exact geometry, unresolved-target omission, list/SVG selection, and
467
+ visual highlights.
468
+ - I. Reference SVG selection/highlighting: `tests/browser/referenceCandidateWorkspace.test.ts`
469
+ and `referenceBindingFidelityWorkspace.test.ts`.
470
+ - J. Zoom/pan: `tests/browser/observationComparison.test.ts`,
471
+ `referenceCandidateWorkspace.test.ts`, and focused workspace scenarios in the
472
+ browser suite. These protect fit/reset, viewBox, pointer pan, and view lock.
473
+ - K. Explicit binding cross-selection: `tests/browser/referenceBindingFidelityWorkspace.test.ts`
474
+ (`Case A - explicit bound cross-selection`). It protects declared-only,
475
+ many-to-one reverse highlighting and keeps primary selection separate.
476
+ - L. Real-browser viewer behavior: `tests/browser/viewerIntegratedAcceptance.test.ts`,
477
+ `viewerEvidenceShell.test.ts`, `observationSvgWorkspace.test.ts`,
478
+ `referenceCandidateWorkspace.test.ts`, and
479
+ `referenceBindingFidelityWorkspace.test.ts`.
480
+ - M. PWA/API cache boundary: `tests/browser/pwaHardening.test.ts` protects real
481
+ service-worker registration, shell precache, no `/api/` cache entries, and
482
+ explicit unavailable state when the server is down.
483
+ - N. Packed installed-package viewer smoke: `scripts/ci/runPackedViewerSmoke.mjs`.
484
+ It owns pack/install/launch checks for the shipped viewer boundary; the
485
+ analogous observation package path is `runPackedObservationSmoke.mjs`.
486
+ - O. Project-aware viewer behavior: `tests/browser/projectWorkflowViewer.test.ts`
487
+ and `tests/browser/projectCheckWorkflow.test.ts`; unit ownership is
488
+ `tests/unit/projectWorkflow.test.ts`, `projectCheckService.test.ts`, and
489
+ `projectCheckResult.test.ts`. These protect init/capture/replace, canonical
490
+ paths, alias projection, and project check flow.
491
+
492
+ ## 13. Package/release boundary
493
+
494
+ - `package.json#files` allows `dist`, `README.md`, `CHANGELOG.md`, `docs`, and
495
+ `LICENSE`; source `src/`, `viewer/src/`, and tests are not package payload.
496
+ - `npm run build` runs `tsc -p tsconfig.json` and `vite build --config
497
+ viewer/vite.config.ts`, producing compiled library/CLI output and
498
+ `dist/viewer` assets.
499
+ - `package.json#exports["."]` exposes `./dist/index.js`; the CLI bin is
500
+ `dist/cli.js`.
501
+ - A new public persisted domain capability needs its domain/application/artifact
502
+ code compiled into `dist`, any public types/functions added deliberately to
503
+ `src/index.ts`, CLI dispatch/help if applicable, viewer server classification/
504
+ routes/projections if displayable, and viewer build output if UI changes.
505
+ - `scripts/ci/runPackedViewerSmoke.mjs` is the packed-candidate viewer proof;
506
+ `tests/browser/*` real-Chromium suites are source-checkout behavior proof.
507
+ Source tests alone do not prove npm package contents.
508
+
509
+ ## 14. Planner-relevant constraints
510
+
511
+ - `ReferenceRegionOverlaySvg` and `TargetOverlaySvg` intentionally use separate
512
+ coordinate domains. Reference-region identity is not runtime-target identity.
513
+ - Runtime target geometry is captured/rendered in viewport CSS pixels without
514
+ device-pixel-ratio conversion, rounding, or clamping.
515
+ - The viewer is GET/HEAD-only, loopback-only, read-only, metadata-first, and
516
+ must not become an evidence or domain derivation engine.
517
+ - Evidence discovery currently requires explicit artifact-family classification
518
+ and canonical reader dispatch; arbitrary new manifests are reported as
519
+ unrecognized rather than auto-supported.
520
+ - Canonical readers remain the sole structural validation authority at the
521
+ viewer boundary.
522
+ - Viewer derivation call sites are explicit: observation relationships in
523
+ `observationView.ts`, reference relationships/adequacy and pair computations
524
+ in `referenceView.ts`, and route dispatch in `httpServer.ts`.
525
+ - Bindings and bounded context are session input. They are read once by startup,
526
+ not persisted or browser-selected by file path.
527
+ - Aliases select canonical artifact directories and never provide artifact
528
+ provenance or replace canonical IDs.
529
+ - Artifact persistence is immutable by precedent: fresh instance directory,
530
+ atomic temp-directory rename, no overwrite, and previous artifacts retained.
531
+ - Supersession is represented as authored logical identity/reference data; it
532
+ does not authorize destructive mutation of the superseded artifact.
533
+ - `unexpected` is evaluator output, not an authored contract category.
534
+ - Reference-image pixels are not runtime/CSS pixels; cross-domain interpretation
535
+ goes through the existing coordinate-scale/fidelity owners.
536
+ - PWA caching may cache shell/assets but must not make stale evidence/API/media
537
+ responses authoritative after the evidence root or server changes.
538
+ - Shipping a capability requires the compiled `dist` boundary, public exports
539
+ where applicable, CLI/viewer integration where applicable, and packed smoke
540
+ coverage, not only source-checkout tests.
541
+
542
+ ## 15. Open questions genuinely not answerable from current code
543
+
544
+ - The current implementation does not define whether v0.9 authored visual
545
+ annotations are a new persisted artifact family, fields on an existing family,
546
+ or a separate authored layer; that is a planner-owned product/architecture
547
+ decision.
548
+ - The current code does not define the semantic identity inputs, supersession
549
+ rules, or media payload shape for a future annotation artifact.
550
+ - The current code does not define whether annotation authoring should be
551
+ exposed through a CLI, project workflow, viewer-only session, or another
552
+ application service.
553
+ - The current viewer has no mutation route; the authorization and persistence
554
+ boundary for any future authoring interaction is therefore unresolved by
555
+ existing code.
556
+ - The current code does not specify how authored annotation geometry should
557
+ behave when a runtime viewport or reference image is resized or unavailable;
558
+ existing runtime and reference coordinate contracts remain the only grounded
559
+ precedents.
560
+
561
+ ## 16. Retrieval compliance
562
+
563
+ - my-dev-kit used before whole production/test source reads: `yes`.
564
+ - Full-file production/test fallbacks: `0`.
565
+ - Unexplained full-file fallbacks: `0`.
566
+ - The only generated managed retrieval state is the fresh index listed in
567
+ section 3. The only requested tracked repository report is this file.