A Hypermake project is declared by one file at the project root: hypermake.json. This page documents every key the loaders actually read — derived from the loader code, not from intent — with its type, default, and which parser reads it. This site's own hypermake.json is used as the primary worked example.
How the file is read
There is no single parser. Three read paths share the file, and they disagree about strictness. This is a real property of the current contract, so the reference states it up front and attributes every key below to its reader.
Unknown top-level keys are silently ignored — a typo like "recipeSource" is inert, not an error. Exceptions that do fail the load: a malformed rootUuid, and invalid privateJobs/hostResources service bindings.
Serve subsection decoders
Strict, per-block. dev.responseHeaders, dev.documentShells, dev.auth each get a dedicated decoder with unknown fields disallowed.
Any unknown field or malformed entry inside these blocks is a hard error: serve refuses to start.
Serve identity probe
Fallback-chain scavenger. dev.origin, dev.defaultTarget, dev.transport, dev.inspect are probed as raw paths — in hypermake.json first, then legacy locations in config.json.
Unreadable JSON and absent paths are skipped silently; the first value found wins.
Identity and roots
Identity keys — project loader (lenient)
Key
Type
Default
Notes
id
string
""
Project identity. The dev service falls back to the root directory's basename when empty. (The serve layer also reads id/name directly, bypassing the typed loader.)
name
string
""
Display name for registries and service records.
rootUuid
string
absent
Authored project identity: a lowercase RFC 4122 UUID, never derived or normalized by the system. Gates privileged connection/operator operations, which fail closed when it is missing. A malformed value fails every config load — this is the one top-level key the lenient loader validates.
Root-marker filenames projected to capability consumers. Root detection itself always walks up using the default set — it has to find the file before it can read it.
defaultTargets
string[]
[]
Declared default build targets, projected through the capabilities surface. No build path substitutes them today: a bare build still errors with missing build target. Declare and treat as advisory.
Identity in practice (the hypermake repo's own config)hypermake.json
Each entry: {id, origin, kind, path, handler?, tool?, commands?}. When neither recipeSources nor makeRecipeRoots is declared, src/ and recipes/ are auto-scanned if they contain .make files, and a root recipes.json is auto-registered as a native-spec source.
makeRecipeRoots
string[]
[]
Directories scanned recursively for .make recipe files under origin make. Equivalent to a recipe-dir source; this fixture declares both for the same directory.
phpCompatSources
string[]
[]
Legacy compat listing projected to capabilities. Actual compat recipes load through a recipeSources entry of kind compat/php-compat.
recipeSources kinds
kind
Meaning
native-spec (also "", pattern-json)
A JSON file of declarative pattern-recipe specs at path.
recipe-dir
A directory of .make recipe files at path, under this source's origin.
compat / php-compat
A PHP-compat recipe file at path.
manifest
Pattern recipes generated from a manifest file; handler defaults to manifestArtifact, commands defaults to a file-existence check.
lzr
The built-in LZR recipe pack; tool overrides the lzr binary name.
anything else
Silently skipped — a misspelled kind contributes no recipes and no error.
Protocol mappings
protocols (object[], project loader) maps protocol names to project directories: {"name": "public", "dir": "rendered/public"}. When the key is absent the defaults are src, cache, build, rendered, public → rendered/public, and the journal directory. Two names are core-owned and cannot be remapped — declared mappings for journal and request-projection are silently dropped and re-forced to their control directories — and the hypermake name maps to the Hypermake home directory unless the project declares it. See Protocols and addresses for how the mapped names behave; hypermake protocols list prints the effective registry.
One of on-first-command, recommend, off. Any other value falls back to recommend silently.
daemon.idleTTL
string
"4h0m0s"
Go duration string; idle shutdown TTL for the resident daemon. hypermake daemon status reports the effective policy and its source.
The dev block
Everything the resident dev service needs lives under dev. The four identity keys use the fallback-chain probe; the block-shaped keys each have their own decoder.
Serve identity — fallback-chain probe
Key
Type
Default
Notes
dev.origin
string
none
The public origin the service answers as, e.g. "https://lzr-testing.localhost". Probe order: --origin flag, then dev.origin and legacy paths in hypermake.json/config.json. Serve errors when nothing resolves.
dev.defaultTarget
string
"public"
The build target the service serves when none is passed.
dev.transport
string
"unix-socket"
unix-socket (socket under .hypermake/run/, fronted by a local reverse proxy) or tcp (loopback --addr).
dev.inspect
bool
false
Enables the Inspector surface. Also forced on by the --inspect flag or a *.localhost origin host.
Serve blocks — strict decoders (unknown fields are errors)
Key
Type
Default
Notes
dev.responseHeaders
object[]
[]
Each entry {path, set}: an exact URL path and a header-name→value object. Duplicate paths, duplicate header names (case-insensitive), non-ASCII values, Caddy placeholder syntax, and the reserved Service-Worker-Allowed header are all rejected.
dev.documentShells
object[]
[]
Each entry {shell, routePatterns}: an .html shell artifact served for document navigations whose path matches any pattern (* matches one segment). Applies only to requests with a document navigation destination; fragment fetches pass through.
dev.auth
object
absent
Fail-closed ingress binding for served deployments; shape below.
dev.requestProjections
object[]
[]
Each entry {schemaVersion, routePattern, targetPattern, provider, keyPattern} with schema hypermake.request-projection-route.v1. Providers are a closed set (approval-detail, job-detail); targets must be bounded rendered/public/ targets; route captures {name} bind the target and key.
dev.companions
object[]
[]
Sidecar processes the dev service supervises; schema hypermake.dev-companion.v1. Validated when the service materializes companion artifacts; shape below.
dev.edgeHandlers
object[]
[]
Edge-module declarations, schema hypermake.dev-edge-handler.v1: {id, module, directive, sourceTarget, configTarget, publicFileBinding, placement} with placement fixed to before-routing and a read-only, non-secret file binding.
dev.auth shape
All paths are canonical project-relative references; ingress must be one of application-unix-socket, control-unix-socket, private-probe and must be trusted by the referenced deployment policy, or serve refuses to start. exchangeDirectory and loginRedirects must be declared together. The device block enables the device login flow: the signing key is delivered only through the named environment variable, requestTtlSeconds is 1–600, and sessionTtlSeconds is capped by the deployment policy. Values below are placeholders — mint real policy material with hypermake auth owner-ceremony. Serving with authentication documents the policy files, the ceremony, and the refusal contract in full.
Placeholder shape (not a live configuration)hypermake.json
A companion declares an executable graph target, argv, and health probe; transport is unix-socket only, health exposure is private-control only, and routePrefix may not overlap another companion or the reserved /_hypermake and /lzr-runtime owners. Argv may not embed absolute paths or secret-shaped values; host access goes through declared placeholders: ${socket}, ${origin}, ${root}, and ${host:NAME} for a binding declared in top-level hostResources. Host resource kinds are a closed set: directory (read|read-write/private-path), file (read/private-path), credential-file (read/secret-material), unix-socket (connect/owner-socket).
Worked example (from the in-tree dev-companion fixture)hypermake.json
{name, dataTarget, adapterTarget?, operation?, patchPointer?, patchOp?, initialGeneration?, initialValue?} — named browser-writable resources, e.g. {"name": "demo.save", "dataTarget": "client://demo/status.json"}.
clientGraph.clientProtocols
object[]
[]
{protocol, patterns?, sensitivity, resources} — browser-owned protocol families with per-resource kinds and default values.
clientGraph.pipeline
object
absent
A client pipeline graph; normalized and validated when packaging, with diagnostics on invalid shapes.
clientGraph.modelPacks
object[]
[]
{id, manifestDigest, manifestUrl} references to digest-pinned model packs.
clientGraph.routeOwners
string[]
key absent
Authoritative owner set for route-manifest completeness. Presence matters: an empty list explicitly opts out of enforcement; an absent key derives owners from self-declaring src/!owner route dirs.
clientGraph.staticNavigationRoutes
string[]
key absent
Explicit opt-in per fixed route to static navigation serving; each entry must name exactly one built owned route. Never inferred.
Appendix: remaining keys
Lower-traffic keys — project loader (lenient)
Key
Type
Notes
privateJobs
object[]
Private-job provider declarations (subject prefixes, executor targets, service bindings). Normalized and validated at parse time — the one array that can fail the lenient load, including its hostResources service bindings.