Ownership Manifest & Lease Headers
The ownership manifest tells Weldr which parts of a generated project remain fully managed, which expose safe extension points, and which surfaces are considered fully ejected. It lives at the project root as weldr.ownership.yaml
and is evaluated before every regeneration.
Manifest schema
version: ownership/v2
surfaces:
model:
mode: managed
app_model_segments:
- entities
- relationships
- workflows
db: managed # drizzle schema + SQL migrations
auth: managed
api:
mode: extended # generated segments preserved, custom hooks allowed
hooks:
- src/api/_hooks/**/*.ts
actions:
mode: extended
automation:
mode: managed
domain_logic:
mode: ejected
entrypoints:
- src/domain/**/*.ts
ui: managed
ui_pages:
mode: extended
app_model_segments:
- pages
- navigation
ui_components:
mode: extended
eject_scopes:
- src/app/**/Custom*.tsx
- src/components/_custom/**/*
ui_theme:
mode: managed
styling: ejected
infra: managed
ci: managed
Surfaces that are omitted default to managed
. Structured entries allow extra metadata:
| Field | Meaning |
| ------------------- | ------------------------------------------------------------ |
| hooks
| Glob patterns for additional user-owned files to load. |
| entrypoints
| Runtime import globs used when a surface is ejected. |
| eject_scopes
| UI/component globs that Weldr will never overwrite. |
| app_model_segments
| Which App Model segments the surface governs (e.g. entities
, pages
). |
Unknown surface keys are ignored and reported as warnings.
Effective state at runtime
loadOwnershipState()
resolves the manifest (or produces an all-managed default when missing). The resolved shape is attached to the IR as ir.ownership
, so codegen planners and the CLI always operate with the same surface modes. The helper formatOwnershipSummary()
powers DX tooling such as weldr doctor
.
File leases
Every generated artifact now carries a header describing its surface, ownership mode, and generator:
/** @weldr
surface: api
mode: extended
region-tags: on
generator: template
version: ownership/v2
**/
Leases make regeneration deterministic:
surface
ties the file back to the manifest.mode
records whether Weldr may overwrite, merge, or avoid the file.region-tags
tracks whether generated/custom segments are expected (used in later phases).generator
clarifies which pipeline produced the file (template
, llm
, or manual
).ensureLeaseHeader()
inserts or refreshes the header without touching user code, while extractLease()
parses existing files for verification.
Extended regions
When a surface is set to extended
, Weldr emits paired regions in the generated file so that custom code survives regeneration:
// @weldr:begin crud-order
// generated code here
// @weldr:end crud-order
// @custom:begin order-helpers
// developer-owned code lives here
// @custom:end order-helpers
During a subsequent codegen run we only replace the @weldr
blocks, leaving the @custom
bodies untouched. If a custom block disappears from the latest template we raise a conflict instead of silently deleting user code.
Contracts
contracts
describe the TypeScript surface a user-owned module must expose once a surface is ejected. Each contract entry specifies a module path relative to the generated workspace and a list of exports Weldr will type-check after regeneration. Example:
contracts:
- id: domain.orders
surface: domain_logic
module: src/domain/orders.ts
exports:
- name: createOrder
kind: value
type: '(input: CreateOrderInput) => Promise<Order>'
- name: Order
kind: type
After codegen, Weldr synthesises a temporary TypeScript program that imports each contract and verifies:
kind: default
) is present.type
string is supplied, the exported symbol matches the expected signature in both directions.${namespace}.${export}
identifier (for example, domainOrders.createOrder
).Failures surface as build errors (weldr doctor
/ weldr sync
/ weldr contracts check
) with the contract id and export name that violated the agreement. This keeps ejected modules honest while letting developers own their implementation details.
CLI commands
weldr doctor
— prints the effective ownership table and highlights manifest warnings.weldr leases verify
— scans the local workspace, comparing file headers with the recorded manifest and current ownership policy.weldr contracts check
— validates contract adapters against developer-owned modules, reporting missing exports and type mismatches.Each command accepts --dir
to inspect a specific workspace.
Defaults & safety nets
managed
(no warnings).This layer is the foundation for the broader partial-ejection roadmap: once leases and ownership metadata are in place, we can introduce region-level merges, contract validation, and CLI workflows without worrying about silent overwrites.