@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,731 @@
|
|
|
1
|
+
# v0.9 Tutorial Integration
|
|
2
|
+
|
|
3
|
+
## 1. VERDICT
|
|
4
|
+
|
|
5
|
+
`PASS_V0_9_TUTORIAL_INTEGRATION`
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
LAB_V0_4_8_POINTER_DEFECT_CLOSED true
|
|
9
|
+
POSITIONAL_CLICK_SUPPORTED true
|
|
10
|
+
POSITIONAL_DRAG_SUPPORTED true
|
|
11
|
+
POINT_TUTORIAL_GESTURE PASS
|
|
12
|
+
RECTANGLE_TUTORIAL_GESTURE PASS
|
|
13
|
+
LINE_TUTORIAL_GESTURE PASS
|
|
14
|
+
ARROW_TUTORIAL_GESTURE PASS
|
|
15
|
+
NOTE_TUTORIAL_GESTURE PASS
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The defect that blocked the previous attempt is closed. All four Observer
|
|
19
|
+
tutorials validate against the released `@dailephd/my-dev-kit-lab@0.4.8`, run
|
|
20
|
+
end to end in real Chromium, and produce the full artifact set. Every outcome
|
|
21
|
+
was then verified by reading the canonical Observer evidence the runs actually
|
|
22
|
+
wrote, not by watching the video.
|
|
23
|
+
|
|
24
|
+
Observer implements no tutorial runtime, gained no dependency, and its product
|
|
25
|
+
semantics are unchanged. The package stays at `0.8.1` and v0.9 stays
|
|
26
|
+
unreleased.
|
|
27
|
+
|
|
28
|
+
## 2. Repository identity
|
|
29
|
+
|
|
30
|
+
- Repository: `C:\Users\daile\Projects\my-frontend-observer`
|
|
31
|
+
- Branch: `master`
|
|
32
|
+
- Starting HEAD: `59ae009d4bfdd38b91aa7a4e8ce4e1ca69970948`
|
|
33
|
+
- Package: `@dailephd/my-frontend-observer`
|
|
34
|
+
- Package version: `0.8.1` (unchanged)
|
|
35
|
+
- v0.9: unreleased
|
|
36
|
+
|
|
37
|
+
## 3. Prompt 1 entry gate
|
|
38
|
+
|
|
39
|
+
Preflight matched every required value: branch `master`, HEAD
|
|
40
|
+
`59ae009d4bfdd38b91aa7a4e8ce4e1ca69970948`, clean tracked worktree, package
|
|
41
|
+
`0.8.1`, and `docs/reports/v0.9-architecture-retrieval.md` still carrying its
|
|
42
|
+
intentional `skip-worktree` flag (`S`). No pull, rebase, reset, stash or clean
|
|
43
|
+
was run.
|
|
44
|
+
|
|
45
|
+
The only worktree entry at preflight was the untracked blocker report from the
|
|
46
|
+
previous attempt, which this report replaces.
|
|
47
|
+
|
|
48
|
+
The Prompt 1 demo is unchanged in design. The canonical viewport is still
|
|
49
|
+
1440x900, the nine states are intact, and the `move-footer` correction still
|
|
50
|
+
uses relative positioning so real Chromium observes a genuine 64px footer
|
|
51
|
+
shift. A digest of every tracked file under `examples/v09-demo/` was taken
|
|
52
|
+
before the final tutorial runs and compared afterwards; see section 23.
|
|
53
|
+
|
|
54
|
+
## 4. my-dev-kit-lab v0.4.8 released contract
|
|
55
|
+
|
|
56
|
+
Read from the released package rather than assumed:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
TutorialScenarioV1 schemaVersion 1.0.0
|
|
60
|
+
TutorialTargetContractV1 schemaVersion 1.0.0
|
|
61
|
+
TutorialRunResultV1 schemaVersion 1.0.0
|
|
62
|
+
TutorialManifestV1 schemaVersion 1.0.0
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
All four remain `1.0.0`. The v0.4.8 changelog states this explicitly, and the
|
|
66
|
+
committed scenarios and the generated target contracts use those exact values.
|
|
67
|
+
|
|
68
|
+
Locator kinds, assertions, the `{{targetRoot}}` placeholder and the
|
|
69
|
+
`contract-root`/`target-root` process working directories are unchanged from
|
|
70
|
+
v0.4.7. The action vocabulary gained two members and lost none:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
goto, click, fill, press, hover, drag, wait-for, pointer-click, pointer-drag
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Existing element-to-element `drag` is preserved unchanged, so v0.4.7 scenarios
|
|
77
|
+
remain valid.
|
|
78
|
+
|
|
79
|
+
`LAB_CLI_SOURCE: npm`. `npx --yes @dailephd/my-dev-kit-lab@0.4.8 --version`
|
|
80
|
+
reported `0.4.8`. The sibling checkout at `C:\Users\daile\Projects\my-dev-kit-lab`
|
|
81
|
+
was inspected read-only for corroboration and reports version `0.4.8`; it was
|
|
82
|
+
not modified, built or written to.
|
|
83
|
+
|
|
84
|
+
## 5. v0.4.8 positional pointer-action contract
|
|
85
|
+
|
|
86
|
+
The released shapes, taken from the validator and the executor:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"type": "pointer-click",
|
|
91
|
+
"locator": { "kind": "test-id", "testId": "runtime-annotation-surface" },
|
|
92
|
+
"position": { "x": 0.33, "y": 0.48 },
|
|
93
|
+
"coordinateSpace": "fraction",
|
|
94
|
+
"timeoutMs": 5000
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"type": "pointer-drag",
|
|
101
|
+
"locator": { "kind": "test-id", "testId": "runtime-annotation-surface" },
|
|
102
|
+
"from": { "x": 0.24, "y": 0.18 },
|
|
103
|
+
"to": { "x": 0.83, "y": 0.36 },
|
|
104
|
+
"coordinateSpace": "fraction",
|
|
105
|
+
"timeoutMs": 5000
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Contract facts that matter for authoring:
|
|
110
|
+
|
|
111
|
+
- `coordinateSpace` is required and its only accepted value is `"fraction"`.
|
|
112
|
+
- Coordinates are fractions of the located element's own bounding box, with
|
|
113
|
+
inclusive bounds `[0, 1]`. Anything outside that fails validation.
|
|
114
|
+
- A zero-length `pointer-drag` is rejected by the validator, so a drag always
|
|
115
|
+
expresses a real gesture.
|
|
116
|
+
- Execution is real Playwright mouse input: `mouse.move`, `mouse.down`, for a
|
|
117
|
+
drag a `mouse.move` to the end point in a fixed 8 steps
|
|
118
|
+
(`POINTER_DRAG_MOVE_STEPS = 8`), then `mouse.up`. The `mouse.up` runs even
|
|
119
|
+
when the movement throws, so a failed step cannot leave a button held down.
|
|
120
|
+
- Both actions wait for the located element to be visible and then read its
|
|
121
|
+
bounding box. They anchor to one element rather than to the page, so a
|
|
122
|
+
scenario still cannot address arbitrary screen coordinates.
|
|
123
|
+
- The cursor, click feedback, highlight and callout overlays are the lab's own
|
|
124
|
+
and are unchanged; Observer contributes none of them.
|
|
125
|
+
|
|
126
|
+
Both names match what the defect diagnosis suggested, but they were taken from
|
|
127
|
+
the released package, not assumed.
|
|
128
|
+
|
|
129
|
+
## 6. Pointer defect reproduction closure
|
|
130
|
+
|
|
131
|
+
The v0.4.7 blocker was that `drag` resolved two locators and dragged between
|
|
132
|
+
their element centres, while Observer drawing needs two freely chosen points
|
|
133
|
+
inside one surface. In every drawing mode the viewer deliberately makes target
|
|
134
|
+
rectangles pointer-inert, so the only pointer-receiving element covering the
|
|
135
|
+
drawing surface was the single screenshot `<image>`, and two locators could not
|
|
136
|
+
yield two distinct points of one element.
|
|
137
|
+
|
|
138
|
+
Before writing any scenario, that exact interaction was reproduced against the
|
|
139
|
+
real demo, the real project-aware viewer and the real released v0.4.8 CLI. A
|
|
140
|
+
disposable gate scenario drove all five drawing primitives and asserted the
|
|
141
|
+
draft item count after each one:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
step action result draft item count
|
|
145
|
+
rectangle-draw pointer-drag passed 0 -> 1
|
|
146
|
+
line-draw pointer-drag passed 1 -> 2
|
|
147
|
+
arrow-draw pointer-drag passed 2 -> 3
|
|
148
|
+
point-place pointer-click passed 3 -> 4
|
|
149
|
+
note-place pointer-click passed 4 -> 5
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The run finished `status: passed` with `cleanupErrors: []`, and the captured
|
|
153
|
+
screenshot shows five real marks on the observation with the panel reporting
|
|
154
|
+
"5 draft items". The marks were created through the viewer's ordinary pointer
|
|
155
|
+
event path: `useAnnotationPointerInteraction`'s pointerdown, pointermove and
|
|
156
|
+
pointerup handlers on the source-frame SVG.
|
|
157
|
+
|
|
158
|
+
No Observer workaround was involved. No hidden control, no tutorial-only
|
|
159
|
+
endpoint, no direct annotation POST, no `page.evaluate`, no React state
|
|
160
|
+
mutation and no synthetic fixture. The gate passed with zero Observer source
|
|
161
|
+
changes: the two viewer selectors described in section 14 were added
|
|
162
|
+
afterwards, for authoring quality, not to make the gate pass.
|
|
163
|
+
|
|
164
|
+
One measured detail that shaped every scenario: the drawing SVG's bounding box
|
|
165
|
+
maps one-to-one onto the source frame, so a fraction of the element is a
|
|
166
|
+
fraction of the captured viewport. That is why the committed coordinates read
|
|
167
|
+
as sensible positions on the page.
|
|
168
|
+
|
|
169
|
+
## 7. Point / Rectangle / Line / Arrow / Note gesture proof
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
primitive lab action surface locator position specification real Observer draft
|
|
173
|
+
point pointer-click test-id runtime-annotation-surface position (0.33, 0.48) point mark added
|
|
174
|
+
rectangle pointer-drag test-id runtime-annotation-surface (0.24,0.18) -> (0.83,0.36) rectangle mark added
|
|
175
|
+
line pointer-drag test-id runtime-annotation-surface (0.24,0.64) -> (0.80,0.64) line mark added
|
|
176
|
+
arrow pointer-drag test-id runtime-annotation-surface (0.30,0.55) -> (0.62,0.55) arrow mark added
|
|
177
|
+
note pointer-click test-id runtime-annotation-surface position (0.35, 0.77) note mark added with its text
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The same two actions drive the reference surface in scenarios 3 and 4, anchored
|
|
181
|
+
to `test-id reference-annotation-surface`.
|
|
182
|
+
|
|
183
|
+
Every one of the five is exercised again in the committed scenarios, so the
|
|
184
|
+
gate is not a one-off: scenario 1 alone creates all five mark kinds and its
|
|
185
|
+
saved artifact contains `point, rectangle, line, arrow, note`.
|
|
186
|
+
|
|
187
|
+
## 8. Disposable tutorial target architecture
|
|
188
|
+
|
|
189
|
+
Each run gets a lab-owned run root. The lab passes `<runRoot>/target` to the
|
|
190
|
+
prepare command as `{{targetRoot}}`, and prepare builds a complete throwaway
|
|
191
|
+
Observer project inside it:
|
|
192
|
+
|
|
193
|
+
```text
|
|
194
|
+
<targetRoot>/demo/ materialized deterministic demo
|
|
195
|
+
<targetRoot>/demo/server.mjs the demo server the lab then manages
|
|
196
|
+
<targetRoot>/frontend-observer.json canonical project configuration
|
|
197
|
+
<targetRoot>/.frontend-observer/ canonical managed evidence state
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
These are the current canonical Observer paths (`PROJECT_CONFIG_FILENAME` and
|
|
201
|
+
`PROJECT_STATE_DIRECTORY`), not a parallel layout. No second project
|
|
202
|
+
configuration was invented.
|
|
203
|
+
|
|
204
|
+
Nothing is ever written under `examples/v09-demo/`. The demo the lab serves is
|
|
205
|
+
the materialized copy inside the target root, not the tracked template.
|
|
206
|
+
|
|
207
|
+
## 9. Dynamic target-contract generation
|
|
208
|
+
|
|
209
|
+
`examples/v09-demo/scripts/generate-tutorial-target.mjs` writes one contract to
|
|
210
|
+
an explicit `--out` path for an explicit `--scenario`.
|
|
211
|
+
|
|
212
|
+
Ports are discovered with Node built-ins only: a temporary
|
|
213
|
+
`net.Server` bound to `127.0.0.1:0`, the assigned port read back, the listener
|
|
214
|
+
closed. Two ports are taken and checked to be distinct. No dependency was
|
|
215
|
+
added.
|
|
216
|
+
|
|
217
|
+
Closing the probe is unavoidable, and it means a port is only known-free at the
|
|
218
|
+
instant it is chosen; nothing can reserve a TCP port without holding it open.
|
|
219
|
+
The contract is therefore generated immediately before each run, and that
|
|
220
|
+
constraint is documented in the demo README.
|
|
221
|
+
|
|
222
|
+
`--demo-port` and `--viewer-port` pin the ports for deterministic debugging and
|
|
223
|
+
for the generator's own tests. Generated contracts carry absolute paths and
|
|
224
|
+
live ports, so none are committed; only the generator is.
|
|
225
|
+
|
|
226
|
+
The contract declares a `demo-server` process with an HTTP readiness probe on
|
|
227
|
+
`/health`, an `observer-viewer` process with a readiness probe on
|
|
228
|
+
`/api/status`, and an `applicationUrl` pointing at the viewer, which is the
|
|
229
|
+
application the tutorials drive. Both processes use `cwd: "target-root"`, and
|
|
230
|
+
the viewer is started without `--root` so the project-aware session discovers
|
|
231
|
+
the prepared project itself.
|
|
232
|
+
|
|
233
|
+
## 10. Prepare/bootstrap lifecycle
|
|
234
|
+
|
|
235
|
+
`examples/v09-demo/scripts/prepare-tutorial-target.mjs` is the contract's
|
|
236
|
+
trusted prepare executable. It runs once and terminates; it never becomes a
|
|
237
|
+
server.
|
|
238
|
+
|
|
239
|
+
In order:
|
|
240
|
+
|
|
241
|
+
1. validate `--target-root`, `--scenario` and `--demo-port`;
|
|
242
|
+
2. materialize the demo by calling Prompt 1's own `prepareDemoTarget`, so no
|
|
243
|
+
second demo-copy implementation exists;
|
|
244
|
+
3. start Prompt 1's `startDemoServer` in process on the same `demoPort` the lab
|
|
245
|
+
will later use;
|
|
246
|
+
4. `node dist/cli.js init` with the demo URL, the 1440x900 viewport and a
|
|
247
|
+
targets file;
|
|
248
|
+
5. `node dist/cli.js capture baseline`;
|
|
249
|
+
6. scenario-specific evidence;
|
|
250
|
+
7. stop the temporary server in a `finally`.
|
|
251
|
+
|
|
252
|
+
The temporary server exists because Observer's canonical `init` and `capture`
|
|
253
|
+
need a live loopback target. Stopping it in a `finally` means a failing prepare
|
|
254
|
+
still releases the port, which a test verifies by rebinding that exact port
|
|
255
|
+
after prepare returns.
|
|
256
|
+
|
|
257
|
+
Every artifact comes from a canonical owner. Prepare authors contract JSON only
|
|
258
|
+
as *input* to `approve-baseline` and `save-change-contract`, which are what
|
|
259
|
+
validate and persist the artifacts; it never writes an artifact manifest
|
|
260
|
+
itself.
|
|
261
|
+
|
|
262
|
+
## 11. Baseline observation setup
|
|
263
|
+
|
|
264
|
+
`capture baseline` is run through the built CLI, and the result is verified
|
|
265
|
+
rather than assumed: the alias `baseline` resolves in the project catalog, the
|
|
266
|
+
observation manifest's `observationId` matches the catalog entry, the
|
|
267
|
+
`screenshot.png` is non-empty, and all ten configured runtime targets report
|
|
268
|
+
`selectionStatus: matched`.
|
|
269
|
+
|
|
270
|
+
The configured targets bind to Prompt 1's stable vocabulary:
|
|
271
|
+
|
|
272
|
+
```text
|
|
273
|
+
header, navigation, hero, sidebar, content, card1, card2, cta, footer, asset
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Observer target names must match `^[A-Za-z0-9_-]{1,64}$`, which has no place
|
|
277
|
+
for a hyphenated `card-1`, so the two card targets are named `card1` and
|
|
278
|
+
`card2` while their selectors remain `[data-demo-target="card-1"]` and
|
|
279
|
+
`[data-demo-target="card-2"]`. That is the only naming adjustment, and it is
|
|
280
|
+
deterministic.
|
|
281
|
+
|
|
282
|
+
## 12. Contract activation setup
|
|
283
|
+
|
|
284
|
+
For `observer-v09-runtime-contract`, prepare additionally approves a baseline
|
|
285
|
+
contract and saves an initial change contract through the canonical commands,
|
|
286
|
+
then writes project acceptance.
|
|
287
|
+
|
|
288
|
+
The acceptance block is written through the canonical
|
|
289
|
+
`validateProjectConfig` owner: the configuration is read, extended,
|
|
290
|
+
revalidated and only then written back, so an invalid acceptance block can
|
|
291
|
+
never reach disk.
|
|
292
|
+
|
|
293
|
+
One correction was needed during implementation. `--output` names a *parent*
|
|
294
|
+
directory and the writer creates the artifact directory beneath it, so
|
|
295
|
+
acceptance must point at the artifact directory, not the output argument.
|
|
296
|
+
Pointing at the parent produced a genuine runtime refusal from the promotion
|
|
297
|
+
service ("the configured baseline contract is missing or invalid"). The real
|
|
298
|
+
persisted paths are now read back from the CLI's own `Artifact:` output and
|
|
299
|
+
converted to portable project-relative paths.
|
|
300
|
+
|
|
301
|
+
After the tutorial promotes and activates, the canonical check in section 21
|
|
302
|
+
confirms the baseline entry is untouched and only the change entry moved.
|
|
303
|
+
|
|
304
|
+
## 13. External-reference setup
|
|
305
|
+
|
|
306
|
+
For both reference scenarios, prepare imports the fixed Prompt 1 asset
|
|
307
|
+
`examples/v09-demo/references/v09-reference.png` through `import-reference`
|
|
308
|
+
with a `--label` of `v09-tutorial-reference`, then approves it through
|
|
309
|
+
`approve-reference`. No external-reference manifest is handwritten.
|
|
310
|
+
|
|
311
|
+
Regions come from a new tracked fixture,
|
|
312
|
+
`examples/v09-demo/references/v09-reference-regions.json`, holding seven
|
|
313
|
+
regions: `header, hero, sidebar, content, cta, asset, footer`.
|
|
314
|
+
|
|
315
|
+
The geometry was not guessed. The committed PNG's dimensions were read from its
|
|
316
|
+
own IHDR chunk and confirmed to be 1440x900, and the rectangles were then
|
|
317
|
+
measured from the demo's `reference` state in real Chromium at that exact
|
|
318
|
+
viewport. Because the PNG is a 1:1 viewport capture, reference-image pixels
|
|
319
|
+
equal that state's rendered geometry. Every rectangle is integral and inside
|
|
320
|
+
the image bounds. A test re-derives the digest of the committed PNG and
|
|
321
|
+
asserts the imported artifact carries exactly those bytes and those region ids.
|
|
322
|
+
|
|
323
|
+
Applicability was left undeclared. The importer does not require it here, and
|
|
324
|
+
inventing a theme or application state merely for completeness would have been
|
|
325
|
+
fabricated metadata.
|
|
326
|
+
|
|
327
|
+
## 14. Viewer selector stabilization
|
|
328
|
+
|
|
329
|
+
Two selectors were added, one per annotation drawing surface:
|
|
330
|
+
|
|
331
|
+
```text
|
|
332
|
+
data-testid="runtime-annotation-surface" the observation drawing surface
|
|
333
|
+
data-testid="reference-annotation-surface" the reference drawing surface
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The entire production diff under `viewer/src/` is 18 added lines across four
|
|
337
|
+
files and zero deleted lines: an optional `surfaceTestId` prop on
|
|
338
|
+
`TargetOverlaySvg` and `ReferenceRegionOverlaySvg`, rendered as `data-testid`
|
|
339
|
+
only when supplied, plus the two call sites that supply it.
|
|
340
|
+
|
|
341
|
+
The prop is optional on purpose. `TargetOverlaySvg` is also rendered twice
|
|
342
|
+
side by side in the comparison workspace, where one shared test id would be
|
|
343
|
+
ambiguous, so only the annotation-capable workspace supplies one. A test
|
|
344
|
+
asserts exactly one of each id is ever present.
|
|
345
|
+
|
|
346
|
+
Everything else in the scenarios uses existing accessibility, in the priority
|
|
347
|
+
order the task sets: `role` plus accessible name wherever possible
|
|
348
|
+
(`Rectangle mode`, `Associate target hero`, `Select reference region sidebar`,
|
|
349
|
+
`observation baseline`), existing stable data attributes for status
|
|
350
|
+
(`data-draft-item-count`, `data-interpretation-state`, `data-activation-state`,
|
|
351
|
+
`data-materialized-lifecycle`), and deliberate stable classes for a few status
|
|
352
|
+
paragraphs. No selector binds to a generated identifier, and a test enforces
|
|
353
|
+
that by rejecting any 32-character hex run, any `annotation-item-` prefix and
|
|
354
|
+
any `:nth-child` anywhere in the four scenarios.
|
|
355
|
+
|
|
356
|
+
No behavior branch, no tutorial-only control, no hidden button and no alternate
|
|
357
|
+
code path was added. A test drives a real drawing gesture through the newly
|
|
358
|
+
identified surface to prove the attribute changed nothing.
|
|
359
|
+
|
|
360
|
+
## 15. Annotation basics scenario
|
|
361
|
+
|
|
362
|
+
`observer-v09-annotation-basics`, 27 steps.
|
|
363
|
+
|
|
364
|
+
Covers the project-aware viewer, selecting the baseline observation by its
|
|
365
|
+
human alias, Select and Pan modes, all five mark kinds, explicit target
|
|
366
|
+
association, save, reload, and reopening the saved annotation as a revision.
|
|
367
|
+
|
|
368
|
+
The narration teaches that a mark is evidence rather than a requirement; that
|
|
369
|
+
drawing over a target does not associate it, because overlap genuinely is
|
|
370
|
+
ambiguous; that Select and Pan are separate so one drag is never ambiguous;
|
|
371
|
+
that saving produces immutable evidence; and that editing produces a revision
|
|
372
|
+
rather than a rewrite.
|
|
373
|
+
|
|
374
|
+
The arrow step already plants the idea the next tutorial proves: a drawn
|
|
375
|
+
direction is a fact about the drawing, not an instruction about the layout.
|
|
376
|
+
|
|
377
|
+
One real authoring defect was found and fixed here rather than worked around.
|
|
378
|
+
The arrow originally crossed the rectangle's clickable centre, so selecting the
|
|
379
|
+
rectangle failed with a genuine pointer interception. The arrow was moved to
|
|
380
|
+
the card row.
|
|
381
|
+
|
|
382
|
+
## 16. Runtime intent and contract scenario
|
|
383
|
+
|
|
384
|
+
`observer-v09-runtime-contract`, 106 steps.
|
|
385
|
+
|
|
386
|
+
Demonstrates all five operations, `inspect`, `move`, `resize`, `preserve` and
|
|
387
|
+
`remove`, and all four authorable categories, `requested`,
|
|
388
|
+
`expected-dependent` with mode `required`, `protected` and `preserved`. The
|
|
389
|
+
narration states plainly that `unexpected` is not authorable, because it is
|
|
390
|
+
something Observer concludes when comparing runs, never something a person
|
|
391
|
+
declares in advance.
|
|
392
|
+
|
|
393
|
+
The required mappings are all shown as real structured output:
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
Move Right -> property-increases hero.x
|
|
397
|
+
Resize Wider -> property-increases sidebar.width
|
|
398
|
+
Preserve property -> property-unchanged-within-tolerance footer.y
|
|
399
|
+
Preserve relationship -> relationship-unchanged
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
Arrow non-inference is demonstrated, not merely narrated: the arrow is drawn
|
|
403
|
+
pointing left, the move direction `right` is chosen explicitly, and the
|
|
404
|
+
scenario asserts the resulting primitive is `property-increases` on
|
|
405
|
+
`"property": "x"` for `"target": "hero"`.
|
|
406
|
+
|
|
407
|
+
Confirmation invalidation is shown by retargeting a confirmed intent from
|
|
408
|
+
`hero` to `content`: the primitive follows the new association and the
|
|
409
|
+
interpretation drops back to `candidate`, which the scenario asserts. The
|
|
410
|
+
subject is then restored and reconfirmed.
|
|
411
|
+
|
|
412
|
+
`Remove` is confirmed and then shown to be unpromotable, with the product's own
|
|
413
|
+
words asserted: the vocabulary has "no target-absent primitive". `Inspect` is
|
|
414
|
+
confirmed and shown to be informational for good.
|
|
415
|
+
|
|
416
|
+
Selective promotion picks two of four confirmed intents by their deterministic
|
|
417
|
+
human-readable labels, and activation is a separate explicit checkbox. The
|
|
418
|
+
promotion result is asserted to report `2 clauses` and
|
|
419
|
+
`Activation: activated`.
|
|
420
|
+
|
|
421
|
+
Two real defects were found and fixed while making this run: the evidence-list
|
|
422
|
+
locator `baseline` became ambiguous once a contract path also contained the
|
|
423
|
+
word, and a perfectly horizontal line has a zero-height bounding box that
|
|
424
|
+
Playwright treats as invisible. The locator is now `observation baseline` and
|
|
425
|
+
the line is drawn diagonally.
|
|
426
|
+
|
|
427
|
+
## 17. Reference authoring scenario
|
|
428
|
+
|
|
429
|
+
`observer-v09-reference-authoring`, 64 steps.
|
|
430
|
+
|
|
431
|
+
Covers reference-image coordinates, explicit region association, candidate
|
|
432
|
+
region create and refine, all three requirement subject kinds, informational
|
|
433
|
+
intent, asset-sensitive intent, confirmation and save.
|
|
434
|
+
|
|
435
|
+
The coordinate distinction is asserted, not just narrated: the surface's
|
|
436
|
+
accessible name is checked to be exactly `Reference image, 1440 by 900 pixels`,
|
|
437
|
+
and the narration explains these are image pixels and not the runtime CSS
|
|
438
|
+
pixels of a rendered page.
|
|
439
|
+
|
|
440
|
+
The three requirements use real current vocabulary:
|
|
441
|
+
|
|
442
|
+
```text
|
|
443
|
+
region-property hero.width, protected, absolute-reference-px 4
|
|
444
|
+
region-relationship chosen from relationships Observer derived from this
|
|
445
|
+
reference's own geometry, protected
|
|
446
|
+
region-measurement vertical-gap hero to cta, preserved,
|
|
447
|
+
absolute-reference-px 6
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
The relationship is picked from the canonical derived list rather than typed,
|
|
451
|
+
so the scenario cannot require a relationship the image does not contain.
|
|
452
|
+
|
|
453
|
+
Asset-sensitive intent is shown as informational, with the narration
|
|
454
|
+
explaining that an image mattering to a human eye is not the same as a
|
|
455
|
+
checkable geometric claim.
|
|
456
|
+
|
|
457
|
+
The requirement form keeps its previous values when another mark is selected,
|
|
458
|
+
unlike the runtime form which resets. That is existing product behavior and was
|
|
459
|
+
not changed; the scenario steps from the retained value instead, and the demo
|
|
460
|
+
README documents it for anyone editing these files.
|
|
461
|
+
|
|
462
|
+
## 18. Reference materialization scenario
|
|
463
|
+
|
|
464
|
+
`observer-v09-reference-materialization`, 51 steps.
|
|
465
|
+
|
|
466
|
+
From a clean run: open the approved source reference, create a candidate
|
|
467
|
+
region, refine an existing region, author two requirements, confirm all four,
|
|
468
|
+
save, select three of the four, and materialize.
|
|
469
|
+
|
|
470
|
+
Leaving the fourth unselected is the point. It is confirmed and correct and
|
|
471
|
+
simply not part of this revision, which is what makes selection meaningful and
|
|
472
|
+
is verified afterwards by the new revision carrying exactly one requirement.
|
|
473
|
+
|
|
474
|
+
The scenario asserts the product's own bounded evidence before acting, that
|
|
475
|
+
materialization is blocked until the annotation is saved and that the warning
|
|
476
|
+
states the current reference remains unchanged and the result is "not approved
|
|
477
|
+
automatically"; and afterwards that the result reports `Lifecycle: imported`,
|
|
478
|
+
`Approval required: yes`, a `Supersedes:` line and `Requirements: 1`.
|
|
479
|
+
|
|
480
|
+
The final step notes that the viewer did not switch to the new revision, and
|
|
481
|
+
explains why quietly adopting an unapproved reference would make approval
|
|
482
|
+
meaningless. No behavior was changed to make navigation easier.
|
|
483
|
+
|
|
484
|
+
## 19. Lab scenario validation
|
|
485
|
+
|
|
486
|
+
Every scenario was validated by the real released CLI against a freshly
|
|
487
|
+
generated target contract:
|
|
488
|
+
|
|
489
|
+
```text
|
|
490
|
+
observer-v09-annotation-basics valid targetIdMatches true 27 steps
|
|
491
|
+
observer-v09-runtime-contract valid targetIdMatches true 106 steps
|
|
492
|
+
observer-v09-reference-authoring valid targetIdMatches true 64 steps
|
|
493
|
+
observer-v09-reference-materialization valid targetIdMatches true 51 steps
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
## 20. Real tutorial execution
|
|
497
|
+
|
|
498
|
+
All four executed through `my-dev-kit-lab tutorial run` with real Chromium,
|
|
499
|
+
each into its own run root outside the repository, under
|
|
500
|
+
`%TEMP%\my-frontend-observer-v09-tutorial-smoke\final\`. `Z:` was not available
|
|
501
|
+
on this machine, so the documented fallback was used.
|
|
502
|
+
|
|
503
|
+
```text
|
|
504
|
+
scenario status cleanupErrors failed steps
|
|
505
|
+
observer-v09-annotation-basics passed [] none
|
|
506
|
+
observer-v09-runtime-contract passed [] none
|
|
507
|
+
observer-v09-reference-authoring passed [] none
|
|
508
|
+
observer-v09-reference-materialization passed [] none
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
Every run reported `TutorialRunResultV1` schema `1.0.0`. Each scenario received
|
|
512
|
+
a fresh target root and built its own starting state; no run consumed another
|
|
513
|
+
run's output.
|
|
514
|
+
|
|
515
|
+
## 21. Canonical Observer post-run verification
|
|
516
|
+
|
|
517
|
+
The video is not correctness authority. Each run's disposable target root was
|
|
518
|
+
read directly. All 35 checks passed.
|
|
519
|
+
|
|
520
|
+
Scenario 1: one saved `my-frontend-observer/visual-annotation` artifact,
|
|
521
|
+
schema `1.0.0`, source `runtime-observation` whose `observationId` equals the
|
|
522
|
+
prepared baseline; all five mark kinds present; exactly one explicit
|
|
523
|
+
`runtime-target` association, to `hero`; the other four marks still
|
|
524
|
+
unassociated.
|
|
525
|
+
|
|
526
|
+
Scenario 2: project acceptance still names
|
|
527
|
+
`tutorial-baseline/v09-tutorial-baseline` as `baselineArtifact`, unchanged;
|
|
528
|
+
`changeArtifact` now points at a promoted change contract that is not the
|
|
529
|
+
initial one; that contract has exactly two clauses:
|
|
530
|
+
|
|
531
|
+
```text
|
|
532
|
+
requested:property-increases:hero.x
|
|
533
|
+
expected-dependent:property-increases:sidebar.width
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
Remove did not become a clause, Inspect did not become a clause, and the saved
|
|
537
|
+
annotation still records all six items with all six confirmed, including the
|
|
538
|
+
unpromotable remove and inspect intents.
|
|
539
|
+
|
|
540
|
+
Scenario 3: annotation source is `external-reference`; seven items, all
|
|
541
|
+
confirmed; region `create` and `refine` both present; all three requirement
|
|
542
|
+
subject kinds present; informational and asset-sensitive intents confirmed and
|
|
543
|
+
not materialized; and no new reference revision was created by authoring
|
|
544
|
+
alone, which is the distinction the next tutorial builds on.
|
|
545
|
+
|
|
546
|
+
Scenario 4: exactly one approved reference still exists and no approved
|
|
547
|
+
successor was created; a new imported revision exists whose
|
|
548
|
+
`supersedesReferenceId` equals the approved source's `referenceId`; it carries
|
|
549
|
+
8 regions including `promo-band`, and the refined `sidebar` rectangle really
|
|
550
|
+
differs from the source's; it carries exactly one requirement, the selected
|
|
551
|
+
`hero.width` one, and the unselected footer requirement is absent; the source
|
|
552
|
+
approved reference is unchanged at 7 regions and 0 requirements; and the image
|
|
553
|
+
digest is byte-identical to the committed PNG
|
|
554
|
+
(`4bdb94db1096532d...`), proving the source image is reused and annotation
|
|
555
|
+
marks are not baked into it.
|
|
556
|
+
|
|
557
|
+
## 22. Tutorial artifact inventory
|
|
558
|
+
|
|
559
|
+
Every required artifact was written as a non-empty regular file, and every
|
|
560
|
+
requested screenshot was produced.
|
|
561
|
+
|
|
562
|
+
```text
|
|
563
|
+
scenario video srt vtt markdown manifest screenshots
|
|
564
|
+
observer-v09-annotation-basics 1.8 MB 3.0 kB 2.9 kB 3.2 kB 24.6 kB 9 of 9
|
|
565
|
+
observer-v09-runtime-contract 5.5 MB 11.3 kB 11.0 kB 12.0 kB 66.3 kB 13 of 13
|
|
566
|
+
observer-v09-reference-authoring 3.8 MB 7.5 kB 7.3 kB 8.0 kB 42.9 kB 8 of 8
|
|
567
|
+
observer-v09-reference-materialization 2.8 MB 4.5 kB 4.4 kB 4.7 kB 32.8 kB 6 of 6
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
All four manifests declare `TutorialManifestV1` schema `1.0.0`.
|
|
571
|
+
|
|
572
|
+
No generated artifact is tracked. Videos, screenshots, subtitles, Markdown,
|
|
573
|
+
manifests, generated target contracts, target roots and logs all live outside
|
|
574
|
+
the repository or under the git-ignored workflow root. Prompt 3 owns the human
|
|
575
|
+
review of these artifacts and any decision to retain some of them.
|
|
576
|
+
|
|
577
|
+
## 23. Source/demo immutability
|
|
578
|
+
|
|
579
|
+
A SHA-256 digest of all 19 tracked files under `examples/v09-demo/` was taken
|
|
580
|
+
after implementation was complete and immediately before the four final runs,
|
|
581
|
+
and recomputed after all four finished.
|
|
582
|
+
|
|
583
|
+
```text
|
|
584
|
+
demoSourceImmutable: true
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
Tutorial execution mutated nothing in the tracked template. The bootstrap test
|
|
588
|
+
independently fingerprints the template around a real prepare and asserts the
|
|
589
|
+
same thing, and the Prompt 1 materialization test continues to prove the
|
|
590
|
+
template survives a destructive rematerialization.
|
|
591
|
+
|
|
592
|
+
## 24. Full Observer regression
|
|
593
|
+
|
|
594
|
+
```text
|
|
595
|
+
npm run typecheck PASS
|
|
596
|
+
npm run lint PASS
|
|
597
|
+
npm test PASS (89 files, 1451 tests)
|
|
598
|
+
npm run test:browser PASS (29 files, 275 tests)
|
|
599
|
+
npm run test:security PASS (16 files / 167 tests, then 3 files / 77 tests)
|
|
600
|
+
npm run build PASS
|
|
601
|
+
npm run check:docs PASS (17 required files)
|
|
602
|
+
npm pack --dry-run PASS (0.8.1, 364 files, 0 examples/ entries)
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
New tests added by this stage:
|
|
606
|
+
|
|
607
|
+
- `tests/unit/v09TutorialTargetContract.test.ts` (16 tests): released schema
|
|
608
|
+
version, exact target id shared by all four scenarios, only keys the
|
|
609
|
+
released validator accepts, no shell-like field, `{{targetRoot}}` as the only
|
|
610
|
+
placeholder, demo readiness on `/health`, viewer readiness on `/api/status`,
|
|
611
|
+
`applicationUrl` pointing at the viewer, loopback-only urls, rejection of an
|
|
612
|
+
unknown scenario and of invalid or identical ports, determinism for explicit
|
|
613
|
+
ports, and two distinct free ports when none are given.
|
|
614
|
+
- `tests/unit/v09TutorialScenarios.test.ts` (10 tests): exactly four files,
|
|
615
|
+
released schema version, unique ids in order, one shared target id,
|
|
616
|
+
1440x900 viewport, non-empty narration on every step, only released
|
|
617
|
+
actions/locators/assertions, in-bounds non-degenerate pointer fractions,
|
|
618
|
+
never using element-to-element `drag` for drawing, no Observer-only field, no
|
|
619
|
+
absolute path, and no selector bound to a generated identifier. It
|
|
620
|
+
deliberately does not reimplement the lab validator, which is run separately.
|
|
621
|
+
- `tests/browser/v09TutorialBootstrap.test.ts` (17 tests): real prepare runs
|
|
622
|
+
with real Chromium capture, proving materialization, canonical project
|
|
623
|
+
initialization, target binding to the demo vocabulary, baseline capture with
|
|
624
|
+
all ten targets matched, the temporary server releasing its port, contract
|
|
625
|
+
acceptance with valid baseline and change contracts tied to the captured
|
|
626
|
+
observation, canonical reference import and approval with a digest match
|
|
627
|
+
against the committed PNG, and template immutability.
|
|
628
|
+
- `tests/browser/v09ViewerTutorialSelectors.test.ts` (6 tests): each new test
|
|
629
|
+
id present exactly once in the state a tutorial uses it in, on the real SVG
|
|
630
|
+
surface, with its pre-existing role, accessible name and class untouched,
|
|
631
|
+
present across every interaction mode, still drawing correctly, and never
|
|
632
|
+
duplicated.
|
|
633
|
+
|
|
634
|
+
One existing test was updated rather than weakened:
|
|
635
|
+
`tests/unit/v09DemoMaterialization.test.ts` pinned the demo template's
|
|
636
|
+
top-level entries, which legitimately gained `tutorials/`. No test was skipped,
|
|
637
|
+
deleted or made permissive, and no `.skip`, `.only`, `continue-on-error` or
|
|
638
|
+
`|| true` was introduced.
|
|
639
|
+
|
|
640
|
+
## 25. Scope audit
|
|
641
|
+
|
|
642
|
+
All of the following are `false`:
|
|
643
|
+
|
|
644
|
+
```text
|
|
645
|
+
Observer tutorial runtime implemented false
|
|
646
|
+
Observer Playwright loader added false
|
|
647
|
+
Observer browser recorder added false
|
|
648
|
+
Observer subtitle writer added false
|
|
649
|
+
Observer tutorial-manifest schema added false
|
|
650
|
+
Observer cursor implementation added false
|
|
651
|
+
Observer callout renderer added false
|
|
652
|
+
Observer arbitrary tutorial JavaScript added false
|
|
653
|
+
Observer product semantics changed false
|
|
654
|
+
annotation schema changed false
|
|
655
|
+
contract schema changed false
|
|
656
|
+
reference schema changed false
|
|
657
|
+
package version changed false
|
|
658
|
+
dependency added false
|
|
659
|
+
my-dev-kit-lab modified false
|
|
660
|
+
v0.9 released false
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
`package.json` and `package-lock.json` are untouched. The dependency set is
|
|
664
|
+
still exactly `playwright`; `@dailephd/my-dev-kit-lab` appears in neither
|
|
665
|
+
`dependencies` nor `devDependencies`, and is invoked only as an external tool
|
|
666
|
+
through `npx`.
|
|
667
|
+
|
|
668
|
+
`src/` is unchanged. The only production change is the 18-line additive viewer
|
|
669
|
+
selector diff in section 14.
|
|
670
|
+
|
|
671
|
+
`examples/v09-demo` was deliberately not added to `package.json#files`; a pack
|
|
672
|
+
dry run confirms zero `examples/` entries. Prompt 3 owns that decision.
|
|
673
|
+
|
|
674
|
+
Documentation scope was respected: only `examples/v09-demo/README.md` and this
|
|
675
|
+
report were written.
|
|
676
|
+
|
|
677
|
+
## 26. Changed files
|
|
678
|
+
|
|
679
|
+
Added:
|
|
680
|
+
|
|
681
|
+
```text
|
|
682
|
+
examples/v09-demo/scripts/generate-tutorial-target.mjs
|
|
683
|
+
examples/v09-demo/scripts/prepare-tutorial-target.mjs
|
|
684
|
+
examples/v09-demo/references/v09-reference-regions.json
|
|
685
|
+
examples/v09-demo/tutorials/01-annotation-basics.json
|
|
686
|
+
examples/v09-demo/tutorials/02-runtime-intent-contract.json
|
|
687
|
+
examples/v09-demo/tutorials/03-reference-authoring.json
|
|
688
|
+
examples/v09-demo/tutorials/04-reference-materialization.json
|
|
689
|
+
tests/unit/v09TutorialTargetContract.test.ts
|
|
690
|
+
tests/unit/v09TutorialScenarios.test.ts
|
|
691
|
+
tests/browser/v09TutorialBootstrap.test.ts
|
|
692
|
+
tests/browser/v09ViewerTutorialSelectors.test.ts
|
|
693
|
+
docs/reports/v0.9-tutorial-integration.md
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
Modified:
|
|
697
|
+
|
|
698
|
+
```text
|
|
699
|
+
examples/v09-demo/README.md developer tutorial section
|
|
700
|
+
viewer/src/components/TargetOverlaySvg.tsx optional surfaceTestId prop
|
|
701
|
+
viewer/src/components/ReferenceRegionOverlaySvg.tsx optional surfaceTestId prop
|
|
702
|
+
viewer/src/components/ObservationWorkspace.tsx supplies the runtime id
|
|
703
|
+
viewer/src/components/ReferenceWorkspace.tsx supplies the reference id
|
|
704
|
+
tests/unit/v09DemoMaterialization.test.ts template inventory now includes tutorials/
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Generated paths, all git-ignored or outside the repository:
|
|
708
|
+
|
|
709
|
+
```text
|
|
710
|
+
.my-dev-kit-workflow/v0.9/tutorial-integration/ generated contracts, probes, smoke results
|
|
711
|
+
%TEMP%/my-frontend-observer-v09-tutorial-smoke/ tutorial run roots and artifacts
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
`git diff --check` reports no whitespace problems, and `git status --short`
|
|
715
|
+
shows no generated tutorial artifact in tracked source.
|
|
716
|
+
|
|
717
|
+
## 27. Remaining Prompt 3 work
|
|
718
|
+
|
|
719
|
+
Prompt 3 owns end-to-end tutorial acceptance, human review of the four videos,
|
|
720
|
+
subtitles and Markdown, documentation reconciliation across the release-facing
|
|
721
|
+
documents, the decision on whether `examples/v09-demo` ships inside `0.9.0`,
|
|
722
|
+
and the final release regression.
|
|
723
|
+
|
|
724
|
+
Two things are worth carrying forward. The scenarios drive native `<select>`
|
|
725
|
+
controls with `ArrowDown` presses because the lab has no select action, so the
|
|
726
|
+
press counts follow the order of Observer's frozen intent vocabularies and will
|
|
727
|
+
need updating if one of those lists gains a member; this is documented in the
|
|
728
|
+
demo README. And free-port discovery cannot hold a port, so a target contract
|
|
729
|
+
should always be generated immediately before its run.
|
|
730
|
+
|
|
731
|
+
No blocker remains.
|