@agenticprimitives/create-app 0.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Agentic Trust Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # @agenticprimitives/create-app
2
+
3
+ ```
4
+ npx @agenticprimitives/create-app my-product --template product-repo --pin 1.0.0-alpha.24
5
+ cd my-product && pnpm install && npx ap doctor
6
+ ```
7
+
8
+ Writes a product repository the way spec 399 §3.6 describes it — the shape `ap-discovery`, `ap-home` and
9
+ `ap-naming` are created from, never a copy of the monorepo root:
10
+
11
+ | Written | Purpose |
12
+ | --- | --- |
13
+ | `package.json`, `pnpm-workspace.yaml`, `.npmrc`, `tsconfig.base.json` | pnpm workspace over `apps/*` + `examples/*`; strict peers; exact `@agenticprimitives/*` pins |
14
+ | `agentic.lock.json` | the coherent pin set, the rules-source digests, the doctor config, the template revision |
15
+ | `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/*.mdc` | projected from the pinned rules source (edit the source, run `ap doctor --rules --write`) |
16
+ | `.github/workflows/ci.yml` | typecheck · test · `ap doctor` · `ap doctor --rules` |
17
+ | `.github/workflows/live-gates-nightly.yml` | `ap test --live-gates live-gates.json` + `ap conform a2a\|mcp` against the shadow deployment |
18
+ | `live-gates.json` | the gates ledger (spec 392 shape), empty until the first verify script moves in |
19
+ | `wrangler.example.toml` | the env layout: `env-a` / `env-b` live (Ring 0 deploys until the cut), `env-a-split` shadow (this repo) |
20
+ | `scripts/set-cloudflare-secrets.sh` | per-env secrets from a gitignored `.secrets.<env>` file, never echoed |
21
+ | `DEPLOYER.md`, `docs/MOVED.md` | deployer of record per app + env; the text the cut PR leaves in Ring 0 |
22
+
23
+ Options: `--name <kebab>` (defaults to the directory name), `--pin <exact version>` (defaults to the generating
24
+ devkit's version; resolve a dist-tag afterwards with `ap upgrade --pin <tag>`), `--json`.
25
+
26
+ Exit codes: `0` written · `2` usage (non-empty dir, bad name, bad pin, unknown template) · `3` error.
27
+
28
+ The template carries no hostname, no vertical vocabulary and no key (ADR-0021): every deployment-specific value
29
+ is a `<placeholder>` the product fills in.
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ // create-app — the Developer Kit generator (spec 398 §10.3, spec 399 §3.6).
3
+ //
4
+ // npx @agenticprimitives/create-app <dir> --template product-repo [--name <kebab>] [--pin <exact-version>] [--json]
5
+ //
6
+ // Writes a product repository from the template, pins one coherent @agenticprimitives/* set, projects the rules
7
+ // files, and leaves `pnpm install` + `ap doctor` to you (printed at the end). Exit 0 written · 2 usage · 3 error.
8
+ import { resolve } from 'node:path';
9
+ import { createApp, TEMPLATE_NAMES } from '../dist/index.js';
10
+
11
+ const argv = process.argv.slice(2);
12
+ const flag = (n) => argv.includes(`--${n}`);
13
+ const opt = (n) => { const i = argv.indexOf(`--${n}`); return i >= 0 && !String(argv[i + 1] ?? '--').startsWith('--') ? argv[i + 1] : undefined; };
14
+ const dir = argv.find((a, i) => !a.startsWith('--') && !(i > 0 && argv[i - 1].startsWith('--') && opt(argv[i - 1].slice(2)) === a));
15
+ const json = flag('json');
16
+ if (!dir || flag('help')) {
17
+ const usage = `create-app <dir> --template ${TEMPLATE_NAMES.join('|')} [--name <kebab>] [--pin <exact-version>] [--json]`;
18
+ if (json) console.log(JSON.stringify({ ok: !!dir, usage })); else console.log(usage);
19
+ process.exit(dir ? 0 : 2);
20
+ }
21
+ try {
22
+ const result = await createApp({ dir: resolve(dir), template: opt('template') ?? 'product-repo', name: opt('name'), pin: opt('pin') });
23
+ if (json) console.log(JSON.stringify({ ok: true, result }, null, 2));
24
+ else console.log(`create-app · ${result.template} → ${result.dir} (${result.name}, pinned ${result.pin})\n${result.files.map((f) => ` ${f}`).join('\n')}\n\nnext: cd ${result.dir} && pnpm install && npx ap doctor`);
25
+ } catch (e) {
26
+ const code = e?.code ?? 'E_UNEXPECTED';
27
+ if (json) console.log(JSON.stringify({ ok: false, error: { code, message: e.message } })); else console.error(`✗ ${code}: ${e.message}`);
28
+ process.exit(code === 'E_USAGE' ? 2 : 3);
29
+ }
@@ -0,0 +1,34 @@
1
+ import { type DoctorConfigOverrides } from '@agenticprimitives/devkit';
2
+ export declare const PACKAGE_NAME: "@agenticprimitives/create-app";
3
+ export declare const PACKAGE_STATUS: "w0-product-repo-template";
4
+ export declare const SPEC_REF: "specs/399-repository-split-program.md";
5
+ export declare const TEMPLATES_DIR: string;
6
+ export declare const TEMPLATE_NAMES: readonly ["product-repo"];
7
+ export type TemplateName = (typeof TEMPLATE_NAMES)[number];
8
+ /** Bump when the template tree changes shape; recorded in the generated lock so `ap upgrade` can diff it later. */
9
+ export declare const TEMPLATE_REVISION = "2026-09-11.1";
10
+ /** The packages every product pins from the start (the kit, the live-gates runner, the two conformance suites). */
11
+ export declare const BASELINE_PINS: readonly ["@agenticprimitives/devkit", "@agenticprimitives/evaluation", "@agenticprimitives/a2a", "@agenticprimitives/mcp-protocol"];
12
+ export interface CreateAppOptions {
13
+ /** Absolute target directory; created if absent, must be empty or absent. */
14
+ dir: string;
15
+ template?: TemplateName;
16
+ /** Product / repository name (`ap-discovery`). Defaults to the directory's base name. */
17
+ name?: string;
18
+ /** Exact version every baseline @agenticprimitives/* pin gets. Defaults to the generating devkit's version. */
19
+ pin?: string;
20
+ devkitVersion?: string;
21
+ /** Extra substitutions `{{key}}` → value. */
22
+ vars?: Record<string, string>;
23
+ }
24
+ export interface CreateAppResult {
25
+ dir: string;
26
+ template: TemplateName;
27
+ name: string;
28
+ pin: string;
29
+ files: string[];
30
+ }
31
+ /** The doctor config a fresh product carries: no monorepo layout, exact pins required, rules from the bundled corpus. */
32
+ export declare function productDoctorConfig(name: string): DoctorConfigOverrides;
33
+ export declare function createApp(opts: CreateAppOptions): Promise<CreateAppResult>;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAA4G,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEjL,eAAO,MAAM,YAAY,EAAG,+BAAwC,CAAC;AACrE,eAAO,MAAM,cAAc,EAAG,0BAAmC,CAAC;AAClE,eAAO,MAAM,QAAQ,EAAG,uCAAgD,CAAC;AAEzE,eAAO,MAAM,aAAa,QAAmE,CAAC;AAC9F,eAAO,MAAM,cAAc,2BAA4B,CAAC;AACxD,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3D,mHAAmH;AACnH,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,mHAAmH;AACnH,eAAO,MAAM,aAAa,sIAAuI,CAAC;AAElK,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+GAA+G;IAC/G,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE;AAEpH,yHAAyH;AACzH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAevE;AAkBD,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuChF"}
package/dist/index.js ADDED
@@ -0,0 +1,109 @@
1
+ // @agenticprimitives/create-app — the generator (spec 398 §10.3 `npx @agenticprimitives/create-app@<release>`,
2
+ // spec 399 §3.6 the product-repo template). One template today: `product-repo`, the shape every product repository
3
+ // starts from — W1 creates ap-discovery from it, never from a copy of the monorepo root. Generation is pure over
4
+ // the template tree plus a substitution map; the rules files are projected by the devkit so a product carries the
5
+ // doctrine by digest from day one (ADR-0063 §8).
6
+ import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
7
+ import { dirname, join, relative, sep } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { DevkitError, ERROR_CODES, loadRulesCorpus, projectRules, rulesLockEntries, writeLock } from '@agenticprimitives/devkit';
10
+ export const PACKAGE_NAME = '@agenticprimitives/create-app';
11
+ export const PACKAGE_STATUS = 'w0-product-repo-template';
12
+ export const SPEC_REF = 'specs/399-repository-split-program.md';
13
+ export const TEMPLATES_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'templates');
14
+ export const TEMPLATE_NAMES = ['product-repo'];
15
+ /** Bump when the template tree changes shape; recorded in the generated lock so `ap upgrade` can diff it later. */
16
+ export const TEMPLATE_REVISION = '2026-09-11.1';
17
+ /** The packages every product pins from the start (the kit, the live-gates runner, the two conformance suites). */
18
+ export const BASELINE_PINS = ['@agenticprimitives/devkit', '@agenticprimitives/evaluation', '@agenticprimitives/a2a', '@agenticprimitives/mcp-protocol'];
19
+ /** The doctor config a fresh product carries: no monorepo layout, exact pins required, rules from the bundled corpus. */
20
+ export function productDoctorConfig(name) {
21
+ return {
22
+ webNoDirectMcp: { browserApps: [], allowMarkers: ['@external-mcp-client-demo'] },
23
+ noPrivateKeys: { roots: ['apps', 'examples'], allowedIn: [], toleratedEnvNames: [] },
24
+ noHmacHomeBridge: { dir: 'apps', hmacCall: 'bridgeInteractions', sessionRpcCall: 'callInteractions', ceilings: { hmac: 0, total: 0 } },
25
+ noCrossSubjectVaultReads: { roots: [], exemptFiles: ['self-only.ts'], gate: 'subjectOfRead' },
26
+ failOpenKnobs: { roots: ['apps', 'examples'], allowlist: [] },
27
+ internalMarkerSplit: { src: 'apps', secret: 'A2A_CUSTODY_BRIDGE_SECRET', marker: 'x-ap-internal', budget: {} },
28
+ custodianCoverage: { skip: `${name} carries no Home custody surface yet — enable when a Home moves in (specs 294/295)` },
29
+ archetypeCatalog: { skip: `${name} carries no archetype catalog yet — enable when a Home moves in (spec 354 §3)` },
30
+ capabilityVocabulary: { homeGlobs: ['apps/**/*.{ts,tsx}'], packagesGlob: 'packages/*/src/**/*.ts', wireAllowed: [] },
31
+ demoPersonOrgDistinct: { skip: `${name} carries no persona roster yet — enable when @agenticprimitives-demo/estate is consumed (spec 399 §2.6)` },
32
+ rulesDrift: { cursorRules: '.cursor/rules', lock: 'agentic.lock.json', agentsMd: 'AGENTS.md', claudeMd: 'CLAUDE.md' },
33
+ lockCoherent: { allowWorkspace: false, scope: '@agenticprimitives/' },
34
+ };
35
+ }
36
+ function substitute(text, vars) {
37
+ return text.replace(/\{\{([a-zA-Z0-9_.-]+)\}\}/g, (m, k) => (vars[k] !== undefined ? vars[k] : m));
38
+ }
39
+ function walk(dir) {
40
+ const out = [];
41
+ for (const e of readdirSync(dir).sort()) {
42
+ const p = join(dir, e);
43
+ if (statSync(p).isDirectory())
44
+ out.push(...walk(p));
45
+ else
46
+ out.push(p);
47
+ }
48
+ return out;
49
+ }
50
+ const TEXT = /\.(md|json|yaml|yml|toml|ts|tsx|mjs|js|sh|txt|gitignore|tmpl)$|^(\.gitignore|\.npmrc)$/;
51
+ export async function createApp(opts) {
52
+ const template = opts.template ?? 'product-repo';
53
+ if (!TEMPLATE_NAMES.includes(template))
54
+ throw new DevkitError(ERROR_CODES.E_USAGE, `unknown template "${template}" (known: ${TEMPLATE_NAMES.join(', ')})`);
55
+ const src = join(TEMPLATES_DIR, template);
56
+ if (!existsSync(src))
57
+ throw new DevkitError(ERROR_CODES.E_INPUT_MISSING, `template tree missing: ${src}`);
58
+ if (existsSync(opts.dir) && readdirSync(opts.dir).length > 0)
59
+ throw new DevkitError(ERROR_CODES.E_USAGE, `${opts.dir} is not empty — create-app writes only into an empty or absent directory`);
60
+ const name = opts.name ?? opts.dir.split(sep).filter(Boolean).pop() ?? 'product';
61
+ if (!/^[a-z][a-z0-9-]*$/.test(name))
62
+ throw new DevkitError(ERROR_CODES.E_USAGE, `name "${name}" must be kebab-case (a-z, 0-9, -)`);
63
+ const devkitVersion = opts.devkitVersion ?? readOwnDevkitVersion();
64
+ const pin = opts.pin ?? devkitVersion;
65
+ if (!/^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/.test(pin))
66
+ throw new DevkitError(ERROR_CODES.E_USAGE, `--pin "${pin}" must be an exact version (use \`ap upgrade --pin <tag>\` after generation to resolve a dist-tag)`);
67
+ const vars = { name, pin, devkitVersion, templateRevision: TEMPLATE_REVISION, ...(opts.vars ?? {}) };
68
+ mkdirSync(opts.dir, { recursive: true });
69
+ const files = [];
70
+ for (const abs of walk(src)) {
71
+ const relPath = relative(src, abs).split(sep).join('/');
72
+ const target = relPath.endsWith('.tmpl') ? relPath.slice(0, -5) : relPath;
73
+ const out = join(opts.dir, target);
74
+ mkdirSync(dirname(out), { recursive: true });
75
+ const base = target.split('/').pop() ?? '';
76
+ if (TEXT.test(base) || TEXT.test(relPath))
77
+ writeFileSync(out, substitute(readFileSync(abs, 'utf8'), vars));
78
+ else
79
+ cpSync(abs, out);
80
+ files.push(target);
81
+ }
82
+ // The lock: the coherent baseline set, the doctor config, the template revision; rules digests from the projection.
83
+ const corpus = loadRulesCorpus({ root: opts.dir });
84
+ const lock = {
85
+ lockVersion: 1,
86
+ packages: Object.fromEntries(BASELINE_PINS.map((p) => [p, pin])),
87
+ rules: rulesLockEntries(corpus),
88
+ devkit: devkitVersion,
89
+ template: { name: template, revision: TEMPLATE_REVISION },
90
+ doctor: productDoctorConfig(name),
91
+ };
92
+ writeLock(opts.dir, lock);
93
+ files.push('agentic.lock.json');
94
+ const projected = projectRules({ root: opts.dir, corpus, write: true, all: true, createCursorDir: true });
95
+ for (const p of projected)
96
+ if (p.status === 'written')
97
+ files.push(p.path);
98
+ return { dir: opts.dir, template, name, pin, files: [...new Set(files)].sort() };
99
+ }
100
+ function readOwnDevkitVersion() {
101
+ try {
102
+ const p = join(dirname(fileURLToPath(import.meta.url)), '..', 'node_modules', '@agenticprimitives', 'devkit', 'package.json');
103
+ return JSON.parse(readFileSync(p, 'utf8')).version;
104
+ }
105
+ catch {
106
+ return '0.0.0';
107
+ }
108
+ }
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@agenticprimitives/create-app",
3
+ "version": "0.0.0-alpha.1",
4
+ "description": "The Developer Kit generator (spec 398 §10.3, spec 399 §3.6): `create-app <dir> --template product-repo` writes a product repository — pnpm workspace, exact @agenticprimitives/* pins, agentic.lock.json, `ap doctor` + `ap test` CI, a nightly live-gates workflow over the evaluation runner, a generic wrangler env layout with a shadow env, the projected rules files — so a product is built from the template, never from a copy of the monorepo root.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
9
+ "directory": "packages/create-app"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "bin": {
15
+ "create-app": "./bin/create-app.mjs"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "LICENSE",
25
+ "dist",
26
+ "bin",
27
+ "templates",
28
+ "spec.md",
29
+ "README.md"
30
+ ],
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "dependencies": {
35
+ "@agenticprimitives/devkit": "0.0.0-alpha.1"
36
+ },
37
+ "devDependencies": {
38
+ "vitest": "^4.1.8"
39
+ },
40
+ "keywords": [
41
+ "agentic",
42
+ "primitives",
43
+ "create-app",
44
+ "generator",
45
+ "template",
46
+ "product-repo"
47
+ ],
48
+ "scripts": {
49
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
50
+ "typecheck": "tsc -p tsconfig.json --noEmit",
51
+ "test": "vitest run",
52
+ "test:unit": "vitest run test/unit --passWithNoTests",
53
+ "test:watch": "vitest",
54
+ "clean": "rm -rf dist"
55
+ }
56
+ }
package/spec.md ADDED
@@ -0,0 +1,11 @@
1
+ # @agenticprimitives/create-app — package spec
2
+
3
+ Spec of record: [specs/399-repository-split-program.md](../../specs/399-repository-split-program.md) §3.6 (the
4
+ product-repo template: pnpm workspace, exact pins, `agentic.lock.json`, `ap doctor` + `ap test` in CI, the wrangler env
5
+ layout with a shadow env, secrets script, nightly live-gates workflow over `packages/evaluation`'s runner, generated
6
+ rules files — "done when `ap-discovery` is created from it") and [specs/398-agentic-primitives-ux-strategy.md](../../specs/398-agentic-primitives-ux-strategy.md)
7
+ §10.2–10.5 (`packages/create-app` is the generator; `templates/` is the tree it consumes; white-label content stays out).
8
+
9
+ Owns: the template tree, the substitution + generation, the product's initial `agentic.lock.json` (baseline pins,
10
+ rules digests, doctor config). Does not own: the rules source or its projection (`devkit`), any runtime starter code
11
+ (the Next.js + A2A starter of 398 §10.1 is a later template), any deployment name.
File without changes
@@ -0,0 +1,33 @@
1
+ name: ci
2
+
3
+ # Product CI (spec 399 §3.6): typecheck + tests + `ap doctor` (the doctrine gates as CLIs) + `ap doctor --rules`
4
+ # (drift between the projected rules and the pinned source). Conformance of the SHADOW deployment runs in the
5
+ # nightly beside the live gates, not here.
6
+ on:
7
+ push:
8
+ branches: [main, master]
9
+ pull_request:
10
+
11
+ jobs:
12
+ check:
13
+ runs-on: ubuntu-latest
14
+ timeout-minutes: 20
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: pnpm/action-setup@v4
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: 24
21
+ cache: pnpm
22
+ - run: pnpm install --frozen-lockfile
23
+ - run: pnpm typecheck
24
+ - run: pnpm test
25
+ - name: ap doctor
26
+ run: pnpm exec ap doctor --json > doctor-report.json || (cat doctor-report.json; exit 1)
27
+ - name: ap doctor --rules (projection drift)
28
+ run: pnpm exec ap doctor --rules
29
+ - uses: actions/upload-artifact@v4
30
+ if: always()
31
+ with:
32
+ name: doctor-report
33
+ path: doctor-report.json
@@ -0,0 +1,46 @@
1
+ name: live-gates-nightly
2
+
3
+ # Spec 392 / spec 399 §5.4: the product's live gates, nightly, against its SHADOW deployment during the parallel
4
+ # run and against the live environment after the cut. The runner is @agenticprimitives/evaluation's
5
+ # (`ap test --live-gates`); the gates are DATA in live-gates.json. Artifact-only: the report is uploaded, the run
6
+ # is red when a `required` gate fails. Conformance of the same deployment runs beside it.
7
+ on:
8
+ schedule:
9
+ - cron: '17 6 * * *'
10
+ workflow_dispatch:
11
+ inputs:
12
+ home:
13
+ description: 'HOME_URL to run against (defaults to live-gates.json#home)'
14
+ required: false
15
+
16
+ jobs:
17
+ gates:
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 90
20
+ env:
21
+ HOME_URL: ${{ github.event.inputs.home }}
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: pnpm/action-setup@v4
25
+ - uses: actions/setup-node@v4
26
+ with:
27
+ node-version: 24
28
+ cache: pnpm
29
+ - run: pnpm install --frozen-lockfile
30
+ - name: live gates
31
+ run: pnpm exec ap test --live-gates live-gates.json --json > live-gates-report.json || (cat live-gates-report.json; exit 1)
32
+ - name: A2A conformance of the deployment
33
+ if: env.A2A_URL != ''
34
+ env:
35
+ A2A_URL: ${{ vars.A2A_URL }}
36
+ run: pnpm exec ap conform a2a "$A2A_URL"
37
+ - name: MCP conformance of the deployment
38
+ if: env.MCP_URL != ''
39
+ env:
40
+ MCP_URL: ${{ vars.MCP_URL }}
41
+ run: pnpm exec ap conform mcp "$MCP_URL"
42
+ - uses: actions/upload-artifact@v4
43
+ if: always()
44
+ with:
45
+ name: live-gates-report
46
+ path: live-gates-report.json
@@ -0,0 +1,16 @@
1
+ # {{name}} — agent instructions
2
+
3
+ Binding rules for every AI coding assistant working in this repository. The rules below are PROJECTED from the
4
+ pinned source (`agentic.lock.json#rules`) by `ap doctor --rules --write`; do not edit the managed block, and do not
5
+ restate a rule in your own words (ADR-0063 §8).
6
+
7
+ ## Start here
8
+
9
+ 1. `CLAUDE.md` — the repository guide.
10
+ 2. `DEPLOYER.md` — which repository deploys which environment; never deploy a live env this repo does not own.
11
+ 3. `agentic.lock.json` — the coherent `@agenticprimitives/*` set; change it only through `ap upgrade`.
12
+
13
+ ## Always-on rules
14
+
15
+ <!-- ap:rules -->
16
+ <!-- /ap:rules -->
@@ -0,0 +1,25 @@
1
+ # {{name}} — Claude guide
2
+
3
+ A product repository on published `@agenticprimitives/*` packages (ADR-0063; spec 399). Generated from the
4
+ `product-repo` template ({{templateRevision}}). This repo owns its apps, runtime, ops scripts, live gates, product
5
+ specs and white-label config; Ring 0 owns the packages and the doctrine.
6
+
7
+ ## Hard rules (this repository)
8
+
9
+ - **Exact pins, one coherent set.** Every `@agenticprimitives/*` dependency is an exact published version from
10
+ `agentic.lock.json#packages`; move them only with `ap upgrade --canary | --pin`. Never a workspace alias, never a fork.
11
+ - **Doctrine is projected, never restated.** The managed block below and `.cursor/rules/*.mdc` are generated
12
+ from the pinned source; `ap doctor` (`rules-drift`) fails on any edit.
13
+ - **No new app-resident primitive.** Anything a second product would need is a package API in Ring 0 (spec 399 §4).
14
+ - **Shadow first.** This repo deploys `<env>-split` during the parallel run; a live env changes hands only in the
15
+ announced cut PR (`DEPLOYER.md`). Worker names, DO bindings and migration tags never change.
16
+ - **Web → A2A, never MCP** (ADR-0044); **the vault is the record** (ADR-0055); **no silent fallbacks** (ADR-0013).
17
+
18
+ ## Validate
19
+
20
+ `pnpm check` (typecheck + tests + `ap doctor`) · `pnpm doctor:rules` · `pnpm live-gates` (needs `HOME_URL`).
21
+
22
+ ## Binding rules (projected)
23
+
24
+ <!-- ap:rules -->
25
+ <!-- /ap:rules -->
@@ -0,0 +1,14 @@
1
+ # DEPLOYER — who deploys what (spec 399 §5.5 / §10)
2
+
3
+ Two deployers must never both believe they own a live environment. This file names, per app and per
4
+ environment, which repository is the deployer of record. Until an app's announced cut PR, Ring 0
5
+ (`agenticprimitives`) deploys the LIVE environments and this repository deploys only its SHADOW environments.
6
+
7
+ | App | Environment | Deployer of record | Since | Notes |
8
+ | --- | --- | --- | --- | --- |
9
+ | `apps/<app>` | `env-a-split` (shadow) | {{name}} | {{templateRevision}} | fresh DOs, own secrets, own hostnames |
10
+ | `apps/<app>` | `env-a` (live) | agenticprimitives (Ring 0) | — | flips here at the cut PR, same Worker name |
11
+ | `apps/<app>` | `env-b` (live) | agenticprimitives (Ring 0) | — | idem |
12
+
13
+ Rules: a row flips only in the cut PR, with the seven green shadow nights attached; a flipped row is reversible by
14
+ reverting that PR for the seven nights after; the shadow env keeps deploying meanwhile.
@@ -0,0 +1,40 @@
1
+ # {{name}}
2
+
3
+ A product repository on published `@agenticprimitives/*` packages, generated from the Developer Kit's
4
+ `product-repo` template (spec 399 §3.6, revision {{templateRevision}}) by `@agenticprimitives/create-app`
5
+ {{devkitVersion}}. Ring 0 (`agenticprimitives`) keeps the packages, the contracts and the kit; this repository
6
+ owns its UX, its runtime (Workers, Durable Objects, bindings, wrangler configs, secrets), its ops scripts, its
7
+ live gates, its product specs and its white-label config (ADR-0063 §2).
8
+
9
+ ## Layout
10
+
11
+ | Path | What lives there |
12
+ | --- | --- |
13
+ | `apps/*` | the product's deployables — each with its own `wrangler.toml` (see `wrangler.example.toml` for the env layout) |
14
+ | `examples/*` | relying-app demonstrations of the product's ceremonies; each builds against published packages or is retired |
15
+ | `scripts/` | ops scripts that operate THIS product's deployments (`set-cloudflare-secrets.sh`, provisioning, verify scripts) |
16
+ | `live-gates.json` | the live-gates ledger (spec 392 shape) the nightly runs through `ap test --live-gates` |
17
+ | `agentic.lock.json` | the coherent `@agenticprimitives/*` set, the rules-source digests, the doctor config |
18
+ | `AGENTS.md`, `CLAUDE.md`, `.cursor/rules/` | projected from the pinned rules source — regenerate with `ap doctor --rules --write`, never edit the managed block |
19
+ | `DEPLOYER.md` | which repository deploys which Worker, and in which environment — one line per app |
20
+
21
+ ## Commands
22
+
23
+ ```
24
+ pnpm install
25
+ pnpm doctor # ap doctor — the doctrine rules over this tree
26
+ pnpm doctor:rules # drift between the projected rules and the pinned source
27
+ pnpm upgrade:canary # newest canary of every pin, one coherent set, then doctor
28
+ pnpm upgrade:pin 1.0.0-alpha.24 # or one named version / dist-tag
29
+ pnpm live-gates # the ledger against HOME_URL (nightly in CI)
30
+ pnpm conform:a2a https://… # A2A 1.0 conformance of a deployment
31
+ pnpm conform:mcp https://… # MCP conformance of a deployment
32
+ ```
33
+
34
+ ## Rules that bind every change
35
+
36
+ - Every `@agenticprimitives/*` dependency is an exact published version; the set is coherent (`lock-coherent`).
37
+ - Doctrine is projected, never restated: `AGENTS.md` / `CLAUDE.md` managed blocks and `.cursor/rules/*.mdc` come
38
+ from the pinned source by digest (`rules-drift`). A product repo may not paraphrase a rule.
39
+ - A shadow environment (`<env>-split`) is where this repo deploys during a parallel run; the live environment
40
+ changes hands only at the announced cut (spec 399 §5.3). Worker names, DO bindings and migration tags never change.
@@ -0,0 +1,5 @@
1
+ # apps/
2
+
3
+ One directory per deployable. Copied in from Ring 0 with history (`git filter-repo` on a CLONE, never on origin),
4
+ or created new. Each carries its own `wrangler.toml` on the layout in `../wrangler.example.toml`, its `.secrets.<env>`
5
+ (gitignored), and imports `@agenticprimitives/*` only at the exact versions in `../agentic.lock.json`.
@@ -0,0 +1,12 @@
1
+ # MOVED
2
+
3
+ <!-- The text the CUT PR drops into Ring 0 at `apps/<app>/MOVED.md` when this app leaves agenticprimitives
4
+ (spec 399 §5.1 / §5.6). Fill the placeholders; keep it to these lines. -->
5
+
6
+ This app now lives in **{{name}}** (`<repository url>`), extracted with history from agenticprimitives at commit
7
+ `<ring-0 commit>` into `<product commit>` on `<date>`.
8
+
9
+ - Deployer of record: {{name}} (see its `DEPLOYER.md`). Worker names, DO bindings and migration tags are unchanged.
10
+ - Product specs: copied to `{{name}}/specs/`; the Ring-0 copies are pointers listed in `specs/INDEX.md`.
11
+ - Ops scripts: `{{name}}/scripts/`.
12
+ - Reversible by reverting the cut PR for seven nights after `<date>`.
@@ -0,0 +1,4 @@
1
+ # examples/
2
+
3
+ Relying-app demonstrations of this product's ceremonies (spec 399 §2.1). Each example builds against the published
4
+ packages or is retired; none ships from Ring 0.
@@ -0,0 +1,5 @@
1
+ {
2
+ "$comment": "The live-gates ledger (spec 392 shape): every verify script with the authority twin it carries, run nightly by `ap test --live-gates live-gates.json` through @agenticprimitives/evaluation's runner against HOME_URL. `required` gates fail the run; the rest report; `paced` gates are spaced for a metered model plan. Add a gate = one entry.",
3
+ "home": "https://<shadow-home>",
4
+ "gates": []
5
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "{{name}}",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "description": "{{name}} — a product repository on published @agenticprimitives/* packages (ADR-0063). Generated by @agenticprimitives/create-app {{devkitVersion}}, template product-repo {{templateRevision}}.",
6
+ "type": "module",
7
+ "engines": { "node": ">=22.18", "pnpm": ">=9" },
8
+ "scripts": {
9
+ "doctor": "ap doctor",
10
+ "doctor:rules": "ap doctor --rules",
11
+ "test": "pnpm -r test",
12
+ "typecheck": "pnpm -r typecheck",
13
+ "build": "pnpm -r build",
14
+ "check": "pnpm typecheck && pnpm test && ap doctor",
15
+ "live-gates": "ap test --live-gates live-gates.json",
16
+ "conform:a2a": "ap conform a2a",
17
+ "conform:mcp": "ap conform mcp",
18
+ "upgrade:canary": "ap upgrade --canary",
19
+ "upgrade:pin": "ap upgrade --pin"
20
+ },
21
+ "devDependencies": {
22
+ "@agenticprimitives/a2a": "{{pin}}",
23
+ "@agenticprimitives/devkit": "{{pin}}",
24
+ "@agenticprimitives/evaluation": "{{pin}}",
25
+ "@agenticprimitives/mcp-protocol": "{{pin}}",
26
+ "typescript": "^5.7.3",
27
+ "vitest": "^4.1.8"
28
+ }
29
+ }
@@ -0,0 +1,6 @@
1
+ # A product repository: its apps (Workers, Next.js, DOs), its ops scripts, and the examples that demonstrate its
2
+ # ceremonies. Every @agenticprimitives/* import is a published EXACT version (agentic.lock.json#packages) —
3
+ # never a workspace alias, never a fork (ADR-0037 / ADR-0063 §2). `ap doctor` (lock-coherent) refuses otherwise.
4
+ packages:
5
+ - 'apps/*'
6
+ - 'examples/*'
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ # set-cloudflare-secrets.sh — set each app's Worker secrets for ONE environment from the operator's shell.
3
+ #
4
+ # ./scripts/set-cloudflare-secrets.sh <env> apps/<app> # e.g. env-a-split
5
+ #
6
+ # Reads NAME=value pairs from `apps/<app>/.secrets.<env>` (gitignored; never committed) and pushes each with
7
+ # `wrangler secret put --env <env>`. Values never echo. The live envs are set only by the deployer of record
8
+ # (DEPLOYER.md); during the parallel run that is the shadow env only.
9
+ set -euo pipefail
10
+ ENV_NAME="${1:?usage: set-cloudflare-secrets.sh <env> <app-dir>}"
11
+ APP_DIR="${2:?usage: set-cloudflare-secrets.sh <env> <app-dir>}"
12
+ FILE="$APP_DIR/.secrets.$ENV_NAME"
13
+ [ -f "$FILE" ] || { echo "no $FILE — nothing to set" >&2; exit 2; }
14
+ while IFS='=' read -r name value; do
15
+ [ -z "$name" ] && continue
16
+ case "$name" in \#*) continue ;; esac
17
+ printf '%s' "$value" | (cd "$APP_DIR" && npx wrangler secret put "$name" --env "$ENV_NAME") >/dev/null
18
+ echo "set $name for $ENV_NAME ($APP_DIR)"
19
+ done < "$FILE"
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "lib": ["ES2022", "DOM"],
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "resolveJsonModule": true,
12
+ "isolatedModules": true,
13
+ "declaration": true,
14
+ "noUncheckedIndexedAccess": true,
15
+ "noImplicitOverride": true,
16
+ "useUnknownInCatchVariables": true
17
+ }
18
+ }
@@ -0,0 +1,40 @@
1
+ # The env layout every app in this repository follows (spec 399 §5.3). Copy into apps/<app>/wrangler.toml.
2
+ #
3
+ # [env.env-a] a LIVE environment Ring 0 deploys until the cut — names, bindings, DO classes and migration
4
+ # [env.env-b] tags are copied VERBATIM from the Ring-0 config and never renamed (a rename orphans DO storage)
5
+ # [env.env-a-split] the SHADOW environment this repository deploys during the parallel run: fresh DOs, its own
6
+ # secrets, its own hostnames; nightly live gates run against it until seven nights are green
7
+ #
8
+ # Secrets are never in this file: scripts/set-cloudflare-secrets.sh sets them per env from the operator's shell.
9
+ name = "<worker-name>"
10
+ main = "src/index.ts"
11
+ compatibility_date = "2026-09-01"
12
+
13
+ [vars]
14
+ ALLOWED_ORIGINS = ""
15
+
16
+ [env.env-a]
17
+ name = "<worker-name>"
18
+ routes = [{ pattern = "<live-host-a>/*", custom_domain = true }]
19
+ [env.env-a.vars]
20
+ ALLOWED_ORIGINS = ""
21
+
22
+ [env.env-b]
23
+ name = "<worker-name>-b"
24
+ routes = [{ pattern = "<live-host-b>/*", custom_domain = true }]
25
+ [env.env-b.vars]
26
+ ALLOWED_ORIGINS = ""
27
+
28
+ [env.env-a-split]
29
+ name = "<worker-name>-split"
30
+ routes = [{ pattern = "<shadow-host>/*", custom_domain = true }]
31
+ [env.env-a-split.vars]
32
+ ALLOWED_ORIGINS = ""
33
+
34
+ # Durable Objects: the SAME class names and migration tags as the live config — copied, never edited.
35
+ # [[durable_objects.bindings]]
36
+ # name = "<BINDING>"
37
+ # class_name = "<ClassName>"
38
+ # [[migrations]]
39
+ # tag = "<tag-as-in-ring-0>"
40
+ # new_sqlite_classes = ["<ClassName>"]