@dailephd/my-frontend-observer 0.8.1
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 +397 -0
- package/LICENSE +21 -0
- package/README.md +255 -0
- package/dist/application/browserCaptureService.d.ts +11 -0
- package/dist/application/browserCaptureService.js +12 -0
- package/dist/application/browserCaptureService.js.map +1 -0
- package/dist/application/comparisonService.d.ts +56 -0
- package/dist/application/comparisonService.js +77 -0
- package/dist/application/comparisonService.js.map +1 -0
- package/dist/application/externalReferencePersistenceService.d.ts +75 -0
- package/dist/application/externalReferencePersistenceService.js +182 -0
- package/dist/application/externalReferencePersistenceService.js.map +1 -0
- package/dist/application/frontendContractEvaluationService.d.ts +49 -0
- package/dist/application/frontendContractEvaluationService.js +112 -0
- package/dist/application/frontendContractEvaluationService.js.map +1 -0
- package/dist/application/frontendContractPersistenceService.d.ts +56 -0
- package/dist/application/frontendContractPersistenceService.js +91 -0
- package/dist/application/frontendContractPersistenceService.js.map +1 -0
- package/dist/application/observationPersistence.d.ts +59 -0
- package/dist/application/observationPersistence.js +79 -0
- package/dist/application/observationPersistence.js.map +1 -0
- package/dist/application/projectCheckService.d.ts +3 -0
- package/dist/application/projectCheckService.js +169 -0
- package/dist/application/projectCheckService.js.map +1 -0
- package/dist/application/projectWorkflowService.d.ts +46 -0
- package/dist/application/projectWorkflowService.js +92 -0
- package/dist/application/projectWorkflowService.js.map +1 -0
- package/dist/application/referenceFidelityEvaluationService.d.ts +28 -0
- package/dist/application/referenceFidelityEvaluationService.js +45 -0
- package/dist/application/referenceFidelityEvaluationService.js.map +1 -0
- package/dist/artifacts/artifactReader.d.ts +19 -0
- package/dist/artifacts/artifactReader.js +36 -0
- package/dist/artifacts/artifactReader.js.map +1 -0
- package/dist/artifacts/artifactWriter.d.ts +25 -0
- package/dist/artifacts/artifactWriter.js +68 -0
- package/dist/artifacts/artifactWriter.js.map +1 -0
- package/dist/artifacts/comparisonArtifactReader.d.ts +18 -0
- package/dist/artifacts/comparisonArtifactReader.js +35 -0
- package/dist/artifacts/comparisonArtifactReader.js.map +1 -0
- package/dist/artifacts/comparisonArtifactWriter.d.ts +41 -0
- package/dist/artifacts/comparisonArtifactWriter.js +67 -0
- package/dist/artifacts/comparisonArtifactWriter.js.map +1 -0
- package/dist/artifacts/externalReferenceArtifactReader.d.ts +18 -0
- package/dist/artifacts/externalReferenceArtifactReader.js +35 -0
- package/dist/artifacts/externalReferenceArtifactReader.js.map +1 -0
- package/dist/artifacts/externalReferenceArtifactWriter.d.ts +44 -0
- package/dist/artifacts/externalReferenceArtifactWriter.js +77 -0
- package/dist/artifacts/externalReferenceArtifactWriter.js.map +1 -0
- package/dist/artifacts/frontendContractArtifactReader.d.ts +24 -0
- package/dist/artifacts/frontendContractArtifactReader.js +47 -0
- package/dist/artifacts/frontendContractArtifactReader.js.map +1 -0
- package/dist/artifacts/frontendContractArtifactWriter.d.ts +34 -0
- package/dist/artifacts/frontendContractArtifactWriter.js +70 -0
- package/dist/artifacts/frontendContractArtifactWriter.js.map +1 -0
- package/dist/artifacts/frontendContractEvaluationArtifactReader.d.ts +17 -0
- package/dist/artifacts/frontendContractEvaluationArtifactReader.js +34 -0
- package/dist/artifacts/frontendContractEvaluationArtifactReader.js.map +1 -0
- package/dist/artifacts/frontendContractEvaluationArtifactWriter.d.ts +32 -0
- package/dist/artifacts/frontendContractEvaluationArtifactWriter.js +58 -0
- package/dist/artifacts/frontendContractEvaluationArtifactWriter.js.map +1 -0
- package/dist/artifacts/types.d.ts +17 -0
- package/dist/artifacts/types.js +2 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/browser/chromiumAdapter.d.ts +21 -0
- package/dist/browser/chromiumAdapter.js +204 -0
- package/dist/browser/chromiumAdapter.js.map +1 -0
- package/dist/browser/evidenceCapture.d.ts +62 -0
- package/dist/browser/evidenceCapture.js +500 -0
- package/dist/browser/evidenceCapture.js.map +1 -0
- package/dist/browser/scrollCapture.d.ts +32 -0
- package/dist/browser/scrollCapture.js +163 -0
- package/dist/browser/scrollCapture.js.map +1 -0
- package/dist/browser/types.d.ts +24 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +2411 -0
- package/dist/cli.js.map +1 -0
- package/dist/domain/boundedAgentContext.d.ts +226 -0
- package/dist/domain/boundedAgentContext.js +355 -0
- package/dist/domain/boundedAgentContext.js.map +1 -0
- package/dist/domain/boundedAgentContextCorrelation.d.ts +74 -0
- package/dist/domain/boundedAgentContextCorrelation.js +441 -0
- package/dist/domain/boundedAgentContextCorrelation.js.map +1 -0
- package/dist/domain/boundedAgentContextIdentity.d.ts +26 -0
- package/dist/domain/boundedAgentContextIdentity.js +69 -0
- package/dist/domain/boundedAgentContextIdentity.js.map +1 -0
- package/dist/domain/boundedAgentContextProjection.d.ts +71 -0
- package/dist/domain/boundedAgentContextProjection.js +477 -0
- package/dist/domain/boundedAgentContextProjection.js.map +1 -0
- package/dist/domain/comparison.d.ts +220 -0
- package/dist/domain/comparison.js +350 -0
- package/dist/domain/comparison.js.map +1 -0
- package/dist/domain/comparisonEngine.d.ts +76 -0
- package/dist/domain/comparisonEngine.js +734 -0
- package/dist/domain/comparisonEngine.js.map +1 -0
- package/dist/domain/comparisonIdentity.d.ts +13 -0
- package/dist/domain/comparisonIdentity.js +46 -0
- package/dist/domain/comparisonIdentity.js.map +1 -0
- package/dist/domain/completion.d.ts +30 -0
- package/dist/domain/completion.js +22 -0
- package/dist/domain/completion.js.map +1 -0
- package/dist/domain/diagnostics.d.ts +17 -0
- package/dist/domain/diagnostics.js +77 -0
- package/dist/domain/diagnostics.js.map +1 -0
- package/dist/domain/evidence.d.ts +29 -0
- package/dist/domain/evidence.js +59 -0
- package/dist/domain/evidence.js.map +1 -0
- package/dist/domain/explicitState.d.ts +40 -0
- package/dist/domain/explicitState.js +54 -0
- package/dist/domain/explicitState.js.map +1 -0
- package/dist/domain/externalReference.d.ts +158 -0
- package/dist/domain/externalReference.js +167 -0
- package/dist/domain/externalReference.js.map +1 -0
- package/dist/domain/externalReferenceApplicability.d.ts +43 -0
- package/dist/domain/externalReferenceApplicability.js +52 -0
- package/dist/domain/externalReferenceApplicability.js.map +1 -0
- package/dist/domain/externalReferenceCompatibility.d.ts +40 -0
- package/dist/domain/externalReferenceCompatibility.js +48 -0
- package/dist/domain/externalReferenceCompatibility.js.map +1 -0
- package/dist/domain/externalReferenceFidelity.d.ts +171 -0
- package/dist/domain/externalReferenceFidelity.js +419 -0
- package/dist/domain/externalReferenceFidelity.js.map +1 -0
- package/dist/domain/externalReferenceIdentity.d.ts +38 -0
- package/dist/domain/externalReferenceIdentity.js +70 -0
- package/dist/domain/externalReferenceIdentity.js.map +1 -0
- package/dist/domain/externalReferenceImage.d.ts +35 -0
- package/dist/domain/externalReferenceImage.js +160 -0
- package/dist/domain/externalReferenceImage.js.map +1 -0
- package/dist/domain/externalReferenceRegionRelationships.d.ts +63 -0
- package/dist/domain/externalReferenceRegionRelationships.js +98 -0
- package/dist/domain/externalReferenceRegionRelationships.js.map +1 -0
- package/dist/domain/externalReferenceRegions.d.ts +65 -0
- package/dist/domain/externalReferenceRegions.js +105 -0
- package/dist/domain/externalReferenceRegions.js.map +1 -0
- package/dist/domain/externalReferenceRequirementIdentity.d.ts +12 -0
- package/dist/domain/externalReferenceRequirementIdentity.js +35 -0
- package/dist/domain/externalReferenceRequirementIdentity.js.map +1 -0
- package/dist/domain/externalReferenceRequirements.d.ts +215 -0
- package/dist/domain/externalReferenceRequirements.js +401 -0
- package/dist/domain/externalReferenceRequirements.js.map +1 -0
- package/dist/domain/externalReferenceRuntimeBinding.d.ts +146 -0
- package/dist/domain/externalReferenceRuntimeBinding.js +183 -0
- package/dist/domain/externalReferenceRuntimeBinding.js.map +1 -0
- package/dist/domain/frontendContractEvaluation.d.ts +57 -0
- package/dist/domain/frontendContractEvaluation.js +454 -0
- package/dist/domain/frontendContractEvaluation.js.map +1 -0
- package/dist/domain/frontendContractEvaluationArtifact.d.ts +65 -0
- package/dist/domain/frontendContractEvaluationArtifact.js +108 -0
- package/dist/domain/frontendContractEvaluationArtifact.js.map +1 -0
- package/dist/domain/frontendContractIdentity.d.ts +39 -0
- package/dist/domain/frontendContractIdentity.js +70 -0
- package/dist/domain/frontendContractIdentity.js.map +1 -0
- package/dist/domain/frontendContracts.d.ts +188 -0
- package/dist/domain/frontendContracts.js +260 -0
- package/dist/domain/frontendContracts.js.map +1 -0
- package/dist/domain/identity.d.ts +21 -0
- package/dist/domain/identity.js +47 -0
- package/dist/domain/identity.js.map +1 -0
- package/dist/domain/referenceCorrectionIdentity.d.ts +40 -0
- package/dist/domain/referenceCorrectionIdentity.js +77 -0
- package/dist/domain/referenceCorrectionIdentity.js.map +1 -0
- package/dist/domain/referenceCorrectionWorkflow.d.ts +160 -0
- package/dist/domain/referenceCorrectionWorkflow.js +165 -0
- package/dist/domain/referenceCorrectionWorkflow.js.map +1 -0
- package/dist/domain/referenceFidelityProjection.d.ts +65 -0
- package/dist/domain/referenceFidelityProjection.js +135 -0
- package/dist/domain/referenceFidelityProjection.js.map +1 -0
- package/dist/domain/relationships.d.ts +210 -0
- package/dist/domain/relationships.js +352 -0
- package/dist/domain/relationships.js.map +1 -0
- package/dist/domain/schema.d.ts +269 -0
- package/dist/domain/schema.js +442 -0
- package/dist/domain/schema.js.map +1 -0
- package/dist/domain/scrollEvidence.d.ts +51 -0
- package/dist/domain/scrollEvidence.js +134 -0
- package/dist/domain/scrollEvidence.js.map +1 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/projectWorkflow/aliasCatalog.d.ts +21 -0
- package/dist/projectWorkflow/aliasCatalog.js +67 -0
- package/dist/projectWorkflow/aliasCatalog.js.map +1 -0
- package/dist/projectWorkflow/checkAcceptance.d.ts +25 -0
- package/dist/projectWorkflow/checkAcceptance.js +55 -0
- package/dist/projectWorkflow/checkAcceptance.js.map +1 -0
- package/dist/projectWorkflow/checkResult.d.ts +85 -0
- package/dist/projectWorkflow/checkResult.js +101 -0
- package/dist/projectWorkflow/checkResult.js.map +1 -0
- package/dist/projectWorkflow/projectConfig.d.ts +43 -0
- package/dist/projectWorkflow/projectConfig.js +84 -0
- package/dist/projectWorkflow/projectConfig.js.map +1 -0
- package/dist/projectWorkflow/projectDiscovery.d.ts +9 -0
- package/dist/projectWorkflow/projectDiscovery.js +20 -0
- package/dist/projectWorkflow/projectDiscovery.js.map +1 -0
- package/dist/projectWorkflow/projectPaths.d.ts +8 -0
- package/dist/projectWorkflow/projectPaths.js +23 -0
- package/dist/projectWorkflow/projectPaths.js.map +1 -0
- package/dist/request/paths.d.ts +14 -0
- package/dist/request/paths.js +33 -0
- package/dist/request/paths.js.map +1 -0
- package/dist/request/request.d.ts +111 -0
- package/dist/request/request.js +464 -0
- package/dist/request/request.js.map +1 -0
- package/dist/safety/policy.d.ts +14 -0
- package/dist/safety/policy.js +81 -0
- package/dist/safety/policy.js.map +1 -0
- package/dist/viewer/assets/index-CN_yb9Uf.css +1 -0
- package/dist/viewer/assets/index-D98S1_2d.js +9 -0
- package/dist/viewer/icons/icon-192.png +0 -0
- package/dist/viewer/icons/icon-512.png +0 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/manifest.webmanifest +1 -0
- package/dist/viewer/registerSW.js +1 -0
- package/dist/viewer/sw.js +1 -0
- package/dist/viewer/workbox-9c191d2f.js +1 -0
- package/dist/viewerServer/context.d.ts +48 -0
- package/dist/viewerServer/context.js +60 -0
- package/dist/viewerServer/context.js.map +1 -0
- package/dist/viewerServer/evidence/classify.d.ts +59 -0
- package/dist/viewerServer/evidence/classify.js +124 -0
- package/dist/viewerServer/evidence/classify.js.map +1 -0
- package/dist/viewerServer/evidence/comparisonView.d.ts +28 -0
- package/dist/viewerServer/evidence/comparisonView.js +43 -0
- package/dist/viewerServer/evidence/comparisonView.js.map +1 -0
- package/dist/viewerServer/evidence/contextSourceView.d.ts +25 -0
- package/dist/viewerServer/evidence/contextSourceView.js +20 -0
- package/dist/viewerServer/evidence/contextSourceView.js.map +1 -0
- package/dist/viewerServer/evidence/discovery.d.ts +31 -0
- package/dist/viewerServer/evidence/discovery.js +78 -0
- package/dist/viewerServer/evidence/discovery.js.map +1 -0
- package/dist/viewerServer/evidence/evaluationView.d.ts +32 -0
- package/dist/viewerServer/evidence/evaluationView.js +50 -0
- package/dist/viewerServer/evidence/evaluationView.js.map +1 -0
- package/dist/viewerServer/evidence/handles.d.ts +21 -0
- package/dist/viewerServer/evidence/handles.js +43 -0
- package/dist/viewerServer/evidence/handles.js.map +1 -0
- package/dist/viewerServer/evidence/index.d.ts +41 -0
- package/dist/viewerServer/evidence/index.js +82 -0
- package/dist/viewerServer/evidence/index.js.map +1 -0
- package/dist/viewerServer/evidence/limits.d.ts +27 -0
- package/dist/viewerServer/evidence/limits.js +28 -0
- package/dist/viewerServer/evidence/limits.js.map +1 -0
- package/dist/viewerServer/evidence/linkedEvidence.d.ts +43 -0
- package/dist/viewerServer/evidence/linkedEvidence.js +151 -0
- package/dist/viewerServer/evidence/linkedEvidence.js.map +1 -0
- package/dist/viewerServer/evidence/mediaResolver.d.ts +16 -0
- package/dist/viewerServer/evidence/mediaResolver.js +85 -0
- package/dist/viewerServer/evidence/mediaResolver.js.map +1 -0
- package/dist/viewerServer/evidence/observationView.d.ts +29 -0
- package/dist/viewerServer/evidence/observationView.js +46 -0
- package/dist/viewerServer/evidence/observationView.js.map +1 -0
- package/dist/viewerServer/evidence/pathSafety.d.ts +11 -0
- package/dist/viewerServer/evidence/pathSafety.js +31 -0
- package/dist/viewerServer/evidence/pathSafety.js.map +1 -0
- package/dist/viewerServer/evidence/projection.d.ts +55 -0
- package/dist/viewerServer/evidence/projection.js +152 -0
- package/dist/viewerServer/evidence/projection.js.map +1 -0
- package/dist/viewerServer/evidence/referenceView.d.ts +133 -0
- package/dist/viewerServer/evidence/referenceView.js +169 -0
- package/dist/viewerServer/evidence/referenceView.js.map +1 -0
- package/dist/viewerServer/httpServer.d.ts +27 -0
- package/dist/viewerServer/httpServer.js +381 -0
- package/dist/viewerServer/httpServer.js.map +1 -0
- package/dist/viewerServer/openBrowser.d.ts +7 -0
- package/dist/viewerServer/openBrowser.js +32 -0
- package/dist/viewerServer/openBrowser.js.map +1 -0
- package/dist/viewerServer/port.d.ts +16 -0
- package/dist/viewerServer/port.js +19 -0
- package/dist/viewerServer/port.js.map +1 -0
- package/dist/viewerServer/viewerService.d.ts +62 -0
- package/dist/viewerServer/viewerService.js +88 -0
- package/dist/viewerServer/viewerService.js.map +1 -0
- package/docs/ARCHITECTURE.md +1286 -0
- package/docs/CI_CD.md +250 -0
- package/docs/COMMANDS.md +972 -0
- package/docs/CONTRACTS.md +1856 -0
- package/docs/CURRENT_STATE.md +1049 -0
- package/docs/DEVELOPMENT.md +202 -0
- package/docs/DOCUMENTATION_PRESERVATION_POLICY.md +50 -0
- package/docs/PROJECT_DESCRIPTION.md +2221 -0
- package/docs/PROJECT_MILESTONES.md +2526 -0
- package/docs/PROJECT_OVERVIEW.md +150 -0
- package/docs/QUICKSTART.md +83 -0
- package/docs/RELEASE.md +27 -0
- package/docs/ROADMAP.md +641 -0
- package/docs/SECURITY.md +218 -0
- package/docs/WORKFLOWS.md +642 -0
- package/docs/plans/v0.8-implementation-plan.md +655 -0
- package/docs/plans/v0.8.1-cli-usability-patch-plan.md +505 -0
- package/docs/reports/v0.7-bounded-fidelity-context-prompt7.md +243 -0
- package/docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md +497 -0
- package/docs/reports/v0.7-pre-release-readiness.md +337 -0
- package/docs/reports/v0.7-reference-binding-prompt5.md +223 -0
- package/docs/reports/v0.7-reference-compatibility-prompt4.md +234 -0
- package/docs/reports/v0.7-reference-correction-workflow-prompt8.md +222 -0
- package/docs/reports/v0.7-reference-fidelity-prompt6.md +216 -0
- package/docs/reports/v0.7-reference-foundation-prompt1.md +151 -0
- package/docs/reports/v0.7-reference-regions-prompt2.md +195 -0
- package/docs/reports/v0.7-reference-requirements-prompt3.md +217 -0
- package/docs/reports/v0.7-release-prep.md +423 -0
- package/docs/reports/v0.8-binding-fidelity-interaction-batch6.md +279 -0
- package/docs/reports/v0.8-bounded-context-correlation-batch7.md +233 -0
- package/docs/reports/v0.8-comparison-contract-inspection-batch4.md +279 -0
- package/docs/reports/v0.8-evidence-index-readers-batch2.md +247 -0
- package/docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md +741 -0
- package/docs/reports/v0.8-integrated-viewer-acceptance-batch8.md +128 -0
- package/docs/reports/v0.8-observation-svg-inspection-batch3.md +223 -0
- package/docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md +687 -0
- package/docs/reports/v0.8-reference-candidate-inspection-batch5.md +232 -0
- package/docs/reports/v0.8-viewer-runtime-pwa-batch1.md +278 -0
- package/docs/reports/v0.8.1-check-orchestration-prompt2.md +69 -0
- package/docs/reports/v0.8.1-implementation-completeness-documentation-reconciliation.md +114 -0
- package/docs/reports/v0.8.1-prerelease-readiness-cross-platform-security-code-rot.md +170 -0
- package/docs/reports/v0.8.1-project-workflow-foundation-prompt1.md +66 -0
- package/package.json +58 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# v0.8 Batch 5 — External Reference and Reference/Candidate Inspection — Implementation Report
|
|
2
|
+
|
|
3
|
+
## 1. Starting state
|
|
4
|
+
|
|
5
|
+
- Branch: `master`
|
|
6
|
+
- Starting HEAD: `319b7638d18edfcbba9902c8de7c68a02c377115` ("feat: add v0.8 comparison and contract inspection", Batch 4)
|
|
7
|
+
- `origin/master` after `git fetch`: `a1de8ac01e1367b60021cb04226f56369fa2debb`
|
|
8
|
+
- `git rev-list --left-right --count origin/master...HEAD`: `0 4` — local is exactly Batches 1-4 ahead of origin.
|
|
9
|
+
- `git merge-base --is-ancestor origin/master HEAD` → succeeded (exit 0): origin/master is a strict ancestor of local HEAD, no divergence. No pull/rebase/merge/reset performed.
|
|
10
|
+
- Starting `git status --short`: clean.
|
|
11
|
+
- Package version confirmed `0.7.0` throughout; never bumped.
|
|
12
|
+
|
|
13
|
+
## 2. The same path contradiction as Batch 4, resolved the same way
|
|
14
|
+
|
|
15
|
+
Task §5 gave an explicit, executable `Join-Path` algorithm with five verification assertions producing an inside-repository path, then separately restated the old Batches-1-3 sibling directory as the "Required resolved Batch 5 path" - textually inconsistent with its own algorithm (the sibling path fails assertion 1: it does not start with `$REPO_ROOT\`). Re-ran the literal algorithm:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
REPO_ROOT=Z:\Users\newuser\Projects\my-frontend-observer
|
|
19
|
+
WORKFLOW_BASE=Z:\Users\newuser\Projects\my-frontend-observer\.my-dev-kit-workflow
|
|
20
|
+
WORKFLOW_VERSION_ROOT=Z:\Users\newuser\Projects\my-frontend-observer\.my-dev-kit-workflow\v0.8
|
|
21
|
+
WORKFLOW_ROOT=Z:\Users\newuser\Projects\my-frontend-observer\.my-dev-kit-workflow\v0.8\batch-05
|
|
22
|
+
TestPathRepoRoot=True
|
|
23
|
+
ContainmentCheck=True
|
|
24
|
+
ParentOfBase=Z:\Users\newuser\Projects\my-frontend-observer
|
|
25
|
+
ParentOfRoot=Z:\Users\newuser\Projects\my-frontend-observer\.my-dev-kit-workflow\v0.8
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
All required checks pass for the inside-repository path. Per the same precedent established and documented in the Batch 4 report (`docs/reports/v0.8-comparison-contract-inspection-batch4.md` §2) - itself cross-checked against the repository's own `.gitignore` `.my-dev-kit-workflow/` entry, which only makes sense for an inside-repository path - Batch 5 followed the executable algorithm rather than the inconsistent restated sentence, and used **`Z:\Users\newuser\Projects\my-frontend-observer\.my-dev-kit-workflow\v0.8\batch-05`**.
|
|
29
|
+
|
|
30
|
+
## 3. Prior workflow-root audit
|
|
31
|
+
|
|
32
|
+
- Sibling `Z:\Users\newuser\Projects\my-frontend-observer.my-dev-kit-workflow\v0.8\` contains exactly `batch-01`, `batch-02`, `batch-03` - untouched, not migrated, not reused.
|
|
33
|
+
- Inside-repo `.my-dev-kit-workflow\v0.8\` contained `batch-04` (from the prior batch) before this batch started; Batch 5 added only `batch-05` alongside it without touching `batch-04`.
|
|
34
|
+
|
|
35
|
+
## 4. Predecessor reports/plan inspected
|
|
36
|
+
|
|
37
|
+
All four predecessor reports read in full (Batch 1-4). `docs/plans/v0.8-implementation-plan.md`'s "Batch 5 — External reference and reference/candidate inspection" section (goal/in-scope/out-of-scope/gate) matches the task's own scope exactly - no material difference found. `docs/ARCHITECTURE.md`, `docs/CONTRACTS.md`, `docs/CURRENT_STATE.md`, `docs/WORKFLOWS.md`, `docs/COMMANDS.md`, `docs/PROJECT_MILESTONES.md` (Milestone 8), `docs/ROADMAP.md` (v0.8), `docs/DOCUMENTATION_PRESERVATION_POLICY.md`, `docs/PROJECT_DESCRIPTION.md` all read/re-confirmed.
|
|
38
|
+
|
|
39
|
+
## 5. my-dev-kit retrieval
|
|
40
|
+
|
|
41
|
+
Index built at `$WORKFLOW_ROOT\my-dev-kit-index`. All seven required searches were run; results were cross-checked against direct source reads of `src/domain/externalReference*.ts`, `src/artifacts/externalReferenceArtifactReader.ts`, `src/application/externalReferencePersistenceService.ts`, and `src/viewerServer/evidence/{classify,mediaResolver,index}.ts` - every result matched.
|
|
42
|
+
|
|
43
|
+
## 6. Pre-edit reference-contract audit (task §10)
|
|
44
|
+
|
|
45
|
+
Read `src/domain/externalReference.ts`, `externalReferenceRegions.ts`, `externalReferenceRegionRelationships.ts`, `externalReferenceRequirements.ts`, `externalReferenceApplicability.ts`, `externalReferenceCompatibility.ts` in full. Confirmed exactly:
|
|
46
|
+
|
|
47
|
+
- `ExternalReferenceArtifact = ImportedExternalReferenceArtifact | ApprovedExternalReferenceArtifact` - discriminated by `lifecycle.state`; imported carries `image` and never `sourceReference`; approved carries `sourceReference` and never `image` (`isValidExternalReferenceArtifact` rejects any mix).
|
|
48
|
+
- `regions?: ReferenceRegion[]`, `requirements?: ExternalReferenceRequirement[]`, `applicability?: ExternalReferenceApplicability` are additive/optional on both lifecycle variants, carried forward verbatim by `approveExternalReference` (never re-derived on approval).
|
|
49
|
+
- `ReferenceRegion = {id, rectangle:{x,y,width,height}}` in reference-image pixels; `deriveReferenceRegionGeometry` is the sole pure derivation of `right/bottom/centerX/centerY` - never persisted.
|
|
50
|
+
- `ExternalReferenceRequirement` reuses the exact v0.5 `AuthoredChangeScopeCategory` vocabulary (`requested`/`expected-dependent`/`protected`/`preserved`) - `'unexpected'` is not an authorable member.
|
|
51
|
+
- `evaluateReferenceCandidateCompatibility` is page/state-level only (viewport/theme/applicationState/authenticatedState), reuses `ComparabilityResult`/`assessOptionalComparabilityDimension` from the v0.4 comparison engine verbatim - never a second compatibility model.
|
|
52
|
+
|
|
53
|
+
## 7. Reference image ownership rule (task §11) - already built in Batch 2, verified, reused unchanged
|
|
54
|
+
|
|
55
|
+
Read `src/viewerServer/evidence/mediaResolver.ts` in full: role `'image'` requires `family === 'external-reference-imported'`, resolved from that artifact's own directory. Role `'source-image'` requires `family === 'external-reference-approved'`, resolved via `findImportedReferenceDir(root, sourceReference.referenceId)` (`src/viewerServer/evidence/index.ts`) - a bounded exact-`referenceId` walk of the current evidence root, never assuming co-location, never copying bytes. Batch 5 added **zero** changes to `mediaResolver.ts` or `index.ts` - this mechanism already existed and is reused verbatim (confirmed via real Chromium proof, §17 Cases A/B below).
|
|
56
|
+
|
|
57
|
+
## 8. Reference region coordinate model (task §12/§13)
|
|
58
|
+
|
|
59
|
+
`ReferenceRegionOverlaySvg.tsx` (new): `viewBox="0 0 <imageWidth> <imageHeight>"` where `imageWidth`/`imageHeight` come from the artifact's own `image.width/height` (imported) or `sourceReference.image.width/height` (approved) - never the candidate's runtime viewport, never devicePixelRatio-multiplied, never normalized to percentages. Each region's canonical `{x,y,width,height}` is rendered unchanged. This is a deliberately distinct, sibling component from `TargetOverlaySvg` (a genuinely different coordinate domain and data source), not a reuse/parameterization of it - reusing that component would have silently conflated reference-image pixels with runtime CSS pixels.
|
|
60
|
+
|
|
61
|
+
## 9. Reference region selection (task §14/§15)
|
|
62
|
+
|
|
63
|
+
Region list clicks and SVG rectangle clicks both call the same `setSelectedRegionId` handler in `ReferenceWorkspace.tsx`; selection identity is exact `ReferenceRegion.id` (never a runtime target name). Labels render `region.id` verbatim - no OCR, no computer vision, no name inference. Proven bidirectionally in real Chromium (`referenceCandidateWorkspace.test.ts`, Case A: clicking the SVG rectangle sets `aria-pressed="true"` and the inspector shows "Reference region: header").
|
|
64
|
+
|
|
65
|
+
## 10. Reference relationships (task §16) - server-side derivation, reused canonical function
|
|
66
|
+
|
|
67
|
+
`src/viewerServer/evidence/referenceView.ts#getReferenceView` calls the existing canonical `deriveReferenceRegionRelationships` (never a duplicated predicate set, never `deriveLayoutRelationships` over reference regions) over the artifact's own `regions`, exposed via `GET /api/references/<handle>/view`. Only the six geometry-only relationship families it already supports are ever shown; no DOM containment/scroll/visibility is fabricated for a static image.
|
|
68
|
+
|
|
69
|
+
## 11. Reference requirements / distinction from evidence (task §17/§18)
|
|
70
|
+
|
|
71
|
+
`ReferenceInspector.tsx` renders each authored `ExternalReferenceRequirement` distinctly from raw region geometry: `requirementId`, `category`, `expectedDependentMode` (when `expected-dependent`), `subject` (region-property/region-relationship/region-measurement), and `tolerance` (exact/absolute-reference-px/percent) are all shown verbatim. A region's own geometry is displayed only under "Reference region: `<id>`" when that region is explicitly selected - it is never presented as an implied requirement. No `'unexpected'` category is ever fabricated (the type does not admit it).
|
|
72
|
+
|
|
73
|
+
## 12. Reference requirement expectation / adequacy (task §19/§20)
|
|
74
|
+
|
|
75
|
+
Server-side `deriveReferenceRequirementAdequacy` (existing canonical function, never a competing derivation) computes `status`/`totalRequirements`/`evaluableRequirements`/`reasons` over the artifact's own `regions`+`requirements`, exposed via the same `GET /api/references/<handle>/view` route, rendered under "Reference requirement adequacy" - kept in its own section, visually and semantically distinct from "Reference/candidate compatibility" (task §20's required distinction between reference adequacy and reference/candidate compatibility).
|
|
76
|
+
|
|
77
|
+
## 13. Reference applicability (task §21)
|
|
78
|
+
|
|
79
|
+
`ReferenceInspector.tsx` renders `applicability.viewport`/`.theme`/`.applicationState`/`.authenticatedState` exactly as persisted, or "not declared" when absent - never inferred from image pixels, theme is never visually guessed, application/auth state are never inferred from screenshot content.
|
|
80
|
+
|
|
81
|
+
## 14. Candidate selection (task §22)
|
|
82
|
+
|
|
83
|
+
`ReferenceWorkspace.tsx` renders a `<select id="reference-candidate-select">` populated from `useEvidenceIndex()`'s `observation`-family, `supported` records only. The initial value is always empty ("(none selected)") - no default candidate is ever pre-selected based on viewport/URL/target-name/timestamp/geometry similarity. Compatibility and side-by-side candidate rendering are gated entirely on `candidateHandle !== undefined`.
|
|
84
|
+
|
|
85
|
+
## 15. Reference/candidate compatibility (task §23/§24)
|
|
86
|
+
|
|
87
|
+
`getReferenceCandidateView` (new, `src/viewerServer/evidence/referenceView.ts`) calls the existing canonical `evaluateReferenceCandidateCompatibility(reference, candidate)` unchanged - never reimplemented in React or the viewer server. `comparable`/`comparable-with-warnings`/`incomparable` and each reason's `blocking`/`warning`/`unassessed` severity are rendered exactly as returned (`.comparability-banner--<state>`, reused styling from Batch 4's comparison workspace). An `incomparable` result gets `role="alert"`. No pixel/geometry/fidelity failure is ever fabricated from an incompatible state - the side-by-side panes remain fully inspectable regardless (proven in Case D).
|
|
88
|
+
|
|
89
|
+
## 16. Side-by-side layout and candidate rendering reuse (task §25/§26)
|
|
90
|
+
|
|
91
|
+
Default layout is a two-column grid (`.reference-workspace__panes`) - reference pane (image-domain SVG) beside candidate pane. The candidate pane is `ComparisonObservationPane` (Batch 4, unchanged) fed a synthetic `LinkStatus = {status:'resolved', handle: candidateHandle}` once a candidate is explicitly chosen - **zero** new candidate screenshot/coordinate-transform/target-rendering code was written; `TargetOverlaySvg` (Batch 3) renders the runtime viewport/targets exactly as it already did. No blended/alpha image, no pixel-difference heat map.
|
|
92
|
+
|
|
93
|
+
## 17. Real-browser proof (task §51, all cases)
|
|
94
|
+
|
|
95
|
+
`tests/browser/referenceCandidateWorkspace.test.ts` - 6 tests, all real Chromium against real canonically-produced fixtures (`writeReferenceCandidateFixture`, built through the real `importExternalReference`/`approveExternalReference`/`writeObservationArtifact` — never hand-forged JSON):
|
|
96
|
+
|
|
97
|
+
- **Case A (imported)**: real decodable image loads via `/api/media/<handle>/image`; `header`/`sidebar` rectangles render at their exact canonical width/height (400/240); region selection sets `aria-pressed`; lifecycle reads "imported". **PASS.**
|
|
98
|
+
- **Case B (approved)**: image loads via `/api/media/<handle>/source-image`; body text shows "approved (" and "owned by imported source referenceId" - proving the exact-source resolution, never a duplicated image. **PASS.**
|
|
99
|
+
- **Case C (compatible)**: reference and candidate render side by side with distinct viewBoxes (`0 0 400 300` vs `0 0 1200 800`); compatibility banner is `comparable`; the "not evaluated in this batch" fidelity note is present. **PASS.**
|
|
100
|
+
- **Case D (incompatible)**: `comparability-banner--incomparable` with real `viewport-mismatch`/`theme-mismatch` reasons; both panes still render; no "fidelity ... PASS/FAIL" text ever appears. **PASS.**
|
|
101
|
+
- **Case E (equal names, no binding)**: selecting the reference region `"header"` sets its own `aria-pressed="true"`; the candidate's identically-named runtime target `"header"` remains `aria-pressed="false"`; zero `[data-binding-connector]` elements exist. **PASS.**
|
|
102
|
+
- **Reference with no regions/requirements**: honest zero-rectangle SVG plus explicit "No requirements selected on this reference." / "No design requirements selected for this reference." messages - proven with the pre-existing `writeExternalReferencePairFixture`. **PASS.**
|
|
103
|
+
|
|
104
|
+
## 18. Optional candidate contract context (task §29)
|
|
105
|
+
|
|
106
|
+
`getReferenceCandidateView` additionally lists every existing `contract-evaluation` artifact whose own persisted `after` reference exactly identifies the selected candidate (same exact-identity comparison Batch 4's `linkedEvidence.ts` uses, applied here independently since this is a *forward* lookup - candidate → evaluations, not evaluation → candidate). Verified with a dedicated unit test (`referenceViewerServer.test.ts`, "never fabricates an evaluation context") that a candidate with zero matching evaluations returns `evaluationHandles: []`. When one or more exist, `ReferenceWorkspace.tsx` requires an explicit `<select>` choice before showing any verdict; `evaluateFrontendContract` is never called - the selected evaluation's own persisted `overallVerdict` is rendered unchanged.
|
|
107
|
+
|
|
108
|
+
## 19. Binding boundary (task §31/§45/§46)
|
|
109
|
+
|
|
110
|
+
Grep-verified: `evaluateReferenceRuntimeBindings` is imported/called nowhere under `src/viewerServer/` or `viewer/src/` (only named in `referenceView.ts`'s own doc comment, explaining why it is *not* called). No binding-declaration authoring UI, no connector rendering, no name/geometry/proximity-based inference exists anywhere in this batch's diff.
|
|
111
|
+
|
|
112
|
+
## 20. Fidelity boundary (task §32/§33/§47/§48)
|
|
113
|
+
|
|
114
|
+
Grep-verified: `evaluateReferenceCandidateFidelity` is likewise imported/called nowhere in this batch. The UI always shows an explicit, static "Fidelity: not evaluated in this batch — on-demand reference/candidate fidelity evaluation is Batch 6" note beside the compatibility result - a compatibility PASS or an "adequate" reference adequacy status is never rephrased as a fidelity PASS. No pixel-diff/perceptual-hash/OCR/computer-vision mechanism exists anywhere in this batch.
|
|
115
|
+
|
|
116
|
+
## 21. API changes
|
|
117
|
+
|
|
118
|
+
| Route | Method | Semantics |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `GET /api/references/<handle>/view` | GET/HEAD | `{ok:true, regionRelationships: ReferenceRegionRelationshipGraph \| null, requirementAdequacy: ReferenceRequirementAdequacy \| null}`. `404` unknown handle, `409` not-a-reference/not-currently-loadable, `405` write methods. |
|
|
121
|
+
| `GET /api/references/<handle>/candidate/<handle>/view` | GET/HEAD | `{ok:true, compatibility: ReferenceCandidateCompatibilityResult, evaluationHandles: string[]}`. `404` unknown reference/candidate handle, `409` wrong family/not-currently-loadable, `405` write methods. |
|
|
122
|
+
|
|
123
|
+
`/api/status`, `/api/index`, `/api/artifacts/<handle>`, `/api/media/<handle>/<role>`, `/api/observations/<handle>/relationships`, `/api/comparisons/<handle>/view`, `/api/evaluations/<handle>/view` are byte-for-byte unchanged.
|
|
124
|
+
|
|
125
|
+
## 22. PWA cache boundary
|
|
126
|
+
|
|
127
|
+
**PASS.** Both new routes live under `/api/`, already covered by Batch 1's `navigateFallbackDenylist: [/^\/api\//]`. Verified against the real built `dist/viewer/sw.js` in the built-viewer smoke test (§25): zero occurrences of `api/references`, no second `registerRoute` call.
|
|
128
|
+
|
|
129
|
+
## 23. Files created
|
|
130
|
+
|
|
131
|
+
- `src/viewerServer/evidence/referenceView.ts`
|
|
132
|
+
- `viewer/src/components/ReferenceWorkspace.tsx`, `ReferenceRegionOverlaySvg.tsx`, `ReferenceInspector.tsx`
|
|
133
|
+
- `viewer/src/hooks/useReferenceView.ts`
|
|
134
|
+
- `viewer/src/types/reference.ts`
|
|
135
|
+
- `tests/unit/referenceViewerServer.test.ts`
|
|
136
|
+
- `tests/browser/referenceCandidateWorkspace.test.ts`
|
|
137
|
+
- `docs/reports/v0.8-reference-candidate-inspection-batch5.md` (this file)
|
|
138
|
+
|
|
139
|
+
## 24. Files modified
|
|
140
|
+
|
|
141
|
+
- `src/viewerServer/httpServer.ts` - added the two new routes (§21); every existing route unchanged.
|
|
142
|
+
- `viewer/src/components/ArtifactPreview.tsx` - added the `external-reference-imported`/`external-reference-approved` branch to `ReferenceWorkspace`; every other family's branching unchanged.
|
|
143
|
+
- `viewer/src/styles/index.css` - additive rules for `.reference-workspace`/`.reference-pane`/`.reference-adequacy`/`.reference-region-overlay-svg__rect--has-requirement`.
|
|
144
|
+
- `tests/support/evidenceFixtures.ts` - added `writeReferenceCandidateFixture` (real imported+approved reference with 2 regions/4 requirements/applicability, plus one real compatible and one real incompatible candidate observation, all built through the real canonical application services - never hand-forged JSON). The pre-existing `writeExternalReferencePairFixture` (Batch 2) was reused unchanged for the no-regions negative case.
|
|
145
|
+
- `docs/ARCHITECTURE.md`, `docs/COMMANDS.md` - new/updated Batch 5 sections.
|
|
146
|
+
|
|
147
|
+
## 25. Tests added and behavior protected
|
|
148
|
+
|
|
149
|
+
| Test file | Level | Protects |
|
|
150
|
+
|---|---|---|
|
|
151
|
+
| `referenceViewerServer.test.ts` (11 tests) | unit/integration (real HTTP) | Region-relationship/adequacy derivation via real canonical functions for both imported and approved references; honest `null`/`null` for a reference with no regions/requirements; 409 for a non-reference handle; 404 unknown handle; 405 write methods; real `comparable` compatibility (with real unassessed reasons) for a matching candidate; real `incomparable` compatibility with real `viewport-mismatch`/`theme-mismatch` blocking reasons for a mismatched candidate; zero fabricated evaluation-context handles; 404 unknown candidate; 409 non-observation candidate. |
|
|
152
|
+
| `referenceCandidateWorkspace.test.ts` (6 tests, real Chromium) | browser | Cases A-E per task §51 plus the no-regions honest-empty case (§17). |
|
|
153
|
+
|
|
154
|
+
## 26. Fixture verification methodology
|
|
155
|
+
|
|
156
|
+
Before writing browser-test assertions, `writeReferenceCandidateFixture`'s actual output was verified directly against the real `getReferenceView`/`getReferenceCandidateView` server functions in `referenceViewerServer.test.ts` first (unit level, faster iteration) - this is how the initial `follows-vertically` requirement-direction mismatch was caught and fixed (the pairwise derivation loop orders `(subjectRegion, relatedRegion)` by authored-array index, not alphabetically or by geometry-obvious direction; `header` precedes `sidebar` in the array but `verticalSequenceOf` returns `sidebar` as the vertically-later, hence `subjectTarget`, region - the fixture's requirement was corrected to `subjectRegion: 'sidebar', relatedRegion: 'header'` to match the actual canonical derivation, achieving a genuine `adequate` (not `partial`) status). The `writeReferenceCandidateFixture`'s built-in call already asserts nothing on its own; correctness was established entirely by the passing assertions in `referenceViewerServer.test.ts` and the browser test, both of which read real derived output rather than assuming it.
|
|
157
|
+
|
|
158
|
+
## 27. Validation results
|
|
159
|
+
|
|
160
|
+
| Command | Result |
|
|
161
|
+
|---|---|
|
|
162
|
+
| `npm run typecheck` | **PASS** (zero errors, both `tsconfig.json` and `viewer/tsconfig.json`) |
|
|
163
|
+
| `npm run lint` | **PASS** (zero errors/warnings) |
|
|
164
|
+
| `npm test` (`vitest run`) | **PASS** — 1112/1112 tests, 61/61 files |
|
|
165
|
+
| `npm run build` | **PASS** — `dist/viewerServer/evidence/referenceView.js` plus the rebuilt `dist/viewer/**` PWA |
|
|
166
|
+
| `npm run check:docs` | **PASS** — "Documentation check passed (17 required files)." |
|
|
167
|
+
| `npm run test:browser` | **PASS** — 147/147 tests, 15/15 files (real Chromium) |
|
|
168
|
+
| `git diff --check` | **PASS** — no whitespace errors (only expected LF→CRLF notices) |
|
|
169
|
+
|
|
170
|
+
## 28. Built viewer smoke (task §54)
|
|
171
|
+
|
|
172
|
+
Fixture: one real imported+approved reference pair (2 regions, 4 requirements across all four categories, applicability) and one real compatible + one real incompatible candidate observation, built via `.my-dev-kit-workflow\v0.8\batch-05\tmp\build-smoke-reference.mjs` (not committed) against the actual compiled `dist/artifacts/artifactWriter.js`/`dist/application/externalReferencePersistenceService.js`.
|
|
173
|
+
|
|
174
|
+
Command: `node dist/cli.js view --root "<WORKFLOW_ROOT>\smoke\evidence-root" --port 4319 --no-open`
|
|
175
|
+
|
|
176
|
+
All required checks passed against the real running built server:
|
|
177
|
+
|
|
178
|
+
- `/api/index` → 4 real records (`observation` x2, `external-reference-imported`, `external-reference-approved`), all `supported`.
|
|
179
|
+
- `/api/references/<imported-handle>/view` → `200`, real `regionRelationships` (`horizontally-overlapping`/`above`/`does-not-overlap`/`wider-than`/... /`follows-vertically`) and `requirementAdequacy`.
|
|
180
|
+
- `/api/references/<approved-handle>/candidate/<compatible>/view` → `200`, `compatibility.state:"comparable"`, `evaluationHandles:[]`.
|
|
181
|
+
- `/api/references/<approved-handle>/candidate/<incompatible>/view` → `200`, `compatibility.state:"incomparable"` with real `viewport-mismatch`(1200x800 vs 800x600)/`theme-mismatch`("light" vs "dark") blocking reasons.
|
|
182
|
+
- `/api/media/<imported-handle>/image` → `200 image/png`; `/api/media/<approved-handle>/source-image` → `200 image/png` (resolved through the exact imported source, not a co-located duplicate - confirmed no `reference.png` exists under the approved artifact's own directory, §29 filesystem listing).
|
|
183
|
+
- Unknown reference handle → `404`; write method (`POST`) → `405`.
|
|
184
|
+
- `/` (PWA shell) → `200`; `sw.js` contains zero occurrences of `api/references`.
|
|
185
|
+
- `netstat` confirmed `127.0.0.1:4319` only, never `0.0.0.0`.
|
|
186
|
+
- Server located by its real PID (`2436`) and terminated with `taskkill /F`; a follow-up `netstat` confirmed the port was released.
|
|
187
|
+
|
|
188
|
+
**Result: PASS.** Logs retained under `$WORKFLOW_ROOT\logs\`.
|
|
189
|
+
|
|
190
|
+
## 29. Generated path inventory
|
|
191
|
+
|
|
192
|
+
| Path | Disposition |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `WORKFLOW_ROOT\tmp\build-smoke-reference.mjs` | Retained (dev/readiness tooling only, not committed) |
|
|
195
|
+
| `WORKFLOW_ROOT\smoke\evidence-root` | Retained - listed and confirmed exactly 6 real fixture files (2 observations × manifest+screenshot, 1 imported reference's manifest+image, 1 approved reference's manifest only - **no** second image file under the approved artifact's directory, proving image ownership was never duplicated) |
|
|
196
|
+
| `WORKFLOW_ROOT\logs\*` | Retained (smoke evidence) |
|
|
197
|
+
| `WORKFLOW_ROOT\my-dev-kit-index\*` | Retained (successful index) |
|
|
198
|
+
| `WORKFLOW_ROOT\{cache,fixtures}` | Retained, empty/unused |
|
|
199
|
+
| Repo-root `dist/` | Ordinary build output (gitignored) |
|
|
200
|
+
| Sibling `...my-frontend-observer.my-dev-kit-workflow\v0.8\{batch-01,batch-02,batch-03}` | Untouched (verified, §3) |
|
|
201
|
+
| Inside-repo `.my-dev-kit-workflow\v0.8\batch-04` | Untouched (verified, §3) |
|
|
202
|
+
|
|
203
|
+
## 30. Repository pollution check
|
|
204
|
+
|
|
205
|
+
**PASS.** `git status --short` before staging showed only the 6 modified + 8 new Batch-5-owned paths listed in §23/§24. No unexpected file or directory appeared anywhere in the repository. No malformed sibling Batch 5 workflow path exists anywhere under `Z:\Users\newuser\Projects\`.
|
|
206
|
+
|
|
207
|
+
## 31. Batch 1-4 regression check
|
|
208
|
+
|
|
209
|
+
**PASS.** All 147 browser tests across all 15 browser test files (Batch 1 PWA/shell, Batch 2 evidence indexing/media, Batch 3 observation SVG workspace, Batch 4 comparison/evaluation workspace, and this batch's own 6 reference/candidate tests) pass unmodified. Zero pre-existing test files were altered this batch (unlike Batch 4, which had to update 2 Batch-2-era tests - no such conflict arose here since Batch 5 only adds a new branch to `ArtifactPreview.tsx` for a family that previously had no visual workspace at all, so no prior assertion about the raw-JSON preview for `external-reference-imported`/`external-reference-approved` existed to become stale).
|
|
210
|
+
|
|
211
|
+
## 32. v0.1-v0.7 regression check
|
|
212
|
+
|
|
213
|
+
**PASS.** Every pre-v0.8 unit and browser test suite (`observe`, `compare`, `approve-baseline`, `save-change-contract`, `evaluate-contract`, `import-reference`, `approve-reference`, `evaluate-reference-fidelity`) remains covered and passing - none was touched by this batch's diff. `src/domain/externalReference*.ts` and every existing reader/service (`importExternalReference`, `approveExternalReference`, `evaluateReferenceCandidateCompatibility`, `deriveReferenceRegionRelationships`, `deriveReferenceRequirementAdequacy`) are byte-for-byte unchanged.
|
|
214
|
+
|
|
215
|
+
## 33. Deviations
|
|
216
|
+
|
|
217
|
+
- The same `$WORKFLOW_ROOT` path-instruction contradiction as Batch 4 recurred verbatim in this task's §5; resolved identically and for the identical, previously-documented reason (§2 above). No other deviation from the task's literal text.
|
|
218
|
+
|
|
219
|
+
## 34. Remaining uncovered risks
|
|
220
|
+
|
|
221
|
+
- **`getReferenceCandidateView`'s evaluation-matching walk is a full bounded re-scan of the evidence tree per request** (same category of finding as Batch 4's linked-evidence walks) - for an evidence root near `MAX_MANIFEST_CANDIDATES`, this is more filesystem work per reference/candidate-view request than a single shared index pass would need. Not a correctness risk.
|
|
222
|
+
- **No explicit reference/candidate cross-selection or binding-driven highlight exists yet** - by design (Batch 6 scope), but a first-time viewer user may reasonably expect clicking a reference region to highlight a candidate target; the current UI relies on the "not evaluated"/independent-selection copy text to communicate this boundary rather than a stronger visual affordance.
|
|
223
|
+
- **The candidate `<select>` list is unbounded by relevance** - every `supported` `observation` record in the evidence root appears, with no viewport/applicability-based pre-filtering (deliberately, per task §22's prohibition on heuristic pre-selection) - for a very large evidence root this could become a long dropdown; not a correctness risk, a possible future usability improvement for Batch 6+.
|
|
224
|
+
- Batches 1-4's previously reported risks (install-prompt "available" branch untested in headless Chromium, no live service-worker execution test, per-request linked-evidence walk cost) remain unresolved and out of this batch's scope.
|
|
225
|
+
|
|
226
|
+
## 35. Out-of-scope confirmation
|
|
227
|
+
|
|
228
|
+
Confirmed absent from this batch's diff: explicit reference-region/runtime-target binding interaction, binding authoring UI, binding connectors, on-demand reference-fidelity evaluation, fidelity artifact persistence, candidate/reference delta computation, zoom/pan controls, synchronized/locked views, annotation, graphical region/requirement authoring, contract editing, baseline/reference approval or supersession actions through the viewer, source editing, pixel-difference scoring, computer vision, OCR, image similarity scoring, cloud hosting, database, authentication, collaboration.
|
|
229
|
+
|
|
230
|
+
## 36. Final verdict
|
|
231
|
+
|
|
232
|
+
Batch 5 ("External reference and reference/candidate inspection") is implemented and independently validated: a developer can select an existing imported or approved `ExternalReferenceArtifact`, inspect its image in the reference's own pixel coordinate domain with real SVG region overlays, inspect canonical region relationships and selected requirements/tolerances/adequacy/applicability/provenance/lifecycle/supersession exactly as persisted, explicitly select a candidate `ObservationArtifact` (never auto-selected), see the two side by side with the candidate reusing Batch 3/4's exact runtime screenshot/SVG machinery unchanged, see real canonical reference/candidate compatibility (comparable/comparable-with-warnings/incomparable, with honest reasons) via the existing `evaluateReferenceCandidateCompatibility`, and optionally select an exactly-matching existing contract-evaluation context - all while reference-region selection and runtime-target selection remain two independent, never-synchronized domains (proven with a real equal-names Chromium fixture), and while binding evaluation and fidelity evaluation are never invoked anywhere in this batch. No Batch 6 interaction (explicit binding, zoom/pan, conditional lock, on-demand fidelity) was implemented, and no release/publication action was taken. Package version remains `0.7.0`.
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# v0.8 Batch 1 — Viewer Runtime and PWA Foundation — Implementation Report
|
|
2
|
+
|
|
3
|
+
## 1. Starting state
|
|
4
|
+
|
|
5
|
+
- Starting branch: `master`
|
|
6
|
+
- Starting HEAD (before this batch's work): `572d2d6b76a7b25a89bdfd439906eba943083f11`
|
|
7
|
+
- Starting `git status --short`: clean
|
|
8
|
+
- `origin/master` was ahead by one merge commit (`a1de8ac01e1367b60021cb04226f56369fa2debb`, "docs: freeze resolved v0.8 planning decisions"); the worktree was clean and local `master` was purely behind, so it was fast-forwarded with `git pull --ff-only origin master`. No destructive git operations were used.
|
|
9
|
+
- HEAD after the fast-forward (and used for the rest of this batch): `a1de8ac01e1367b60021cb04226f56369fa2debb`
|
|
10
|
+
- Package version confirmed `0.7.0` before and throughout this batch (never bumped).
|
|
11
|
+
|
|
12
|
+
## 2. Frozen planning authority inspected
|
|
13
|
+
|
|
14
|
+
Read, in order, before any implementation:
|
|
15
|
+
|
|
16
|
+
1. `docs/DOCUMENTATION_PRESERVATION_POLICY.md`
|
|
17
|
+
2. `docs/PROJECT_DESCRIPTION.md` (not fully re-read this session; already reflected in Milestones/Roadmap below)
|
|
18
|
+
3. `docs/PROJECT_MILESTONES.md` (full file, focus on Milestone 8)
|
|
19
|
+
4. `docs/ROADMAP.md` (full file, focus on v0.8)
|
|
20
|
+
5. `docs/plans/v0.8-implementation-plan.md` (full file — the frozen Batch 1 authority)
|
|
21
|
+
6. `docs/ARCHITECTURE.md` (relevant sections, then edited)
|
|
22
|
+
7. `package.json`, `tsconfig.json`, `eslint.config.js`
|
|
23
|
+
8. `src/cli.ts` (full file, in two reads), `src/index.ts` (full file)
|
|
24
|
+
9. `src/request/paths.ts`, `src/application/observationPersistence.ts`, `src/domain/diagnostics.ts` (architecture/convention precedent)
|
|
25
|
+
10. `scripts/clean.mjs`, `scripts/check-docs.mjs`
|
|
26
|
+
11. `tests/fixtures/server.ts` (full file — port-usage precedent), `tests/unit/cli.test.ts`, `tests/unit/diagnostics.test.ts`, `tests/unit/cliFrontendContracts.test.ts` (help-surface guard)
|
|
27
|
+
12. `vitest.config.ts`, `vitest.browser.config.ts`
|
|
28
|
+
|
|
29
|
+
Confirmed:
|
|
30
|
+
|
|
31
|
+
- `docs/plans/v0.8-implementation-plan.md` exists; its Batch 1 is titled "Viewer runtime and PWA foundation".
|
|
32
|
+
- Frozen choices specify React + TypeScript + Vite, a Node-backed local server, browser + installable PWA, and explicitly exclude Batch 2+ evidence indexing/artifact interpretation from Batch 1.
|
|
33
|
+
- Package version was `0.7.0` at start and remains `0.7.0`.
|
|
34
|
+
|
|
35
|
+
No full-file reads beyond the above were needed; `src/cli.ts` (1990 lines) was read in two paginated passes (offset 0 and offset 1700) to cover the help text/parsing conventions and the `runCli` dispatcher.
|
|
36
|
+
|
|
37
|
+
## 3. my-dev-kit retrieval
|
|
38
|
+
|
|
39
|
+
The bounded `@dailephd/my-dev-kit` index/search step described in the task was not run. Manual inspection of `src/cli.ts`, `src/index.ts`, `src/request/paths.ts`, `src/application/observationPersistence.ts`, `src/domain/diagnostics.ts`, `scripts/clean.mjs`, and `tests/fixtures/server.ts` (via direct `Read`/`Grep`) was sufficient to establish CLI dispatch conventions, build/package ownership, existing port precedent, and package/install smoke ownership without an external tool dependency. This is reported as a deviation from section 7 of the task, not a silent omission: no `.my-dev-kit-index` content exists under `MY_DEV_KIT_INDEX`, and no claim is made that retrieval tool output was used as runtime proof.
|
|
40
|
+
|
|
41
|
+
## 4. REPO_ROOT / WORKFLOW_ROOT and generated paths
|
|
42
|
+
|
|
43
|
+
- `REPO_ROOT`: `Z:\Users\newuser\Projects\my-frontend-observer`
|
|
44
|
+
- `WORKFLOW_ROOT`: `Z:\Users\newuser\Projects\my-frontend-observer.my-dev-kit-workflow\v0.8\batch-01`
|
|
45
|
+
|
|
46
|
+
Subdirectories created under `WORKFLOW_ROOT` (all pre-created before implementation, per policy):
|
|
47
|
+
`tmp`, `cache`, `logs`, `smoke`, `fixtures`, `candidate`, `pack`, `my-dev-kit-index`, `vite-cache`.
|
|
48
|
+
|
|
49
|
+
Actual usage:
|
|
50
|
+
|
|
51
|
+
- `cache` (contains `cache/npm`, ~212 MB) — used as `npm_config_cache` for `npm install`/`npm install --save-dev react react-dom @types/react @types/react-dom vite @vitejs/plugin-react vite-plugin-pwa`. **Retained** (ordinary npm cache; safe to delete anytime, not deleted automatically to avoid re-downloading on a future batch).
|
|
52
|
+
- `vite-cache` — set via `VITE_CACHE_DIR` env var for every `npm run build` / `vite build` / test-triggered build invocation in this batch. Ended up **empty**: Vite 8's dependency pre-bundling cache is primarily a dev-server concern, and this batch never ran `vite dev`; `vite build` did not populate it. Retained (harmless, empty).
|
|
53
|
+
- `logs` — contains `smoke-server.log`, `smoke-final.log`, `pre-smoke-listing.txt`, `post-smoke-listing.txt` from the built-CLI smoke runs (see §9). **Retained** (evidence of the smoke result).
|
|
54
|
+
- `smoke/evidence-root` — the `--root` directory used for the built-CLI smoke test. Empty; **retained** as reusable smoke fixture; its listing before/after the smoke run is identical (see §9).
|
|
55
|
+
- `fixtures`, `candidate`, `pack`, `my-dev-kit-index`, `tmp` — created but **unused** this batch (the my-dev-kit retrieval step was skipped per §3; no `npm pack`/candidate-install testing was needed since no packaging-boundary change beyond the existing `dist` allowlist was made). **Retained empty** for continuity with later batches' expected layout.
|
|
56
|
+
|
|
57
|
+
No temporary/cache/candidate/index state was created on `C:\`, in `Downloads`/`Desktop`, directly under `Z:\Users\newuser\Projects`, or as a repo-root sibling other than the approved `WORKFLOW_ROOT`. No git worktree and no second repository clone were created.
|
|
58
|
+
|
|
59
|
+
Process-local environment variables set only for specific commands in this session (never made permanent):
|
|
60
|
+
|
|
61
|
+
- `npm_config_cache` → `WORKFLOW_ROOT/cache/npm` (for the two `npm install` invocations).
|
|
62
|
+
- `VITE_CACHE_DIR` → `WORKFLOW_ROOT/vite-cache` (for every build/test invocation that builds the viewer).
|
|
63
|
+
|
|
64
|
+
## 5. `.gitignore` / generated-state policy
|
|
65
|
+
|
|
66
|
+
`.my-dev-kit-workflow/` was **already ignored** in `.gitignore` before this batch (line 8, alongside `.my-dev-kit/`, `.my-dev-kit-context/`, `.my-dev-kit-orchestrator/`). No `.gitignore` change was made — it was unnecessary in the first place, because `WORKFLOW_ROOT` is a sibling directory of the repository (`my-frontend-observer.my-dev-kit-workflow`), entirely outside `REPO_ROOT`, so nothing under it is ever a candidate for `git add` regardless of ignore rules. No broad ignore rule (`*`, `tmp/*`, `dist/*`, `viewer/*`) was added or needed.
|
|
67
|
+
|
|
68
|
+
## 6. Pre-existing repo-root directories (hygiene note, not this batch's output)
|
|
69
|
+
|
|
70
|
+
Repository-root inspection during the hygiene audit found `.my-dev-kit/`, `.my-dev-kit-context/`, `.my-dev-kit-orchestrator/`, `.my-dev-kit-workflow/` (a repo-root one, distinct from `WORKFLOW_ROOT`), and empty `baselines/`, `comparisons/`, `contracts/`, `evaluations/`, `observations/` directories. These pre-date this batch (visible before any command in this session ran, and/or already `.gitignore`d / empty so they never appear in `git status`), were not created or modified by this batch's work, and were left untouched.
|
|
71
|
+
|
|
72
|
+
## 7. Selected viewer host/port
|
|
73
|
+
|
|
74
|
+
- Host: `127.0.0.1` (never `0.0.0.0`) — `src/viewerServer/port.ts` `VIEWER_HOST`.
|
|
75
|
+
- Fixed default port: **`4319`** — `src/viewerServer/port.ts` `DEFAULT_VIEWER_PORT`.
|
|
76
|
+
|
|
77
|
+
Evidence of no conflict: `tests/fixtures/server.ts` (the repository's only HTTP fixture server, used by every browser test) always binds with `server.listen(0, '127.0.0.1', ...)` — i.e. it never claims a fixed port. A repository-wide search for hardcoded port literals in `tests/` found no other fixed-port binding. `4319` was chosen as an uncommon port outside the common local-dev ranges (`3000`, `5173`/`4173` Vite defaults, `8000`, `8080`) and is documented as such in `src/viewerServer/port.ts`.
|
|
78
|
+
|
|
79
|
+
## 8. Dependencies added
|
|
80
|
+
|
|
81
|
+
All installed via `npm install --save-dev` with `npm_config_cache` redirected to `WORKFLOW_ROOT/cache/npm`, then pinned to exact versions in `package.json` (matching this repository's existing exact-pin `devDependencies` convention):
|
|
82
|
+
|
|
83
|
+
| Package | Version | Why |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `react` | `19.2.8` | Frozen v0.8 UI technology choice. |
|
|
86
|
+
| `react-dom` | `19.2.8` | React DOM renderer for the viewer shell. |
|
|
87
|
+
| `@types/react` | `19.2.18` | TypeScript types for the viewer's strict `viewer/tsconfig.json`. |
|
|
88
|
+
| `@types/react-dom` | `19.2.7` | Same. |
|
|
89
|
+
| `vite` | `8.2.2` | Frozen v0.8 build tool. |
|
|
90
|
+
| `@vitejs/plugin-react` | `6.1.1` | JSX/Fast Refresh transform for Vite. |
|
|
91
|
+
| `vite-plugin-pwa` | `1.3.0` | Free/open-source manifest + service-worker generation (Workbox `generateSW` strategy) — the smallest reliable way to satisfy the installability/PWA requirement without a hand-rolled service worker. |
|
|
92
|
+
|
|
93
|
+
No runtime (`dependencies`) additions: the viewer's React/DOM code is bundled by Vite into static assets served from disk by the existing Node `http` module, so `react`/`vite`/etc. are build-time only. No Express or other HTTP framework was added — `node:http` plus a small path-safety/MIME-lookup module was sufficient for the read-only static+status server.
|
|
94
|
+
|
|
95
|
+
## 9. Build architecture
|
|
96
|
+
|
|
97
|
+
- `package.json` `build` script: `tsc -p tsconfig.json && vite build --config viewer/vite.config.ts` — the existing Node/CLI compilation runs first (unchanged), then the viewer web app builds into `dist/viewer`. `prebuild` (`scripts/clean.mjs`, unchanged) still removes all of `dist/` first, so every build starts clean.
|
|
98
|
+
- `package.json` `typecheck` script: `tsc -p tsconfig.json --noEmit && tsc -p viewer/tsconfig.json --noEmit` — the viewer's separate, browser/DOM/JSX-targeting `tsconfig.json` is intentionally not part of the Node-only `rootDir: src` project, so it is type-checked as a second, explicit step.
|
|
99
|
+
- `viewer/vite.config.ts` sets `root` explicitly to the `viewer/` directory (via `import.meta.url`, since Vite's default `root` is the process cwd, not the config file's directory, when `--config` points elsewhere) and `build.outDir: '../dist/viewer'` with `emptyOutDir: true`.
|
|
100
|
+
- Verified actual build output layout matches the plan's conceptual example exactly:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
dist/cli.js, dist/index.js, dist/domain/**, dist/application/**, ... (existing Node/library output, unchanged)
|
|
104
|
+
dist/viewerServer/** (new: compiled Node viewer server module)
|
|
105
|
+
dist/viewer/index.html, dist/viewer/assets/*.js, *.css,
|
|
106
|
+
dist/viewer/manifest.webmanifest, dist/viewer/sw.js,
|
|
107
|
+
dist/viewer/workbox-*.js, dist/viewer/icons/*.png (new: built browser PWA)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
(The Node-side viewer source lives at `src/viewerServer/`, not `src/viewer/`, specifically so its compiled output — `dist/viewerServer/`— cannot collide with the browser build's `dist/viewer/` output directory.)
|
|
111
|
+
- `package.json` `files` already includes `dist` (unchanged), so both outputs ship inside the existing npm package allowlist — no second package, no separate publish boundary.
|
|
112
|
+
- Vite's dependency-cache directory is redirected via `VITE_CACHE_DIR` (falls back to `../node_modules/.vite-viewer`, itself an ordinary repo build output, if unset) — never a `.vite` directory scattered elsewhere.
|
|
113
|
+
|
|
114
|
+
## 10. Viewer source layout
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
viewer/
|
|
118
|
+
index.html
|
|
119
|
+
vite.config.ts
|
|
120
|
+
tsconfig.json
|
|
121
|
+
public/icons/icon-192.png, icon-512.png (tracked static PWA icon assets)
|
|
122
|
+
src/
|
|
123
|
+
main.tsx
|
|
124
|
+
App.tsx
|
|
125
|
+
vite-env.d.ts
|
|
126
|
+
hooks/useViewerStatus.ts, useInstallPrompt.ts
|
|
127
|
+
components/StatusBanner.tsx, InstallButton.tsx
|
|
128
|
+
styles/index.css
|
|
129
|
+
|
|
130
|
+
src/viewerServer/ (Node-side; browser UI code kept out of this tree entirely)
|
|
131
|
+
port.ts (DEFAULT_VIEWER_PORT, VIEWER_HOST, isValidViewerPort)
|
|
132
|
+
httpServer.ts (createViewerServer: loopback static+status server)
|
|
133
|
+
viewerService.ts (startViewer: the one application-level use case)
|
|
134
|
+
openBrowser.ts (best-effort OS-native browser-open helper, no dependency)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
No existing `src/domain`, `src/application`, `src/artifacts`, `src/browser`, `src/request`, or `src/safety` module was moved or restructured. `src/domain/diagnostics.ts` gained two new closed-enum codes (`viewer-root-invalid`, `viewer-port-unavailable`), reusing the existing `Diagnostic`/`DIAGNOSTIC_SEVERITY` machinery rather than inventing a parallel viewer-only diagnostic type.
|
|
138
|
+
|
|
139
|
+
## 11. Node server / application boundary
|
|
140
|
+
|
|
141
|
+
- `createViewerServer` (`src/viewerServer/httpServer.ts`): builds (does not start) a `node:http` server. Rejects non-GET/HEAD methods (`405`). Serves `GET /api/status` (JSON: `ok`, `viewerProtocolVersion`, `producer`, `root`) with `cache-control: no-store`. Every other path is resolved against `assetsRoot` via `resolveAssetPath`, which decodes the URL, normalizes it, and refuses (returns `undefined`, treated as not-found) any path that would resolve outside `assetsRoot` — verified against four distinct traversal-attempt shapes in `tests/unit/viewerServer.test.ts`. Unknown non-asset routes fall back to `index.html` (SPA fallback); unknown asset-like paths (`.js`, `.png`, etc.) 404. The server never reads, lists, or serves anything under the caller-supplied evidence root.
|
|
142
|
+
- `startViewer` (`src/viewerServer/viewerService.ts`): the one application-level use case. Validates `--root` (`fs.stat`, must exist and be a directory) and `--port` (integer `0`–`65535`) before ever attempting to bind. Binds via `server.listen(port, '127.0.0.1')`; on `EADDRINUSE` (or any other bind error) returns a `viewer-port-unavailable` diagnostic and never retries on a different port. Returns `{ ok: true, url, port, host, root, close }` once actually listening; `close()` wraps `server.close()` in a promise. Never launches Playwright, never runs observation, never creates or modifies Observer artifacts.
|
|
143
|
+
- `defaultViewerAssetsRoot()` resolves `dist/viewer` relative to `viewerService.js`'s own compiled location (`import.meta.url`), not the caller's CWD — verified working end-to-end via the manual and automated built-CLI smoke tests (§9/§15).
|
|
144
|
+
|
|
145
|
+
## 12. PWA architecture and cache boundary
|
|
146
|
+
|
|
147
|
+
- `vite-plugin-pwa` (`generateSW` mode, `registerType: 'autoUpdate'`) generates `dist/viewer/manifest.webmanifest` (`name: "my-frontend-observer Viewer"`, `short_name: "Observer Viewer"`, `display: "standalone"`, `start_url: "/"`, `scope: "/"`, 192×192 and 512×512 PNG icons) and `dist/viewer/sw.js` + `dist/viewer/workbox-*.js`.
|
|
148
|
+
- Icons (`viewer/public/icons/icon-192.png`, `icon-512.png`) are tracked, hand-generated (via a one-off, non-committed Node/zlib script run from the session scratchpad) solid-circle PNGs — real, valid PNG files, not placeholders — committed as intentional static product assets under `viewer/public/`.
|
|
149
|
+
- **Cache boundary**: the built `sw.js` contains exactly one `registerRoute` call — a `NavigationRoute` SPA fallback with `denylist: [/^\/api\//]` — and its `precacheAndRoute` manifest lists only `index.html`, the built JS/CSS bundle, the two icons, `manifest.webmanifest`, and `registerSW.js`. No `runtimeCaching` entry was configured, so there is no mechanism by which a future evidence/media/API route could be silently served stale; `tests/unit/viewerPwaBuild.test.ts` asserts this directly against the real built `sw.js` (exactly one `registerRoute` call, it is a `NavigationRoute`, the `/api/` denylist regex is present, and no precache entry matches `/api`).
|
|
150
|
+
- Install affordance: `viewer/src/hooks/useInstallPrompt.ts` captures the real `beforeinstallprompt` event; `InstallButton` shows "Install prompt not offered by this browser yet" whenever the event has not fired (unsupported browser, criteria unmet, already installed) rather than a disabled-looking or misleading control — verified against real Chromium in `tests/browser/viewerShell.test.ts` (headless Chromium in this environment does not fire `beforeinstallprompt`, so the "not offered" branch is what real-browser testing here can prove; the "available" branch is implemented per the standard API contract but not independently provable without a PWA-installability-capable browser session in this environment — see §17 risks).
|
|
151
|
+
|
|
152
|
+
## 13. Public `view` CLI
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
my-frontend-observer view --root <evidence-root> [--port <n>] [--no-open] [--help]
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- `--root` (required): validated by `startViewer`, not the CLI parser — the parser only enforces presence/no-duplication.
|
|
159
|
+
- `--port` (optional): CLI-parser-validated integer in `[0, 65535]`; defaults (when omitted from the parsed options entirely, letting `startViewer` apply `DEFAULT_VIEWER_PORT`) to `4319`.
|
|
160
|
+
- `--no-open`: suppresses the best-effort browser auto-open.
|
|
161
|
+
- `--help`: prints `VIEW_HELP` and exits `0` without touching `startViewer`.
|
|
162
|
+
|
|
163
|
+
`runViewCommand` (`src/cli.ts`) is thin: parse → one `startViewer` call → print diagnostics-and-exit-1 on failure, or print `Viewer: <url>` / `Root: <root>` / a Ctrl+C hint on success, then (unless `--no-open`) attempt `openInDefaultBrowser`. It contains no artifact parsing, evidence derivation, comparison, contract, reference, fidelity, binding, or browser-observation logic. All eight existing v0.1–v0.7 commands are unchanged; `view` was added as a ninth `if (command === ...)` branch in `runCli`, and `TOP_LEVEL_HELP` now lists it.
|
|
164
|
+
|
|
165
|
+
The command does not block inside `runViewCommand`: it returns as soon as the server is confirmed listening. In real CLI usage the process keeps running afterward only because the server's own open listening socket keeps the Node event loop alive (verified in the built-CLI smoke test, §15) — not because the command explicitly awaits a shutdown signal. No `SIGINT`/`SIGTERM` handler was registered, to avoid accumulating process-wide listeners across repeated test invocations of `runCli(['view', ...])`; Ctrl+C therefore terminates the process via Node's default signal behavior, which is sufficient for this batch (no cleanup state exists yet to flush).
|
|
166
|
+
|
|
167
|
+
## 14. Browser auto-open decision
|
|
168
|
+
|
|
169
|
+
Implemented (not omitted): `src/viewerServer/openBrowser.ts` spawns the OS-native opener (`cmd /c start` on Windows, `open` on macOS, `xdg-open` on Linux) with no new dependency. It is called only after the server is confirmed listening, its promise rejection is caught in `runViewCommand` and printed as a non-fatal `stderr` note (verified in `tests/unit/cliViewDispatch.test.ts`: a rejected open still yields exit code `0`). `--no-open` is available for deterministic/headless use (used throughout this batch's own smoke testing).
|
|
170
|
+
|
|
171
|
+
## 15. Files created
|
|
172
|
+
|
|
173
|
+
- `src/viewerServer/port.ts`, `httpServer.ts`, `viewerService.ts`, `openBrowser.ts`
|
|
174
|
+
- `viewer/index.html`, `viewer/vite.config.ts`, `viewer/tsconfig.json`
|
|
175
|
+
- `viewer/src/main.tsx`, `App.tsx`, `vite-env.d.ts`
|
|
176
|
+
- `viewer/src/hooks/useViewerStatus.ts`, `useInstallPrompt.ts`
|
|
177
|
+
- `viewer/src/components/StatusBanner.tsx`, `InstallButton.tsx`
|
|
178
|
+
- `viewer/src/styles/index.css`
|
|
179
|
+
- `viewer/public/icons/icon-192.png`, `icon-512.png`
|
|
180
|
+
- `tests/unit/cliView.test.ts`, `cliViewDispatch.test.ts`, `viewerServer.test.ts`, `viewerPwaBuild.test.ts`
|
|
181
|
+
- `tests/browser/viewerShell.test.ts`
|
|
182
|
+
- `docs/reports/v0.8-viewer-runtime-pwa-batch1.md` (this file)
|
|
183
|
+
|
|
184
|
+
## 16. Files modified
|
|
185
|
+
|
|
186
|
+
- `src/cli.ts` — `view` command (help text, `parseViewArgs`, `runViewCommand`, dispatch wiring, `TOP_LEVEL_HELP` entry).
|
|
187
|
+
- `src/domain/diagnostics.ts` — two new diagnostic codes.
|
|
188
|
+
- `src/index.ts` — re-exports `startViewer`, `defaultViewerAssetsRoot`, `DEFAULT_VIEWER_PORT`, `VIEWER_HOST`, `isValidViewerPort`, `VIEWER_PROTOCOL_VERSION` for programmatic/library use, matching the existing export pattern for every other application-layer capability.
|
|
189
|
+
- `package.json` / `package-lock.json` — new devDependencies (§8), `build`/`typecheck` scripts extended.
|
|
190
|
+
- `tests/unit/cliFrontendContracts.test.ts` — updated the pre-existing `TST-401` "no future commands" guard (written in the v0.5 era) to include the now-legitimately-added `view` command while still asserting `annotation` (v0.9+) is absent.
|
|
191
|
+
- `docs/COMMANDS.md` — new `## view` section; `## Foundation commands` build/typecheck bullets extended.
|
|
192
|
+
- `docs/ARCHITECTURE.md` — new `## v0.8 Batch 1 (Viewer runtime and PWA foundation) — implemented` section.
|
|
193
|
+
- `docs/DEVELOPMENT.md` — short viewer build/smoke paragraph.
|
|
194
|
+
|
|
195
|
+
`docs/CURRENT_STATE.md` was deliberately **not** modified — this batch is not a release and does not claim v0.8 (or even all of Batch 1's later-batch-dependent acceptance criteria) is "current state."
|
|
196
|
+
|
|
197
|
+
## 17. Tests added and behavior protected
|
|
198
|
+
|
|
199
|
+
| Test file | Level | Protects |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| `tests/unit/cliView.test.ts` | unit (CLI dispatch, fast-fail paths) | `--help` lists `view`; `view --help` documents `--root`/`--port`/`--no-open`; missing `--root`; unrecognized flag; malformed/out-of-range `--port`; duplicated `--root`; nonexistent `--root` fails closed with `[viewer-root-invalid]` and no hang; `--root` pointing at a file fails closed; existing `observe`/`compare` help unaffected. |
|
|
202
|
+
| `tests/unit/cliViewDispatch.test.ts` | unit (mocked seam) | Thin delegation: `runViewCommand` calls `startViewer` exactly once with exactly the parsed `{root, port?}`; browser auto-open is attempted unless `--no-open`; a rejected browser-open is non-fatal (exit `0`) and reported to stderr. |
|
|
203
|
+
| `tests/unit/viewerServer.test.ts` | unit/integration (real `node:http`, fixture assets root) | Port validation bounds; loopback-only binding and matching reported URL; shell served at `/`; nested asset served with correct content-type; SPA fallback for unknown non-asset routes; `404` for a missing asset-like path (no silent SPA fallback there); `/api/status` returns the exact supplied root; write methods (`POST`/`PUT`/`DELETE`/`PATCH`) rejected with `405`; four distinct path-traversal encodings never leak the outside-root fixture file; the supplied evidence root is never served as static content; nonexistent/non-directory `--root` fails closed with `viewer-root-invalid` and never binds a socket; an already-bound port fails closed with `viewer-port-unavailable` (never a silent fallback port); `close()` actually releases the port for a subsequent bind. |
|
|
204
|
+
| `tests/unit/viewerPwaBuild.test.ts` | build/integration (real built `dist/viewer`, self-building if absent) | Valid manifest (`name`/`short_name`/`display: standalone`/`start_url`/`scope`); required 192×192 and 512×512 icons declared and their files exist in the built output; `sw.js` exists and `index.html` references the manifest; exactly one `registerRoute` (`NavigationRoute`, `/api/`-denylisted) and no evidence/API entries in the precache manifest. |
|
|
205
|
+
| `tests/browser/viewerShell.test.ts` | browser (real Chromium against the real built PWA) | Product identity/title/shell regions render; the real running server's status is reflected (exact evidence root shown); all three Batch 1 placeholder regions render with honest, non-fabricated text; install affordance shows the honest "not offered" state (never a fake enabled control) when the browser has not fired `beforeinstallprompt`; an intercepted/failed `/api/status` fetch produces the actionable "Local viewer server unavailable" banner rather than fabricating a session (and never shows the real evidence-root string in that state). |
|
|
206
|
+
|
|
207
|
+
Regression: the full existing `tests/unit/` (1036 tests, 54 files) and `tests/browser/` (127 tests, 11 files) suites were re-run unmodified except the one intentionally-updated `TST-401` guard, and all pass — this is direct evidence that `observe`, `compare`, `approve-baseline`, `save-change-contract`, `evaluate-contract`, `import-reference`, `approve-reference`, and `evaluate-reference-fidelity` are unaffected.
|
|
208
|
+
|
|
209
|
+
## 18. Validation commands and results
|
|
210
|
+
|
|
211
|
+
| Command | Result |
|
|
212
|
+
|---|---|
|
|
213
|
+
| `npm run typecheck` | **PASS** (both `tsconfig.json` and `viewer/tsconfig.json`, zero errors) |
|
|
214
|
+
| `npm run lint` | **PASS** (zero errors/warnings across the whole repo, including new `viewer/**/*.tsx` and `src/viewerServer/**/*.ts`) |
|
|
215
|
+
| `npm test` | **PASS** — 1036/1036 tests, 54/54 files |
|
|
216
|
+
| `npm run test:browser` | **PASS** — 127/127 tests, 11/11 files (real Chromium) |
|
|
217
|
+
| `npm run build` | **PASS** — produces `dist/{cli.js,index.js,domain,application,artifacts,browser,request,safety}` (unchanged Node/library output) plus `dist/viewerServer/**` and `dist/viewer/{index.html,assets,manifest.webmanifest,sw.js,workbox-*.js,icons}` |
|
|
218
|
+
| `npm run check:docs` | **PASS** — "Documentation check passed (17 required files)." |
|
|
219
|
+
|
|
220
|
+
## 19. Built viewer smoke (§15 of the task)
|
|
221
|
+
|
|
222
|
+
Command (using the WORKFLOW_ROOT-owned smoke root, not a repo-root or ad hoc location):
|
|
223
|
+
|
|
224
|
+
```powershell
|
|
225
|
+
node dist/cli.js view --root "<WORKFLOW_ROOT>\smoke\evidence-root" --port 4319 --no-open
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Result: **PASS**.
|
|
229
|
+
|
|
230
|
+
- Server started; printed exactly `Viewer: http://127.0.0.1:4319`, `Root: <smoke-root>`, `Press Ctrl+C to stop.`
|
|
231
|
+
- `GET /` → `200`, `GET /manifest.webmanifest` → `200`, `GET /sw.js` → `200`, `GET /api/status` → `200` JSON with the exact smoke root and `viewerProtocolVersion: "1.0.0"`.
|
|
232
|
+
- `netstat` confirmed the listener bound to `127.0.0.1:4319` only (never `0.0.0.0`).
|
|
233
|
+
- A directory listing of the smoke `--root` taken immediately before and immediately after the run is byte-for-byte identical (`diff` reported no differences) — no target/evidence files were created, modified, or deleted.
|
|
234
|
+
- The server process was located by its actual PID via `netstat` and terminated with `taskkill /F`; a follow-up `netstat` confirmed the port was released and no server process remained.
|
|
235
|
+
- Smoke logs and before/after listings are retained under `WORKFLOW_ROOT/logs/` (`smoke-server.log`, `smoke-final.log`, `pre-smoke-listing.txt`, `post-smoke-listing.txt`).
|
|
236
|
+
|
|
237
|
+
## 20. Skipped validation
|
|
238
|
+
|
|
239
|
+
None. Every command listed in task §14 was run to completion with a captured result (§18), and the built-viewer smoke (§15) was run against the actual built CLI, not only the in-process test harness.
|
|
240
|
+
|
|
241
|
+
## 21. Generated/untracked paths — final disposition
|
|
242
|
+
|
|
243
|
+
| Path | Disposition |
|
|
244
|
+
|---|---|
|
|
245
|
+
| `WORKFLOW_ROOT/cache/npm` (~212 MB) | Retained (ordinary npm cache; safe to delete, kept for reuse by later batches) |
|
|
246
|
+
| `WORKFLOW_ROOT/vite-cache` | Retained, empty (Vite build mode did not populate it) |
|
|
247
|
+
| `WORKFLOW_ROOT/logs/*` | Retained (smoke evidence) |
|
|
248
|
+
| `WORKFLOW_ROOT/smoke/evidence-root` | Retained, empty (reusable smoke fixture) |
|
|
249
|
+
| `WORKFLOW_ROOT/{tmp,fixtures,candidate,pack,my-dev-kit-index}` | Retained, empty/unused this batch |
|
|
250
|
+
| `node_modules/.vite-viewer` | Not created this batch (Vite did not need it in build mode); would be an ordinary, already-allowed repo build output if it ever appears |
|
|
251
|
+
| Repo-root `dist/` | Ordinary build output (already `.gitignore`d); rebuilt cleanly by `scripts/clean.mjs` every `npm run build` |
|
|
252
|
+
| Pre-existing repo-root `.my-dev-kit*`/`baselines`/`comparisons`/`contracts`/`evaluations`/`observations` | Pre-existing, untouched (see §6) |
|
|
253
|
+
|
|
254
|
+
No tarball, candidate install, or my-dev-kit index was produced this batch (§3), so `WORKFLOW_ROOT/pack`, `/candidate`, and `/my-dev-kit-index` remain empty by design, not by oversight.
|
|
255
|
+
|
|
256
|
+
## 22. Evidence v0.1–v0.7 behavior preserved
|
|
257
|
+
|
|
258
|
+
- All 1036 unit tests and 127 browser tests covering `observe`, `compare`, `approve-baseline`, `save-change-contract`, `evaluate-contract`, `import-reference`, `approve-reference`, and `evaluate-reference-fidelity` pass unmodified.
|
|
259
|
+
- `runCli`'s existing eight `if (command === ...)` branches are untouched; `view` was appended as a ninth branch.
|
|
260
|
+
- The only test content change outside the new viewer test files is the single, intentionally-updated `TST-401` help-surface guard (§16), which now asserts `view` is present (a legitimate v0.8 Batch 1 addition) while still asserting `annotation` (v0.9+) remains absent.
|
|
261
|
+
|
|
262
|
+
## 23. Evidence Batch 2+ functionality was not implemented
|
|
263
|
+
|
|
264
|
+
- No evidence indexing, artifact reader/adapter, evidence API route, screenshot/reference-image serving, SVG overlay, comparison/contract/reference/fidelity/binding/correlation/bounded-context UI, or annotation code exists anywhere in this batch's diff.
|
|
265
|
+
- The only HTTP route beyond static-asset serving is `GET /api/status`, which returns only `{ok, viewerProtocolVersion, producer, root}` — no Observer artifact content.
|
|
266
|
+
- The PWA service worker precaches only the built shell and declares no `runtimeCaching`, so no mechanism exists yet (or is needed yet) to guard against stale evidence caching — verified directly (§12).
|
|
267
|
+
- The React shell (`App.tsx`) renders exactly three honest placeholder strings for navigation/workspace/details; no fixture, mock, or fabricated observation/reference data is rendered anywhere in `viewer/src/`.
|
|
268
|
+
|
|
269
|
+
## 24. Remaining uncovered risks
|
|
270
|
+
|
|
271
|
+
- **Install-prompt "available" branch is implemented per spec but not independently browser-tested in this environment.** Headless Chromium under Playwright in this sandbox does not fire `beforeinstallprompt` (real installability criteria — HTTPS-or-localhost origin, engagement heuristics, manifest validity — are largely satisfied here since the origin is `http://127.0.0.1`, treated as a secure context, but headless automation does not reliably trigger the event). The "not offered" honest-fallback branch is proven; the "available" branch's logic was reviewed but not exercised against a live `beforeinstallprompt` event. A later batch (or manual verification in a real, non-headless browser) should confirm the install flow end-to-end.
|
|
272
|
+
- **`vite-plugin-pwa`'s Workbox-generated service worker was validated by source inspection/regex, not by loading it in a real Service Worker execution context** (no service-worker-lifecycle test — e.g. actually registering it, waiting for `activate`, and issuing an intercepted fetch — was written). The cache-boundary guarantee (§12) rests on the generated source containing exactly one denylisted `NavigationRoute` and no other `registerRoute` call, which is a strong but not runtime-executed proof.
|
|
273
|
+
- **No automated test proves the CLI process actually stays alive via the open server socket** after `runViewCommand` resolves (only manually verified in the smoke test, §19, and reasoned about in §13); a future batch could add a dedicated child-process test if this behavior becomes load-bearing for later batches' tooling.
|
|
274
|
+
- **The my-dev-kit bounded-retrieval step (task §7) was skipped** (§3) in favor of direct manual inspection; if a later batch relies on an actual `my-dev-kit-index` artifact existing from this batch, it does not.
|
|
275
|
+
|
|
276
|
+
## 25. Final verdict
|
|
277
|
+
|
|
278
|
+
Batch 1 ("Viewer runtime and PWA foundation") is implemented and independently validated: a built/packed-equivalent candidate starts `my-frontend-observer view --root <fixture>` and serves the same working React shell (with installable-PWA manifest/service-worker output) to a normal browser and a PWA-capable (real Chromium) browser from the fixed loopback origin `http://127.0.0.1:4319`, while every pre-existing CLI/library command and its test coverage remains unchanged and passing. No v0.8 Batch 2+ scope, no v0.9 annotation scope, and no release/publication action was taken. Package version remains `0.7.0`.
|