You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build one loader that the CLI and Recipe Builder can use to fetch, validate, and cache a catalog. Return a validated catalog plus its source, content digest, freshness state, and any cache warning. Both clients must use the same rules for accepting current or cached data.
Parent: #275. Blocked by #249. This issue provides the JSON format, loader API, cache interface, and typed errors consumed by #272, #273, and #274.
Deliver the format and loader
Define the document in @repo/domain with formatVersion: 1, catalogId, requiredCapabilities, targets, and modules.
Export the full official definitions as JSON. Decode through Effect Schema so values such as TargetIdentity regain their methods.
Freeze the v1 capability set for supported tokens and contribution operations. Reject exports that exceed it. Adding a definition must not increase requirements for existing v1 clients. Keep these interpreter capabilities separate from generated-project supportedRuntimes.
Compute a digest of the received UTF-8 document after HTTP content decoding. Use it for diagnostics and cache integrity, not publisher authentication or a project version pin.
Keep one decoded catalog for the entire calling operation. A later load may return newer content.
Put the shared loader and runtime-neutral cache interface under packages/scaffold/src/service/catalog/. Export them through the browser-safe package entrypoint. Inject Effect HTTP and cache services. Use an in-memory test cache here; #273 owns filesystem persistence and #274 owns browser persistence.
Define cache behavior
Attempt a current fetch on every new load. Use ETag or Last-Modified when available. Key cache entries by normalized source URL. Store the document bytes, digest, HTTP validators, and last successful fetch or revalidation time.
Result
Required behavior
Valid HTTP 200 document
Validate the complete effective catalog, then replace the cache entry and return current data.
HTTP 304 with a usable entry
Return that document and update its successful revalidation time.
HTTP 304 without a usable entry
Retry once without validators. Fail if the server still supplies no usable document.
Transport failure, timeout, HTTP 408, 429, or 5xx
Return a compatible validated cache entry with a stale-data warning. Fail if no such entry exists.
Other failed HTTP status, invalid JSON, HTML response, invalid catalog, or unsupported protocol or capability
Return a typed error. Do not hide the failure behind an older cache entry.
Cache read failure or corrupt or incompatible entry
Attempt the network. Treat that cache entry as unavailable.
Cache write failure after a valid fetch
Return the valid document with a persistence warning. Do not fail the current operation.
Recheck cached byte integrity and engine compatibility before reuse. Age alone does not invalidate a compatible entry. Never use another URL's entry or replace valid cached data with an invalid response. Cache writes must publish a whole entry atomically; client adapters implement that requirement.
Do not disable TLS verification. Browser fetch errors may hide the underlying network or CORS cause, so do not invent a diagnosis. Return warning data that lets each client show the source and last validation time. #273 renders warnings to stderr; #274 renders a persistent notice.
Limit decompressed input to 8 MiB and the total load to 15 seconds, including the single 304 recovery request. Check the byte limit while receiving data. Cancellation must cancel the request and release streams. If measurements justify changing a limit, record the reason and retain boundary tests.
Done when
The complete official catalog survives export and decode with its data and schema-class behavior intact.
Unsupported formats, capabilities, and invalid composed catalogs produce distinct actionable errors before planning.
Controlled HTTP tests cover every row of the cache table, byte limits, cancellation, and the total timeout.
A fake clock makes warning timestamps deterministic.
Changing the server document affects a later load but cannot replace an already returned catalog.
The loader works through both host and browser-safe imports without host filesystem dependencies.
Keep out of this issue
Filesystem and IndexedDB adapters, UI messages, project configuration fields, hosted assets, deployment, community source selection, and changes to generated templates. #272 owns StackConfig.$schema and publication.
Validate
Run bun format, bun lint, bun run type-check, and scoped bun run test --filter=<workspace> commands. Never use bun test. Tests must use controlled HTTP and cache fixtures rather than the public registry. Run bun run okf:check for knowledge changes.
Build one loader that the CLI and Recipe Builder can use to fetch, validate, and cache a catalog. Return a validated catalog plus its source, content digest, freshness state, and any cache warning. Both clients must use the same rules for accepting current or cached data.
Parent: #275. Blocked by #249. This issue provides the JSON format, loader API, cache interface, and typed errors consumed by #272, #273, and #274.
Deliver the format and loader
@repo/domainwithformatVersion: 1,catalogId,requiredCapabilities,targets, andmodules.TargetIdentityregain their methods.supportedRuntimes.Put the shared loader and runtime-neutral cache interface under
packages/scaffold/src/service/catalog/. Export them through the browser-safe package entrypoint. Inject Effect HTTP and cache services. Use an in-memory test cache here; #273 owns filesystem persistence and #274 owns browser persistence.Define cache behavior
Attempt a current fetch on every new load. Use ETag or Last-Modified when available. Key cache entries by normalized source URL. Store the document bytes, digest, HTTP validators, and last successful fetch or revalidation time.
Recheck cached byte integrity and engine compatibility before reuse. Age alone does not invalidate a compatible entry. Never use another URL's entry or replace valid cached data with an invalid response. Cache writes must publish a whole entry atomically; client adapters implement that requirement.
Do not disable TLS verification. Browser fetch errors may hide the underlying network or CORS cause, so do not invent a diagnosis. Return warning data that lets each client show the source and last validation time. #273 renders warnings to stderr; #274 renders a persistent notice.
Limit decompressed input to 8 MiB and the total load to 15 seconds, including the single 304 recovery request. Check the byte limit while receiving data. Cancellation must cancel the request and release streams. If measurements justify changing a limit, record the reason and retain boundary tests.
Done when
Keep out of this issue
Filesystem and IndexedDB adapters, UI messages, project configuration fields, hosted assets, deployment, community source selection, and changes to generated templates. #272 owns
StackConfig.$schemaand publication.Validate
Run
bun format,bun lint,bun run type-check, and scopedbun run test --filter=<workspace>commands. Never usebun test. Tests must use controlled HTTP and cache fixtures rather than the public registry. Runbun run okf:checkfor knowledge changes.