Deliver the full Manifest Inspector module for the Workbench UI with tree browsing, JSON/YAML rendering, provenance metadata, and diffing against prior manifest versions. This plan is spec-first and aligns with SDS-054 and PRD-025 (US-025-002).
PRD: docs/specs/shared/prd/025-workbench-ui.md (US-025-002, REQ-WB-002)
SDS: docs/specs/shared/sds/054-workbench-ui-service.md (Manifest Inspector Module)
Reference: docs/specs/shared/reference/011-manifest-schema.md (REF-011)
docs/specs/**/<context>.manifest.json and docs/specs/**/*.sds.manifest.jsonartifacts/manifests/<context>/<timestamp>.manifest.jsonartifacts/manifests/index.json (latest pointer + history metadata)artifacts/manifests/index.json (object keyed by context).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
"type": "object",
"additionalProperties": {
"type": "object",
"required": ["context", "latest", "history"],
"properties": {
"context": { "type": "string" },
"latest": { "type": "string" },
"history": {
"type": "array",
"items": {
"type": "object",
"required": ["manifestId", "timestamp"],
"properties": {
"manifestId": { "type": "string" },
"timestamp": { "type": "string", "format": "date-time" },
"author": { "type": "string" },
"message": { "type": "string" },
"sizeBytes": { "type": "integer", "minimum": 0 },
"manifestHash": { "type": "string" },
"tags": { "type": "array", "items": { "type": "string" } },
"validation": {
"type": "object",
"required": ["validationStatus", "validationTimestamp", "validationErrors"],
"properties": {
"validationStatus": { "type": "string", "enum": ["valid", "invalid"] },
"validationTimestamp": { "type": "string", "format": "date-time" },
"validationErrors": { "type": "array", "items": { "type": "string" } }
}
}
}
}
}
}
}
}
latest points to the most recent manifestId in history; history preserves the immutable chronological record for diff baselines.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"semantic-core": {
"context": "semantic-core",
"latest": "semantic-core@2026-01-19T20:01:12Z",
"history": [
{
"manifestId": "semantic-core@2026-01-18T16:45:02Z",
"timestamp": "2026-01-18T16:45:02Z",
"author": "sea-ci",
"message": "regenerate semantic-core",
"sizeBytes": 184233,
"manifestHash": "sha256:1a2b3c...",
"tags": ["ci"],
"validation": {
"validationStatus": "valid",
"validationTimestamp": "2026-01-18T16:45:05Z",
"validationErrors": []
}
}
]
}
}
tools/ir_to_manifest.py or a dedicated registry tool) to:
manifestHash (sha256)generatedAt timestamp (UTC)context, sdsId, prdIds, adrIdssourceSeaPath and sourceSeaHashindex.json in a deterministic ordertools/schemas/manifest.schema.json and persist validation status in index.json under validation for each manifest entry (validationStatus, validationTimestamp, validationErrors).Outcome: A stable manifest registry with historical versions and full provenance for diffing.
services/workbench-bff/ (FastAPI for parity with existing services)GET /api/manifests → list with metadata, validation status, latest versionGET /api/manifests/:id → manifest payload + provenance metadataGET /api/manifests/:id/versions → list of historical versionsGET /api/manifests/:id/diff?from=<hash>&to=<hash> → diff payload (JSON Patch)GET /api/manifests/:id/source → source SEA-DSL/ADR/PRD/SDS refs (paths + hashes)from (optional): manifest hash (sha256) to diff from. If omitted, defaults to the previous historical entry before to (or previous before latest if to omitted).to (optional): manifest hash (sha256) to diff to. If omitted, defaults to latest.1
2
3
4
5
6
7
8
9
{
"manifestId": "semantic-core",
"from": "sha256:1a2b3c...",
"to": "sha256:9f8e7d...",
"operations": [
{ "op": "replace", "path": "/model/types/Policy", "value": { "fields": ["id", "name"] } },
{ "op": "add", "path": "/runtime/messaging/outbox", "value": { "enabled": true, "table": "outbox_events" } }
]
}
400 for malformed hash values or inconsistent from/to selection404 for unknown manifest id or hash not found in registry history1
{ "error": "manifest_hash_not_found", "message": "Hash not found in history", "manifestId": "semantic-core", "hash": "sha256:deadbeef..." }
/api/manifests/semantic-core/diff (defaults to latest vs previous)/api/manifests/semantic-core/diff?from=sha256:1a2b3c...&to=sha256:9f8e7d....json, .yaml, .yml extensions; reject all others.docs/specs/ and artifacts/manifests/ only; blacklist everything else.tools/schemas/manifest.schema.json before serving.Outcome: Production API that provides complete manifest data, provenance, and diff history.
apps/workbench/src/pages/ManifestInspector.tsx (new page)apps/workbench/src/App.tsx (route + nav item)apps/workbench/src/components/ManifestTree.tsx (recursive tree, search, key-path selection)apps/workbench/src/components/ManifestProvenance.tsx (hash, timestamps, refs)apps/workbench/src/components/ManifestDiffViewer.tsx (structural + raw diff)apps/workbench/src/components/ManifestPayloadView.tsx (JSON/YAML toggle with highlight)apps/workbench/src/lib/manifest-api.ts (typed fetch wrapper with error typing)apps/workbench/src/types/manifest.ts (manifest DTOs)Outcome: Fully functional Manifest Inspector with rich inspection and diffing.
Outcome: Faster debugging and higher trust in manifest correctness.
Outcome: Verified end-to-end behavior with no placeholders or stubs.