Skip to content

feat(gui): one manifest contract for Flavian, Aurelius and Vespasian (#187) - #196

Merged
PAMulligan merged 2 commits into
mainfrom
feat/gui-unified-manifest-187
Nov 8, 2026
Merged

PAMulligan merged 2 commits into
mainfrom
feat/gui-unified-manifest-187

Conversation

@PAMulligan

Copy link
Copy Markdown
Collaborator

Slice 1 of #187 (stage 4 of packages/gui/docs/GUI-PLATFORM.md, epic #186). Does not close #187: the remaining slices are planned in this PR.

What changes

  • One contract. ProductId names all five products, ScreenId gains site, ScreenExtras gains frameworks (Aurelius's wizard choices) next to Flavian's themeStarters. ParserKey stays a closed union on purpose: the engine throws on an unknown key at run time, so (string & {}) would only hide typos; the new registry test checks that every parser a manifest names resolves. TaskKind now lists the kinds the manifests actually emit (prereq:*, init, docker:<DockerCommand>, site:<SiteCommand>, pipeline:<PipelineKind>, qa:*) instead of literals nothing used.
  • Three manifests, one registry. aurelius.ts is the fork's real manifest (Aurelius main 86bcc99) in place of the scaffold; vespasian.ts and types/site.ts are ported verbatim from Vespasian main ed0696c. All three are registered in PRODUCTS. ACTIVE_PRODUCT_ID stays flavian, so this build's behaviour is unchanged (the existing manifest tests prove it). Selecting the other two would still leave their fork-only screens unrendered until slices 2 and 3 land, and the docs say so.
  • Registry invariants (tests/shared/product/registry.test.mts, 26 tests): registry keys match manifest ids; Aurelius and Vespasian expose the screens their forks ship; wizard command kinds per product; and for every registered manifest: unique screen and step ids, labels, the prerequisite convention (prereq-check, parser prereq, exit codes [0, 1]), registered parsers, delegate targets inside the product, success codes include 0, and the manifest survives a JSON round trip (pure data).
  • Design and plan. docs/plans/2026-11-08-trajan-engine-reconciliation-design.md records the drift measured today (per-directory diff lines against both forks, the files only one copy has, where the contract split), goals, non-goals, anti-goals, the decisions taken here and the ones reserved for you. …-plan.md has the tasks for the next slices with files, interfaces and the tests that gate them: the Wix-site screen; the Aurelius additions (generic runStep IPC and useStep, extra prerequisite steps, the script-backed wizard, manifest-declared pipeline inputs, one QA artifact model, fillTemplate dropping empty sole placeholders); product-neutral transport and build identity; the engine's home; fork retirement.

Decisions I'd like you to confirm or overturn

From the design doc: Flavian's copy as the base (the issue's proposal); closed ParserKey; prefix-typed TaskKind; ScreenExtras as the union of the forks' extras; porting the fork manifests verbatim and registering them now. The two decisions only you can take (where the engine lives; one app vs branded builds) carry a recommendation each in the design doc and gate slice 5, not slices 2 to 4.

Verification

pnpm --filter @flavian/gui lint, typecheck, test (81 pass), build (the three manifests bundle) and the smoke test all pass.

🤖 Generated with Claude Code

…187)

Slice 1 of the Trajan engine reconciliation (stage 4 of GUI-PLATFORM.md,
epic #186). The three GUI forks had let the ProductManifest contract split
(ScreenId, ParserKey, CommandDescriptor, ScreenExtras, ProductId, TaskKind
all differed); this brings the forks' catalogs back under one contract in
this engine, without changing what the Flavian build does.

- manifest.ts: ProductId names all five products, ScreenId gains `site`,
  ScreenExtras gains `frameworks`; ParserKey stays a closed union on purpose
  (the engine throws on unknown keys at run time, so an open type would only
  hide typos; the registry test checks every parser a manifest names).
- types/task.ts: TaskKind lists the kinds the manifests emit (prereq:*, init,
  docker:<DockerCommand>, site:<SiteCommand>, pipeline:<PipelineKind>, qa:*)
  instead of literals nothing used.
- aurelius.ts is the fork's real manifest (Aurelius main 86bcc99) in place of
  the scaffold; vespasian.ts and types/site.ts are ported verbatim from
  Vespasian main ed0696c. Both are registered in PRODUCTS; ACTIVE_PRODUCT_ID
  stays flavian, so this build is unchanged.
- tests/shared/product/registry.test.mts pins the registry and, for every
  registered manifest: unique screen and step ids, labels, the prerequisite
  convention, registered parsers, delegate targets, exit codes, and that the
  manifest is plain JSON-serializable data.
- docs/plans/2026-11-08-trajan-engine-reconciliation-{design,plan}.md hold
  the measured drift, the decisions taken here, the decisions reserved for
  the owner (engine home, branded builds vs one app, signing) and the tasks
  for the remaining slices: the Wix-site screen, the Aurelius additions with
  a generic step runner, product-neutral transport, the engine's home, fork
  retirement. GUI-PLATFORM.md points at them.

gui lint, typecheck, 81 unit tests, build and smoke pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@PAMulligan
PAMulligan merged commit f073381 into main Nov 8, 2026
21 checks passed
@PAMulligan
PAMulligan deleted the feat/gui-unified-manifest-187 branch November 8, 2026 19:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GUI: reconcile the Flavian, Aurelius and Vespasian engine forks into one shared engine

1 participant