@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,589 @@
|
|
|
1
|
+
# v0.9 Demo Foundation
|
|
2
|
+
|
|
3
|
+
## 1. VERDICT
|
|
4
|
+
|
|
5
|
+
`PASS_V0_9_DEMO_FOUNDATION`
|
|
6
|
+
|
|
7
|
+
A deterministic, offline, version-controlled Observer demo now exists under
|
|
8
|
+
`examples/v09-demo/`, together with a safe materialization script, a
|
|
9
|
+
loopback-only demo server, a fixed external reference image, and automated
|
|
10
|
+
unit, real-HTTP and real-Chromium coverage. The full Observer regression suite
|
|
11
|
+
remains green. No product semantics, package version, dependency or release
|
|
12
|
+
state changed.
|
|
13
|
+
|
|
14
|
+
This is demonstration infrastructure only. It is not a v0.9 product feature and
|
|
15
|
+
it does not release anything.
|
|
16
|
+
|
|
17
|
+
## 2. Repository identity
|
|
18
|
+
|
|
19
|
+
- Repository: `C:\Users\daile\Projects\my-frontend-observer`
|
|
20
|
+
- Branch: `master`
|
|
21
|
+
- Starting HEAD: `9cedc2e79ed626b9bbced5583e2da605dc14a72c`
|
|
22
|
+
- Package: `@dailephd/my-frontend-observer`
|
|
23
|
+
- Package version: `0.8.1` (unchanged)
|
|
24
|
+
|
|
25
|
+
The planner-known implementation-complete commit was
|
|
26
|
+
`a78a058271564661e2f04a835db04071b135258a`. Local `master` was one commit
|
|
27
|
+
ahead of it at `9cedc2e` (`docs: record v0.9 pre-release readiness`), which is
|
|
28
|
+
exactly the later pre-release readiness work the task anticipates. That commit
|
|
29
|
+
adds only `docs/reports/v0.9-pre-release-readiness.md`. The divergence is
|
|
30
|
+
therefore legitimate continuation work, the tracked worktree was clean at
|
|
31
|
+
entry, and `9cedc2e` was adopted as `STARTING_HEAD`. Nothing was reset,
|
|
32
|
+
rebased, pulled or overwritten.
|
|
33
|
+
|
|
34
|
+
`docs/reports/v0.9-architecture-retrieval.md` carried its intentional
|
|
35
|
+
`skip-worktree` flag (`S`) at preflight and still carries it. It was not
|
|
36
|
+
cleared, restored, overwritten or deleted. No `git clean` and no
|
|
37
|
+
`git reset --hard` was run at any point.
|
|
38
|
+
|
|
39
|
+
## 3. Purpose
|
|
40
|
+
|
|
41
|
+
The Observer product now has a generic tutorial automation consumer,
|
|
42
|
+
`@dailephd/my-dev-kit-lab@0.4.7`, which already owns Playwright loading,
|
|
43
|
+
Chromium launch, managed processes, HTTP readiness, tutorial scenarios, target
|
|
44
|
+
contracts, locators, assertions, cursor and overlay rendering, recording,
|
|
45
|
+
subtitles, tutorial markdown, manifests and packed acceptance.
|
|
46
|
+
|
|
47
|
+
Observer must not reimplement any of that. This stage therefore builds only the
|
|
48
|
+
deterministic demo application that later Observer-specific tutorial scenarios
|
|
49
|
+
will observe, annotate and compare, plus the small amount of infrastructure
|
|
50
|
+
needed to materialize and serve it on loopback.
|
|
51
|
+
|
|
52
|
+
This is Prompt 1 of three. No tutorial scenario was authored here, no tutorial
|
|
53
|
+
video was generated, and no lab target contract was frozen.
|
|
54
|
+
|
|
55
|
+
## 4. v0.9 entry state
|
|
56
|
+
|
|
57
|
+
v0.9 product implementation was already complete and unreleased at entry. All
|
|
58
|
+
frozen v0.9 semantics were treated as read-only:
|
|
59
|
+
|
|
60
|
+
`VisualAnnotationArtifact`, annotation identity and persistence, runtime intent
|
|
61
|
+
mappings, confirmation semantics, frontend-contract primitives, contract
|
|
62
|
+
promotion, reference requirement semantics, reference materialization,
|
|
63
|
+
reference approval, project acceptance and viewer authoring security are all
|
|
64
|
+
unchanged by this stage.
|
|
65
|
+
|
|
66
|
+
The demo was built around the completed product, not inside it.
|
|
67
|
+
|
|
68
|
+
## 5. Demo architecture
|
|
69
|
+
|
|
70
|
+
The demo is a small deterministic HTML, CSS and JavaScript application. No
|
|
71
|
+
frontend framework, no second Vite application and no build system was added,
|
|
72
|
+
and no dependency was added or upgraded.
|
|
73
|
+
|
|
74
|
+
The architecture has three separable pieces:
|
|
75
|
+
|
|
76
|
+
1. An immutable tracked template under `examples/v09-demo/`.
|
|
77
|
+
2. A materialization script that copies that template into a caller-provided
|
|
78
|
+
disposable target root.
|
|
79
|
+
3. A loopback-only static server that serves one materialized (or explicitly
|
|
80
|
+
pointed-at) demo application on a caller-selected port.
|
|
81
|
+
|
|
82
|
+
Geometry lives entirely in CSS custom properties keyed on a single
|
|
83
|
+
`data-demo-state` attribute. The server freezes the requested state into that
|
|
84
|
+
attribute before serving the document. One small classic script owns the only
|
|
85
|
+
two differences CSS cannot express honestly: removing an element from the DOM,
|
|
86
|
+
and pointing an image at a different local file.
|
|
87
|
+
|
|
88
|
+
## 6. Demo component inventory
|
|
89
|
+
|
|
90
|
+
Tracked template:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
examples/v09-demo/README.md
|
|
94
|
+
examples/v09-demo/app/index.html
|
|
95
|
+
examples/v09-demo/app/styles.css
|
|
96
|
+
examples/v09-demo/app/state.js
|
|
97
|
+
examples/v09-demo/app/assets/brand-mark.svg
|
|
98
|
+
examples/v09-demo/app/assets/asset-primary.svg
|
|
99
|
+
examples/v09-demo/app/assets/asset-alternate.svg
|
|
100
|
+
examples/v09-demo/references/v09-reference.png
|
|
101
|
+
examples/v09-demo/references/v09-reference.provenance.json
|
|
102
|
+
examples/v09-demo/scripts/prepare.mjs
|
|
103
|
+
examples/v09-demo/scripts/server.mjs
|
|
104
|
+
examples/v09-demo/scripts/generate-reference.mjs
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The application contains a header, a navigation bar, a hero, a sidebar, a main
|
|
108
|
+
content region, two cards, a call-to-action, a footer and a local illustration
|
|
109
|
+
asset area.
|
|
110
|
+
|
|
111
|
+
## 7. Stable target identity
|
|
112
|
+
|
|
113
|
+
Every region carries a deliberate `data-demo-target` attribute. This vocabulary
|
|
114
|
+
is the demo's identity contract and does not depend on any incidental CSS
|
|
115
|
+
class:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
header
|
|
119
|
+
navigation
|
|
120
|
+
hero
|
|
121
|
+
sidebar
|
|
122
|
+
content
|
|
123
|
+
card-1
|
|
124
|
+
card-2
|
|
125
|
+
cta
|
|
126
|
+
footer
|
|
127
|
+
asset
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
A bounded set of `data-testid` attributes exists only where automation needs to
|
|
131
|
+
interact with the page rather than measure it:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
demo-state-badge
|
|
135
|
+
demo-cta-button
|
|
136
|
+
demo-asset-image
|
|
137
|
+
demo-nav-<state> (one per demo state)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`data-testid` was not added mechanically to every element. Observer Viewer
|
|
141
|
+
selectors were deliberately not touched: `viewer/src/` is unchanged, and the
|
|
142
|
+
minimum stable Viewer test ids belong to Prompt 2 after real scenario authoring
|
|
143
|
+
shows what is needed.
|
|
144
|
+
|
|
145
|
+
## 8. State model
|
|
146
|
+
|
|
147
|
+
Nine frozen states, selected deterministically through the URL query parameter
|
|
148
|
+
`?state=<state>`:
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
baseline
|
|
152
|
+
move-hero
|
|
153
|
+
wider-sidebar
|
|
154
|
+
changed-spacing
|
|
155
|
+
move-footer
|
|
156
|
+
removed-card
|
|
157
|
+
changed-asset
|
|
158
|
+
multi-change
|
|
159
|
+
reference
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Omitting `?state=` renders `baseline`. An unrecognized state fails closed: the
|
|
163
|
+
server answers HTTP 400 with an explicit invalid-state document that names the
|
|
164
|
+
rejected value (HTML-escaped) and lists the supported states. The application
|
|
165
|
+
itself is never rendered for an invalid state, and no unrelated state is ever
|
|
166
|
+
silently substituted.
|
|
167
|
+
|
|
168
|
+
No state name needed to differ from the task's vocabulary.
|
|
169
|
+
|
|
170
|
+
## 9. Baseline state
|
|
171
|
+
|
|
172
|
+
Baseline geometry is frozen for the canonical tutorial viewport `1440x900`.
|
|
173
|
+
Real Chromium measurements through the canonical observation path:
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
header x=0 y=0 w=1440 h=64
|
|
177
|
+
navigation x=0 y=64 w=1440 h=48
|
|
178
|
+
sidebar x=20 y=132 w=260 h=676
|
|
179
|
+
content x=304 y=132 w=1116 h=676
|
|
180
|
+
hero x=325 y=153 w=894 h=180
|
|
181
|
+
card-1 x=325 y=353 w=300 h=170
|
|
182
|
+
card-2 x=645 y=353 w=300 h=170
|
|
183
|
+
cta x=325 y=543 w=1074 h=72
|
|
184
|
+
asset x=325 y=635 w=1074 h=120
|
|
185
|
+
footer x=0 y=828 w=1440 h=72
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Determinism measures actually taken: fixed band heights rather than
|
|
189
|
+
font-dependent ones, a local system font stack, no network font, no remote
|
|
190
|
+
asset, no animation, no transition, no timer, no random value, no current time,
|
|
191
|
+
no network-loaded image, and `overflow: hidden` on the document so a scrollbar
|
|
192
|
+
can never appear and change the usable layout width. In every state, real
|
|
193
|
+
Chromium reports `innerWidth = 1440`, `scrollWidth = 1440` and
|
|
194
|
+
`scrollHeight = 900`.
|
|
195
|
+
|
|
196
|
+
## 10. Change-state semantics
|
|
197
|
+
|
|
198
|
+
Measured against baseline with real Chromium:
|
|
199
|
+
|
|
200
|
+
1. `move-hero` - hero `x` increases from 325 to 485, exactly +160px. Hero
|
|
201
|
+
width, `y` and height are unchanged, and every other demo target is
|
|
202
|
+
byte-identical to baseline. This is the clean `Move Right` ->
|
|
203
|
+
`property-increases x` example.
|
|
204
|
+
2. `wider-sidebar` - sidebar `width` increases from 260 to 400, exactly
|
|
205
|
+
+140px. Sidebar `x`, `y` and height are unchanged, and the header and
|
|
206
|
+
footer do not move. This is the clean `Resize Wider` ->
|
|
207
|
+
`property-increases width` example.
|
|
208
|
+
3. `changed-spacing` - the measured horizontal gap between the sidebar's right
|
|
209
|
+
edge and the content region's left edge grows from 24px to 96px. Neither
|
|
210
|
+
region's own width changes, and no demo target changes its `y`. This is a
|
|
211
|
+
relationship and measurement change, not a region change.
|
|
212
|
+
4. `move-footer` - footer `y` decreases from 828 to 764, exactly -64px, while
|
|
213
|
+
footer `x`, width and height are unchanged and every other target is
|
|
214
|
+
identical to baseline. The footer lifts off the bottom edge, which is
|
|
215
|
+
deliberately the shape of a real layout regression.
|
|
216
|
+
5. `removed-card` - `card-2` is genuinely absent from the document. The
|
|
217
|
+
canonical observation reports `selectionStatus = not-found` and no geometry
|
|
218
|
+
evidence, rather than fabricated geometry. `card-1` and every other target
|
|
219
|
+
are identical to baseline. This demonstrates human intent that v0.9 can
|
|
220
|
+
annotate as a `remove` operation but that the current `ContractPrimitive`
|
|
221
|
+
vocabulary cannot promote into a contract clause.
|
|
222
|
+
6. `changed-asset` - the illustration image `src` changes from
|
|
223
|
+
`assets/asset-primary.svg` to `assets/asset-alternate.svg`. Every demo
|
|
224
|
+
target's geometry, including the asset container's, is identical to
|
|
225
|
+
baseline, so an asset-sensitive difference is never conflated with geometry.
|
|
226
|
+
7. `multi-change` - five deterministic differences at once: hero `x` 625,
|
|
227
|
+
sidebar width 400, footer `y` 764, `card-2` absent, and the alternate asset.
|
|
228
|
+
This is the state for exercising selected-only contract promotion and
|
|
229
|
+
selected-only reference materialization. It is deliberately not the primary
|
|
230
|
+
simple tutorial state.
|
|
231
|
+
|
|
232
|
+
## 11. Reference state
|
|
233
|
+
|
|
234
|
+
`reference` represents a desired design rather than an observed change. It
|
|
235
|
+
differs from baseline in four controlled ways, chosen so a reference workflow
|
|
236
|
+
has one of each kind of difference to work with:
|
|
237
|
+
|
|
238
|
+
- region geometry: sidebar width 320 (baseline 260), hero `x` 497 (baseline
|
|
239
|
+
325);
|
|
240
|
+
- relationship and measurement: the sidebar-to-content gap is 56px (baseline
|
|
241
|
+
24px);
|
|
242
|
+
- asset-sensitive area: the alternate local illustration;
|
|
243
|
+
- visual treatment: a different accent colour.
|
|
244
|
+
|
|
245
|
+
The page frame stays comparable: header and footer geometry are identical to
|
|
246
|
+
baseline, and every demo region is still present. The reference is a design,
|
|
247
|
+
not a removal.
|
|
248
|
+
|
|
249
|
+
## 12. Local asset policy
|
|
250
|
+
|
|
251
|
+
Every asset is a local file committed beneath `examples/v09-demo/`. There is no
|
|
252
|
+
CDN, no Google Fonts, no external image URL, no external API and no
|
|
253
|
+
network-dependent icon library. The demo renders correctly offline.
|
|
254
|
+
|
|
255
|
+
This is enforced two ways. A unit test scans every demo application file and
|
|
256
|
+
fails on any `http://` or `https://` reference (excluding the SVG XML
|
|
257
|
+
namespace declaration, which is an identifier and never fetched). A real
|
|
258
|
+
Chromium test records every network request origin while loading all nine
|
|
259
|
+
states and asserts the only origin contacted is the demo's own loopback server.
|
|
260
|
+
|
|
261
|
+
## 13. Materialization
|
|
262
|
+
|
|
263
|
+
```powershell
|
|
264
|
+
node examples/v09-demo/scripts/prepare.mjs <targetRoot>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
The target root is required and never defaulted. It is resolved absolutely and
|
|
268
|
+
validated before anything is removed. The script refuses:
|
|
269
|
+
|
|
270
|
+
- a missing, empty or whitespace-only argument;
|
|
271
|
+
- a target root containing a null byte;
|
|
272
|
+
- a filesystem or drive root;
|
|
273
|
+
- any path with fewer than two segments below its root;
|
|
274
|
+
- the user's home directory;
|
|
275
|
+
- the repository root;
|
|
276
|
+
- the immutable demo template, or anything inside it;
|
|
277
|
+
- any directory that contains the repository, which a reset would destroy.
|
|
278
|
+
|
|
279
|
+
Reset semantics are "rematerialize the target root": a rerun destroys and
|
|
280
|
+
recreates the target, so it always ends in the same clean state. There is no
|
|
281
|
+
separate reset command, matching the task's contract.
|
|
282
|
+
|
|
283
|
+
A materialized target contains exactly:
|
|
284
|
+
|
|
285
|
+
```text
|
|
286
|
+
<targetRoot>/app/index.html
|
|
287
|
+
<targetRoot>/app/styles.css
|
|
288
|
+
<targetRoot>/app/state.js
|
|
289
|
+
<targetRoot>/app/assets/asset-alternate.svg
|
|
290
|
+
<targetRoot>/app/assets/asset-primary.svg
|
|
291
|
+
<targetRoot>/app/assets/brand-mark.svg
|
|
292
|
+
<targetRoot>/server.mjs
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
That is everything needed to serve the demo without reaching back into the
|
|
296
|
+
template or into any generated Observer evidence. The fixed reference PNG is
|
|
297
|
+
deliberately not copied: it is not needed to serve the application, and Prompt
|
|
298
|
+
2 imports it through canonical Observer commands from its tracked path.
|
|
299
|
+
|
|
300
|
+
## 14. Source immutability
|
|
301
|
+
|
|
302
|
+
The tracked template is read-only during materialization. A test takes a
|
|
303
|
+
SHA-256 fingerprint of every file under `examples/v09-demo/` before the
|
|
304
|
+
materialization suite runs and compares it after a destructive rematerialization
|
|
305
|
+
has occurred; the fingerprints must match exactly. A further test asserts that
|
|
306
|
+
nothing new appeared beside the template's own directories, and that every file
|
|
307
|
+
written during the run lives under the selected target root.
|
|
308
|
+
|
|
309
|
+
Materialization destroys and recreates only the explicitly selected disposable
|
|
310
|
+
target root, and only after every containment and safety check has passed.
|
|
311
|
+
|
|
312
|
+
No generated `.frontend-observer` evidence exists anywhere in the template, and
|
|
313
|
+
a test enforces that.
|
|
314
|
+
|
|
315
|
+
## 15. Demo server
|
|
316
|
+
|
|
317
|
+
`examples/v09-demo/scripts/server.mjs` is a small Node HTTP server using only
|
|
318
|
+
Node built-ins. No dependency was added.
|
|
319
|
+
|
|
320
|
+
Behavior:
|
|
321
|
+
|
|
322
|
+
- binds `127.0.0.1` only; the test reads the bound address back from the OS
|
|
323
|
+
rather than trusting the requested constant;
|
|
324
|
+
- serves only the resolved demo application directory;
|
|
325
|
+
- resolves every request path inside that directory and fails closed on `..`
|
|
326
|
+
segments, `.` segments, backslashes, null bytes and percent-encoded forms of
|
|
327
|
+
the same;
|
|
328
|
+
- serves only a small allowlist of static types (`.html`, `.css`, `.js`,
|
|
329
|
+
`.svg`, `.png`, `.json`); anything else is 404 rather than a guessed type;
|
|
330
|
+
- answers only `GET` and `HEAD`; any other method is 405;
|
|
331
|
+
- sends `cache-control: no-store` and `x-content-type-options: nosniff`.
|
|
332
|
+
|
|
333
|
+
Port selection is always the caller's. `4173` appears nowhere in the file, and
|
|
334
|
+
a test asserts that. The command line requires `--port` and validates it as an
|
|
335
|
+
integer in `1..65535`, rejecting a missing value, a non-integer, `0`, a
|
|
336
|
+
negative value and `65536`. The exported `startDemoServer({ port })` additionally
|
|
337
|
+
accepts `port: 0` for in-process automation, where the OS assigns an ephemeral
|
|
338
|
+
port; this mirrors the repository's existing canonical viewer port contract in
|
|
339
|
+
`src/viewerServer/port.ts`, which documents the same allowance for deterministic
|
|
340
|
+
test use. A test proves the server listens on exactly the port the caller
|
|
341
|
+
selected.
|
|
342
|
+
|
|
343
|
+
An optional `--app-root <dir>` lets the tracked template be served directly
|
|
344
|
+
while editing the demo. A materialized target needs no such flag: the server
|
|
345
|
+
resolves `app/` beside itself.
|
|
346
|
+
|
|
347
|
+
No lab `TutorialTargetContractV1` was frozen or committed. That belongs to
|
|
348
|
+
Prompt 2, once the demo, the Observer project bootstrap and the project-aware
|
|
349
|
+
viewer can be composed with dynamic loopback ports.
|
|
350
|
+
|
|
351
|
+
## 16. Health and readiness
|
|
352
|
+
|
|
353
|
+
```text
|
|
354
|
+
GET /health
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Answers HTTP 200 with a bounded deterministic JSON document:
|
|
358
|
+
|
|
359
|
+
```json
|
|
360
|
+
{
|
|
361
|
+
"ok": true,
|
|
362
|
+
"demoId": "my-frontend-observer-v09-demo",
|
|
363
|
+
"schemaVersion": "1.0.0",
|
|
364
|
+
"canonicalViewport": { "width": 1440, "height": 900 },
|
|
365
|
+
"defaultState": "baseline",
|
|
366
|
+
"states": ["baseline", "..."]
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
There is no current time and no per-run identity in it. A test fetches it twice
|
|
371
|
+
and asserts the two responses are byte-identical, and asserts the health
|
|
372
|
+
response never contains application HTML. `schemaVersion` here describes this
|
|
373
|
+
demo's own readiness document; it is not an Observer artifact schema version
|
|
374
|
+
and no Observer schema was touched.
|
|
375
|
+
|
|
376
|
+
## 17. Reference PNG
|
|
377
|
+
|
|
378
|
+
`examples/v09-demo/references/v09-reference.png` is a fixed 1440x900 PNG
|
|
379
|
+
(55,876 bytes) captured from the demo's `reference` state.
|
|
380
|
+
|
|
381
|
+
It was produced by `examples/v09-demo/scripts/generate-reference.mjs`, which
|
|
382
|
+
serves the `reference` state on loopback and captures it through the
|
|
383
|
+
repository's own canonical Chromium observation path (`captureViewportInternal`
|
|
384
|
+
from `src/browser/chromiumAdapter.ts`, via the compiled `dist/` module). No
|
|
385
|
+
second screenshot engine was added. The script requires a prior `npm run build`
|
|
386
|
+
and fails with an explicit message if the compiled modules are missing.
|
|
387
|
+
|
|
388
|
+
`examples/v09-demo/references/v09-reference.provenance.json` records the source
|
|
389
|
+
demo state, the canonical viewport, the image format, how the image was
|
|
390
|
+
captured, the exact regeneration command and the intended tutorial use. It is a
|
|
391
|
+
plain record beside the asset: it declares no artifact kind and no Observer
|
|
392
|
+
schema version, and a test asserts both fields are absent.
|
|
393
|
+
|
|
394
|
+
The committed PNG is a fixed demo asset. Nothing regenerates it during an
|
|
395
|
+
ordinary test run; regeneration is an explicit manual command so an intentional
|
|
396
|
+
visual change is reviewed deliberately.
|
|
397
|
+
|
|
398
|
+
No generated `.frontend-observer/` reference artifacts were committed. Import
|
|
399
|
+
and approval of this PNG through canonical Observer commands, inside a
|
|
400
|
+
disposable target, belongs to Prompt 2.
|
|
401
|
+
|
|
402
|
+
## 18. Unit and server tests
|
|
403
|
+
|
|
404
|
+
`tests/unit/v09DemoTemplate.test.ts` (12 tests) - stable target vocabulary
|
|
405
|
+
present exactly once each and closed to the frozen set, baseline state frozen
|
|
406
|
+
into the tracked document, bounded and unique `data-testid` set, semantic
|
|
407
|
+
elements for the major regions, no remote origin in any demo file, every
|
|
408
|
+
referenced asset present locally, no animation/transition/timer/randomness/
|
|
409
|
+
current time anywhere, no committed Observer evidence, and the reference PNG
|
|
410
|
+
validated through `src/domain/externalReferenceImage.ts` (format detected from
|
|
411
|
+
magic bytes, dimensions `1440x900`, size within the canonical bound) plus its
|
|
412
|
+
provenance record.
|
|
413
|
+
|
|
414
|
+
`tests/unit/v09DemoMaterialization.test.ts` (16 tests) - explicit target
|
|
415
|
+
required; filesystem/drive root, root-like target, home directory, repository
|
|
416
|
+
root, template and anything inside it, repository-containing directory and null
|
|
417
|
+
byte all rejected; clean target produced with exactly the expected file list;
|
|
418
|
+
every file copied byte-for-byte; rerun resets deterministically and discards a
|
|
419
|
+
stale directory and a mutated file; template fingerprints unchanged across the
|
|
420
|
+
destructive run; nothing written outside the selected target; no Observer
|
|
421
|
+
evidence in the target; and the materialized `server.mjs` resolves its
|
|
422
|
+
application root from the target root alone.
|
|
423
|
+
|
|
424
|
+
`tests/unit/v09DemoServer.test.ts` (18 tests) - real HTTP throughout. Port
|
|
425
|
+
argument validation, no hardcoded port, path containment unit coverage,
|
|
426
|
+
single-attribute state rewriting, loopback binding read back from the OS,
|
|
427
|
+
deterministic `/health`, health not confused with application HTML, baseline at
|
|
428
|
+
`/`, every one of the nine states rendering with exactly that state frozen into
|
|
429
|
+
the document, unknown state failing closed with 400 and no application markup,
|
|
430
|
+
HTML escaping of a hostile state value, every local asset served with the right
|
|
431
|
+
content type, wire-level traversal rejection including percent-encoded and
|
|
432
|
+
backslash forms, the static allowlist, method rejection, and a server listening
|
|
433
|
+
on exactly the caller-selected port.
|
|
434
|
+
|
|
435
|
+
All demo unit suites passed.
|
|
436
|
+
|
|
437
|
+
## 19. Real-browser validation
|
|
438
|
+
|
|
439
|
+
`tests/browser/v09Demo.test.ts` (17 tests) runs against real Chromium at
|
|
440
|
+
`1440x900`, using the repository's existing real-Chromium browser-test
|
|
441
|
+
infrastructure.
|
|
442
|
+
|
|
443
|
+
The geometry suite captures all nine states through the canonical observation
|
|
444
|
+
path and asserts: every required demo target present in baseline; baseline
|
|
445
|
+
rendered at exactly the canonical viewport with the footer flush to the bottom;
|
|
446
|
+
the intended direction and magnitude of each state's primary difference; that
|
|
447
|
+
every unrelated region is untouched in `move-hero`, `wider-sidebar`,
|
|
448
|
+
`move-footer`, `removed-card` and `changed-asset`; that `changed-spacing`
|
|
449
|
+
changes a measured gap and no region's `y`; that `card-2` resolves `not-found`
|
|
450
|
+
with no fabricated geometry when removed; that `multi-change` shows several
|
|
451
|
+
differences at once; that `reference` shows the intended controlled design
|
|
452
|
+
differences while staying comparable; that every demo target stays present,
|
|
453
|
+
unique (never `ambiguous`) and matched in every state except the intentionally
|
|
454
|
+
absent card; and that the major regions expose real landmark roles (`banner`,
|
|
455
|
+
`navigation`, `complementary`, `main`, `contentinfo`) in every state.
|
|
456
|
+
|
|
457
|
+
The DOM suite uses a real page to assert what observation evidence deliberately
|
|
458
|
+
does not carry: the asset `src` swap and its absence elsewhere, every
|
|
459
|
+
tutorial-critical test id present and unique per state, the state badge text and
|
|
460
|
+
`aria-current` navigation marking, the invalid-state page rendering without any
|
|
461
|
+
application markup, that no remote origin is ever contacted, and that no state
|
|
462
|
+
ever needs a scrollbar.
|
|
463
|
+
|
|
464
|
+
All 17 real-browser demo tests passed.
|
|
465
|
+
|
|
466
|
+
The accessibility check is a bounded structural and landmark-role check. It is
|
|
467
|
+
not a full accessibility certification and is not claimed as one. No PWA,
|
|
468
|
+
service-worker or OS-installation claim is made by this stage, because none was
|
|
469
|
+
exercised.
|
|
470
|
+
|
|
471
|
+
## 20. Scope audit
|
|
472
|
+
|
|
473
|
+
All of the following are `false`:
|
|
474
|
+
|
|
475
|
+
```text
|
|
476
|
+
v0.9 annotation schema changed false
|
|
477
|
+
frontend contract schema changed false
|
|
478
|
+
external-reference schema changed false
|
|
479
|
+
runtime intent semantics changed false
|
|
480
|
+
contract promotion semantics changed false
|
|
481
|
+
reference materialization semantics changed false
|
|
482
|
+
viewer security changed false
|
|
483
|
+
tutorial runtime duplicated false
|
|
484
|
+
Playwright tutorial engine added to Observer false
|
|
485
|
+
WebM recorder added to Observer false
|
|
486
|
+
subtitle generator added to Observer false
|
|
487
|
+
package version changed false
|
|
488
|
+
dependency added false
|
|
489
|
+
v0.9 marked released false
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
`src/`, `viewer/src/`, `package.json`, `package-lock.json`, `scripts/` and
|
|
493
|
+
`.github/workflows/` are all unchanged.
|
|
494
|
+
|
|
495
|
+
One file outside `examples/` and `tests/` changed: `eslint.config.js` gained a
|
|
496
|
+
scoped block giving `examples/v09-demo/app/**/*.js` the two DOM globals it
|
|
497
|
+
uses. That file is lint configuration, not Observer production source or
|
|
498
|
+
product semantics, and the addition is scoped to the demo application
|
|
499
|
+
directory. ESLint 10 flat config has no per-file environment comment, so a
|
|
500
|
+
config block is the only available mechanism.
|
|
501
|
+
|
|
502
|
+
`examples/v09-demo` was deliberately not added to `package.json#files`. A
|
|
503
|
+
`npm pack --dry-run` confirms zero `examples/` entries in the candidate
|
|
504
|
+
tarball. Whether the demo ships inside `0.9.0` is a Prompt 3 decision, after
|
|
505
|
+
tutorial acceptance.
|
|
506
|
+
|
|
507
|
+
Documentation scope was respected. Only `examples/v09-demo/README.md` and this
|
|
508
|
+
report were written. `README.md`, `docs/QUICKSTART.md`, `docs/WORKFLOWS.md`,
|
|
509
|
+
`docs/CURRENT_STATE.md` and every other release-facing document are unchanged
|
|
510
|
+
and remain owned by Prompt 3.
|
|
511
|
+
|
|
512
|
+
## 21. Changed files
|
|
513
|
+
|
|
514
|
+
Added:
|
|
515
|
+
|
|
516
|
+
```text
|
|
517
|
+
examples/v09-demo/README.md
|
|
518
|
+
examples/v09-demo/app/index.html
|
|
519
|
+
examples/v09-demo/app/styles.css
|
|
520
|
+
examples/v09-demo/app/state.js
|
|
521
|
+
examples/v09-demo/app/assets/brand-mark.svg
|
|
522
|
+
examples/v09-demo/app/assets/asset-primary.svg
|
|
523
|
+
examples/v09-demo/app/assets/asset-alternate.svg
|
|
524
|
+
examples/v09-demo/references/v09-reference.png
|
|
525
|
+
examples/v09-demo/references/v09-reference.provenance.json
|
|
526
|
+
examples/v09-demo/scripts/prepare.mjs
|
|
527
|
+
examples/v09-demo/scripts/server.mjs
|
|
528
|
+
examples/v09-demo/scripts/generate-reference.mjs
|
|
529
|
+
tests/unit/v09DemoTemplate.test.ts
|
|
530
|
+
tests/unit/v09DemoMaterialization.test.ts
|
|
531
|
+
tests/unit/v09DemoServer.test.ts
|
|
532
|
+
tests/browser/v09Demo.test.ts
|
|
533
|
+
docs/reports/v0.9-demo-foundation.md
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
Modified:
|
|
537
|
+
|
|
538
|
+
```text
|
|
539
|
+
eslint.config.js
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Validation actually run, with exact results:
|
|
543
|
+
|
|
544
|
+
```text
|
|
545
|
+
npm run typecheck PASS
|
|
546
|
+
npm run lint PASS
|
|
547
|
+
npm test PASS (87 files, 1425 tests)
|
|
548
|
+
npm run test:browser PASS (27 files, 252 tests)
|
|
549
|
+
npm run test:security PASS (16 files / 167 tests, then 3 files / 77 tests)
|
|
550
|
+
npm run build PASS
|
|
551
|
+
npm run check:docs PASS (17 required files)
|
|
552
|
+
npm pack --dry-run PASS (0.8.1, 0 examples/ entries; 362 files before this
|
|
553
|
+
report was written, 363 with it)
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
No step was skipped. No test was weakened, skipped or deleted, and no
|
|
557
|
+
`.skip`, `.only`, `continue-on-error` or `|| true` was introduced.
|
|
558
|
+
|
|
559
|
+
Generated paths during this stage, all inside the repository-local approved
|
|
560
|
+
workflow root and all git-ignored:
|
|
561
|
+
|
|
562
|
+
```text
|
|
563
|
+
.my-dev-kit-workflow/v0.9/demo-foundation/tests/materialization/ (created and removed by the materialization suite on each run)
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Two transient exploratory paths were used during implementation and have been
|
|
567
|
+
removed: `.my-dev-kit-workflow/v0.9/demo-foundation/scratch/` and
|
|
568
|
+
`.my-dev-kit-workflow/v0.9/demo-foundation/smoke-target/`. Nothing substantial
|
|
569
|
+
was generated on `C:\` outside the repository.
|
|
570
|
+
|
|
571
|
+
`git diff --check` reports no whitespace problems. No `.frontend-observer`
|
|
572
|
+
evidence, tutorial video, lab workspace, temporary target, server log,
|
|
573
|
+
`node_modules` or `dist` content is tracked by this change.
|
|
574
|
+
|
|
575
|
+
## 22. Remaining next step
|
|
576
|
+
|
|
577
|
+
Prompt 2: Observer-specific `my-dev-kit-lab@0.4.7` tutorial integration.
|
|
578
|
+
|
|
579
|
+
Prompt 2 owns dynamic `TutorialTargetContractV1` generation, demo and bootstrap
|
|
580
|
+
process composition, Observer project initialization, baseline capture,
|
|
581
|
+
external reference import and approval of `v09-reference.png`, project-aware
|
|
582
|
+
Observer viewer startup, the minimum stable Viewer test ids, four
|
|
583
|
+
`TutorialScenarioV1` files, scenario validation against
|
|
584
|
+
`my-dev-kit-lab@0.4.7`, and Observer-specific runtime assertions.
|
|
585
|
+
|
|
586
|
+
Known risks and blockers carried forward: none from this stage. The one open
|
|
587
|
+
decision deliberately deferred is whether `examples/v09-demo` should be
|
|
588
|
+
included in `package.json#files` for `0.9.0`, which Prompt 3 decides after
|
|
589
|
+
tutorial acceptance.
|