--- name: make-app-runtime description: Use when generating, refactoring, reviewing, or debugging Make App project runtime structure, workspace manifests, Service runtime, local/dev scripts, build outputs, Docker/K8s image entrypoints, publish readiness, or packaging errors such as missing `apps/service/dist/server.js`. Covers `apps/` workspace contracts, `apps/ui/dist`, `apps/service` port/build/start contracts, runtime config file location, runtime artifact tests, forwarded host/proto header preservation, and publish gates that include auth, default Trace ID, and applicable permission audits. Does not cover UI layout, authentication implementation, Trace behavior, permission logic, Make adapter env semantics, DSL modeling, Make CLI resource deployment, or canvas-table internals. metadata: version: 0.1.6 --- # make-app-runtime Use this skill for Make App runtime and packaging contracts. These rules are intentionally strict because platform image entrypoints and publish artifacts should not vary per POC. This skill owns project runtime structure, workspace manifests, build outputs, Service start entry, Service port baseline, runtime config file location, Docker/K8s runtime entry alignment, publish-readiness script guidance, and publish-readiness checks. It does not own UI layout (`makeui`), authentication implementation (`make-app-auth`), single-app permission logic (`make-app-permission`), Make adapter environment variable semantics (`make-app-service`), DSL modeling (`makedsl`), Make resource deployment (`makecli`), or canvas-table behavior (`canvas-table-integration`). ## Quick start 1. Identify whether the task touches `apps/`, `apps/service`, `apps/ui/dist`, package scripts, Docker/K8s, image entrypoints, publish readiness, or a runtime error such as `Cannot find module '/app/apps/service/dist/server.js'`. 2. Preserve the platform image contract unless the user explicitly says the platform contract itself is changing. 3. For a new App or an explicit runtime migration, verify the runtime baseline in `apps/package.json`: it must declare `"packageManager": "pnpm@10.20.0"` and `"engines": { "node": "22.20.0", "pnpm": "10.20.0" }`. Existing Make Apps keep their declared runtime during unrelated work; change it only after the user requests an explicit runtime migration. 4. For a new or explicitly migrated App, run package commands through Corepack (`corepack pnpm`), not an ambient `pnpm` binary. For an existing App without a runtime migration, use its compatible declared package manager, lockfile, and established workspace workflow. 5. For a new or explicitly reorganized App, verify workspace manifests: `apps/package.json`, `apps/pnpm-workspace.yaml`, `apps/ui/package.json`, and `apps/service/package.json`. For a legacy App, first identify its actual workspace structure without rewriting it. 6. Verify build artifacts before declaring ready: frontend `apps/ui/dist` and the Service entry selected by the actual platform image (`apps/service/dist/server.js` for the default contract). 7. Add or preserve a contract test for the Service runtime entry. ## Workspace contract Newly generated or explicitly runtime-reorganized Make App projects use: - `apps/ui` - `apps/service` - `apps/dsl` - `apps/docs` - `apps/packages/*` when shared packages are needed Required workspace files: - `apps/package.json` - `apps/pnpm-workspace.yaml` - `apps/ui/package.json` - `apps/service/package.json` `apps/pnpm-workspace.yaml` must include: ```yaml packages: - "ui" - "service" - "packages/*" ``` ## Package manager contract All newly generated Make App React workspaces, and existing Apps undergoing an explicit runtime migration, use the fixed runtime triple: **Node.js 22.20.0**, its bundled **Corepack 0.34.0**, and **pnpm 10.20.0**. The workspace root (`apps/package.json`) must declare the exact Node and pnpm versions: ```json { "packageManager": "pnpm@10.20.0", "engines": { "node": "22.20.0", "pnpm": "10.20.0" } } ``` Each executable workspace package, including `apps/ui/package.json` and `apps/service/package.json`, must declare `"engines": { "node": "22.20.0" }`. The project `engines.node` field rejects unsupported runtimes. Do not add `engineStrict` solely for this runtime baseline: it also enforces dependency engine declarations and requires a repository-specific compatibility decision. The repository must also contain a `.nvmrc` with exactly `22.20.0`, and CI or the Make build image must select exactly Node.js `22.20.0`. `engines` is a compatibility guard; it does not select the Node binary used by a build environment. Existing Make Apps retain their declared Node and package-manager versions during UI, auth, filtering, Service, or DSL work. That includes compatible npm and Yarn projects: preserve their existing `package-lock.json` or `yarn.lock`, workspace install target, and CI workflow. Do not rewrite `packageManager`, `engines`, lockfiles, or Node-selection files unless the user explicitly requests an explicit runtime migration. Perform that migration in a dedicated change with the project's tests and a Beta deployment. If the manager declaration, lockfile, workspace/CI workflow, or target platform build requirement conflicts, stop and report the compatibility blocker under `make-app-runtime`; do not generate a second lockfile or silently convert the App to pnpm. For new or explicitly migrated pnpm Apps, enable Corepack before project work and run installation, tests, builds, package additions, and publish gates as `corepack pnpm ...`. Corepack reads the project declaration; a globally installed `pnpm`, including a newer major version, must not be used for these Apps. For an existing compatible pnpm App, use its declared pnpm version through Corepack. For an existing npm or Yarn App without migration, use the repository's established commands and lockfile; do not introduce Corepack or pnpm solely for an unrelated change. Child workspace manifests must not declare a conflicting package-manager version. For a new or explicitly migrated pnpm App, `apps/package.json` must provide runnable scripts such as `app:ui`, `app:service`, `dev`, `test`, and `build`. `corepack pnpm --filter` targets must match the actual package names, including scoped names. A legacy App keeps its established equivalent scripts and workspace targets. `make-app-runtime` is the owner of `apps/package.json` generation and repair. `makecli app deploy` must not generate or rewrite workspace manifests. Treat `makecli app deploy` as a code deployment boundary unless the target makecli version is proven to run a stricter publish gate. Do not report a generated App as publish-ready merely because deploy succeeded. When preparing a new or explicitly migrated App for publish, provide enough project-local scripts and documentation for the agent or CI to run publish-readiness checks before deploy: - enable Corepack and install dependencies for `apps` with `corepack pnpm install --frozen-lockfile` - verify Node.js is exactly `22.20.0` and Corepack is exactly `0.34.0` - run the workspace build - run the `make-app-auth` published contract audit for Service-fronted Apps - run the `make-app-observability` Trace audit and behavior tests for every new Make App, whether direct-gateway or Service-fronted - run the `make-app-permission` contract audit when single-app permission enforcement is enabled or required by a repository-local delivery baseline - run Service gateway-mode contract tests proving local preview and published upstream scopes are separated - verify `apps/ui/dist` and `apps/service/dist/server.js` - run Service contract tests, including auth callback proxy behavior, when tests exist For a new or explicitly migrated pnpm Service-fronted App, prefer a project-local `verify:publish` script that runs the publish gate in one command. Keep `check:publish` for build/artifact checks, but do not make it the only release gate. Add `trace:audit` for every new App. When single-app permission enforcement is enabled or locally required, add `permission:audit` to that command; do not make unrelated Apps depend on a missing permission runtime. A legacy App uses its existing release command with the equivalent applicable checks. Recommended workspace scripts for a new or explicitly migrated pnpm App. Before adding these to `package.json`, copy or wrap the audit utilities into project-local `scripts/`; do not write user-specific skill install paths into generated projects. Do not copy these pnpm-specific scripts into a legacy npm/Yarn App without an explicit runtime migration. ```json { "scripts": { "check:runtime": "node -e \"if (process.versions.node !== '22.20.0') throw new Error(`Make Apps require Node.js 22.20.0; got ${process.versions.node}`)\" && test \"$(corepack --version)\" = \"0.34.0\"", "auth:audit": "node scripts/audit-auth-contract.mjs . --mode service-fronted --published", "trace:audit": "node scripts/audit-trace-contract.mjs . --mode service-fronted", "schema:diff": "cd .. && makecli diff -f apps/dsl --output=json", "check:publish": "corepack pnpm run build && test -f service/dist/server.js && test -d ui/dist", "verify:publish": "corepack pnpm run check:runtime && corepack pnpm run test && corepack pnpm run auth:audit && corepack pnpm run trace:audit && corepack pnpm run check:publish && corepack pnpm run schema:diff" } } ``` For an App with single-app permission enforcement, add `"permission:audit": "node scripts/audit-make-app-permission.mjs ."` and append `&& corepack pnpm run permission:audit` to `verify:publish`. For a direct-gateway App, use `--mode direct` in `trace:audit` and keep the same default Trace requirement. The Trace contract itself belongs to `make-app-observability`; this Skill only ensures its checks run before deployment. Do not describe `verify:publish` as a universal makecli hook unless the target makecli version supports it. It is a project-local quality gate to run before `makecli app deploy`. Do not pass backend-context flags through `verify:publish`. For a new or explicitly migrated pnpm App, run the gate as `corepack pnpm run verify:publish`; a compatible legacy App uses its established equivalent gate and package manager. Then deploy code to Beta with `makecli app deploy --context --profile --wait`. Follow the `makecli` skill for the Beta completion guide and, after explicit user authorization, publish that Beta version to Prod with `makecli app promote --context --profile --yes --wait`. Keep the same backend context/profile throughout; promotion uses the deployed Beta version and does not push local code. If a project-local Node wrapper must accept flags through `corepack pnpm run`, normalize argv by dropping a standalone `--` before parsing because `corepack pnpm run