@agenticprimitives/devkit 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.
Files changed (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/bin/ap.mjs +119 -0
  4. package/dist/config.d.ts +130 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/config.js +128 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/dispatch.d.ts +44 -0
  9. package/dist/dispatch.d.ts.map +1 -0
  10. package/dist/dispatch.js +43 -0
  11. package/dist/dispatch.js.map +1 -0
  12. package/dist/doctor.d.ts +21 -0
  13. package/dist/doctor.d.ts.map +1 -0
  14. package/dist/doctor.js +71 -0
  15. package/dist/doctor.js.map +1 -0
  16. package/dist/errors.d.ts +37 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +35 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/fs.d.ts +20 -0
  21. package/dist/fs.d.ts.map +1 -0
  22. package/dist/fs.js +54 -0
  23. package/dist/fs.js.map +1 -0
  24. package/dist/index.d.ts +24 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +19 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/lock.d.ts +18 -0
  29. package/dist/lock.d.ts.map +1 -0
  30. package/dist/lock.js +15 -0
  31. package/dist/lock.js.map +1 -0
  32. package/dist/redact.d.ts +2 -0
  33. package/dist/redact.d.ts.map +1 -0
  34. package/dist/redact.js +14 -0
  35. package/dist/redact.js.map +1 -0
  36. package/dist/rules/archetype-catalog.d.ts +4 -0
  37. package/dist/rules/archetype-catalog.d.ts.map +1 -0
  38. package/dist/rules/archetype-catalog.js +48 -0
  39. package/dist/rules/archetype-catalog.js.map +1 -0
  40. package/dist/rules/capability-vocabulary.d.ts +4 -0
  41. package/dist/rules/capability-vocabulary.d.ts.map +1 -0
  42. package/dist/rules/capability-vocabulary.js +56 -0
  43. package/dist/rules/capability-vocabulary.js.map +1 -0
  44. package/dist/rules/custodian-coverage.d.ts +4 -0
  45. package/dist/rules/custodian-coverage.d.ts.map +1 -0
  46. package/dist/rules/custodian-coverage.js +47 -0
  47. package/dist/rules/custodian-coverage.js.map +1 -0
  48. package/dist/rules/demo-person-org-distinct.d.ts +4 -0
  49. package/dist/rules/demo-person-org-distinct.d.ts.map +1 -0
  50. package/dist/rules/demo-person-org-distinct.js +26 -0
  51. package/dist/rules/demo-person-org-distinct.js.map +1 -0
  52. package/dist/rules/fail-open-knobs.d.ts +4 -0
  53. package/dist/rules/fail-open-knobs.d.ts.map +1 -0
  54. package/dist/rules/fail-open-knobs.js +64 -0
  55. package/dist/rules/fail-open-knobs.js.map +1 -0
  56. package/dist/rules/index.d.ts +10 -0
  57. package/dist/rules/index.d.ts.map +1 -0
  58. package/dist/rules/index.js +29 -0
  59. package/dist/rules/index.js.map +1 -0
  60. package/dist/rules/internal-marker-split.d.ts +4 -0
  61. package/dist/rules/internal-marker-split.d.ts.map +1 -0
  62. package/dist/rules/internal-marker-split.js +31 -0
  63. package/dist/rules/internal-marker-split.js.map +1 -0
  64. package/dist/rules/lock-coherent.d.ts +4 -0
  65. package/dist/rules/lock-coherent.d.ts.map +1 -0
  66. package/dist/rules/lock-coherent.js +39 -0
  67. package/dist/rules/lock-coherent.js.map +1 -0
  68. package/dist/rules/no-cross-subject-vault-reads.d.ts +4 -0
  69. package/dist/rules/no-cross-subject-vault-reads.d.ts.map +1 -0
  70. package/dist/rules/no-cross-subject-vault-reads.js +35 -0
  71. package/dist/rules/no-cross-subject-vault-reads.js.map +1 -0
  72. package/dist/rules/no-hmac-home-bridge.d.ts +4 -0
  73. package/dist/rules/no-hmac-home-bridge.d.ts.map +1 -0
  74. package/dist/rules/no-hmac-home-bridge.js +40 -0
  75. package/dist/rules/no-hmac-home-bridge.js.map +1 -0
  76. package/dist/rules/no-private-keys.d.ts +4 -0
  77. package/dist/rules/no-private-keys.d.ts.map +1 -0
  78. package/dist/rules/no-private-keys.js +45 -0
  79. package/dist/rules/no-private-keys.js.map +1 -0
  80. package/dist/rules/rules-drift.d.ts +4 -0
  81. package/dist/rules/rules-drift.d.ts.map +1 -0
  82. package/dist/rules/rules-drift.js +46 -0
  83. package/dist/rules/rules-drift.js.map +1 -0
  84. package/dist/rules/types.d.ts +50 -0
  85. package/dist/rules/types.d.ts.map +1 -0
  86. package/dist/rules/types.js +2 -0
  87. package/dist/rules/types.js.map +1 -0
  88. package/dist/rules/web-no-direct-mcp.d.ts +4 -0
  89. package/dist/rules/web-no-direct-mcp.d.ts.map +1 -0
  90. package/dist/rules/web-no-direct-mcp.js +37 -0
  91. package/dist/rules/web-no-direct-mcp.js.map +1 -0
  92. package/dist/rules-projection.d.ts +58 -0
  93. package/dist/rules-projection.d.ts.map +1 -0
  94. package/dist/rules-projection.js +135 -0
  95. package/dist/rules-projection.js.map +1 -0
  96. package/dist/upgrade.d.ts +37 -0
  97. package/dist/upgrade.d.ts.map +1 -0
  98. package/dist/upgrade.js +116 -0
  99. package/dist/upgrade.js.map +1 -0
  100. package/dist/workspace.d.ts +18 -0
  101. package/dist/workspace.d.ts.map +1 -0
  102. package/dist/workspace.js +56 -0
  103. package/dist/workspace.js.map +1 -0
  104. package/package.json +73 -0
  105. package/rules/coordination-vs-orchestration.md +31 -0
  106. package/rules/demo-person-org-distinct.md +40 -0
  107. package/rules/external-registry-integrations.md +15 -0
  108. package/rules/hard-rules.md +50 -0
  109. package/rules/one-capability-model-generates-both.md +82 -0
  110. package/rules/ontology-drives-behavior.md +58 -0
  111. package/rules/service-agent-signing.md +84 -0
  112. package/rules/sidecar.json +13 -0
  113. package/rules/skill-terminology.md +76 -0
  114. package/rules/vault-and-ontology.md +8 -0
  115. package/rules/vault-records-are-ontology-shaped.md +85 -0
  116. package/spec.md +11 -0
@@ -0,0 +1,37 @@
1
+ import { isCommentLine } from '../fs.js';
2
+ const FORBIDDEN = [
3
+ { re: /(?<!\/a2a)\/mcp\/native/, what: 'native MCP tool ingress (/mcp/native) — go through /a2a/*' },
4
+ { re: /(?<!\/a2a)\/mcp(["'`])/, what: 'OAuth MCP tool ingress (POST /mcp) — go through /a2a/*' },
5
+ { re: /(?<!\/a2a)\/tools\//, what: 'raw MCP tool path (/tools/...) — go through /a2a/tools/... instead' },
6
+ ];
7
+ const SKIP = new Set(['dist', 'node_modules', 'coverage', 'test', 'tests', '__tests__', '.next']);
8
+ export const webNoDirectMcp = {
9
+ id: 'web-no-direct-mcp',
10
+ spec: 'ADR-0044',
11
+ twin: 'check:no-direct-mcp-in-web',
12
+ describe: 'browser apps reach MCP data only via the same-origin /a2a/* surface',
13
+ run(ctx, cfg) {
14
+ const findings = [];
15
+ let scanned = 0;
16
+ for (const app of cfg.browserApps) {
17
+ const src = `${app}/src`;
18
+ if (!ctx.exists(src))
19
+ continue;
20
+ for (const file of ctx.walk(src, { skipDirs: SKIP, file: (n) => /\.(ts|tsx)$/.test(n) && !n.endsWith('.d.ts') })) {
21
+ const text = ctx.read(ctx.rel(file));
22
+ if (cfg.allowMarkers.some((m) => text.includes(m)))
23
+ continue;
24
+ scanned += 1;
25
+ text.split('\n').forEach((line, i) => {
26
+ if (isCommentLine(line))
27
+ return;
28
+ for (const { re, what } of FORBIDDEN)
29
+ if (re.test(line))
30
+ findings.push({ file: ctx.rel(file), line: i + 1, message: what, tag: 'direct-mcp' });
31
+ });
32
+ }
33
+ }
34
+ return { summary: findings.length ? `${findings.length} direct-MCP reference(s) in browser code` : `${scanned} browser files reach MCP only via /a2a/*`, findings };
35
+ },
36
+ };
37
+ //# sourceMappingURL=web-no-direct-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-no-direct-mcp.js","sourceRoot":"","sources":["../../src/rules/web-no-direct-mcp.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAgD;IAC7D,EAAE,EAAE,EAAE,yBAAyB,EAAE,IAAI,EAAE,2DAA2D,EAAE;IACpG,EAAE,EAAE,EAAE,wBAAwB,EAAE,IAAI,EAAE,wDAAwD,EAAE;IAChG,EAAE,EAAE,EAAE,qBAAqB,EAAE,IAAI,EAAE,oEAAoE,EAAE;CAC1G,CAAC;AACF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAElG,MAAM,CAAC,MAAM,cAAc,GAA+C;IACxE,EAAE,EAAE,mBAAmB;IACvB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,4BAA4B;IAClC,QAAQ,EAAE,qEAAqE;IAC/E,GAAG,CAAC,GAAG,EAAE,GAAG;QACV,MAAM,QAAQ,GAAkB,EAAE,CAAC;QACnC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC/B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrC,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBAAE,SAAS;gBAC7D,OAAO,IAAI,CAAC,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;oBACnC,IAAI,aAAa,CAAC,IAAI,CAAC;wBAAE,OAAO;oBAChC,KAAK,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,SAAS;wBAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC,CAAC;gBACjJ,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,0CAA0C,CAAC,CAAC,CAAC,GAAG,OAAO,0CAA0C,EAAE,QAAQ,EAAE,CAAC;IACtK,CAAC;CACF,CAAC"}
@@ -0,0 +1,58 @@
1
+ export interface RuleSidecarEntry {
2
+ description: string;
3
+ globs?: string[];
4
+ alwaysApply?: boolean;
5
+ /** Project to `.cursor/rules/<name>.mdc`. Default false: a rule without a Cursor mirror today stays without one. */
6
+ cursor?: boolean;
7
+ }
8
+ export type RulesSidecar = Record<string, RuleSidecarEntry>;
9
+ export interface RuleSource {
10
+ name: string;
11
+ body: string;
12
+ digest: string;
13
+ }
14
+ export interface RulesCorpus {
15
+ sourceDir: string;
16
+ rules: RuleSource[];
17
+ sidecar: RulesSidecar;
18
+ }
19
+ /** The corpus bundled with this package: copies of the Ring-0 agent-rules, synced at build (`scripts/sync-rules.mjs`). */
20
+ export declare const BUNDLED_RULES_DIR: string;
21
+ export declare function ruleDigest(body: string): string;
22
+ /** The hard-rules block of a root guide, as one rule body — the second source id (399 §3.4). */
23
+ export declare function extractHardRules(guideText: string): string | null;
24
+ export declare function loadRulesCorpus(opts: {
25
+ root: string;
26
+ source?: string;
27
+ sidecar?: string;
28
+ hardRulesFrom?: string;
29
+ }): RulesCorpus;
30
+ export declare function rulesLockEntries(corpus: RulesCorpus): Record<string, string>;
31
+ /** The Cursor rule file: frontmatter from the sidecar, blank line, body verbatim. */
32
+ export declare function renderMdc(entry: RuleSidecarEntry, body: string): string;
33
+ export declare const RULES_BLOCK_START = "<!-- ap:rules -->";
34
+ export declare const RULES_BLOCK_END = "<!-- /ap:rules -->";
35
+ /** The managed block for AGENTS.md / CLAUDE.md: the table of rules with their digests. */
36
+ export declare function renderRulesBlock(corpus: RulesCorpus, opts: {
37
+ sourceLabel: string;
38
+ }): string;
39
+ export declare function replaceRulesBlock(text: string, block: string): string | null;
40
+ export interface ProjectionResult {
41
+ path: string;
42
+ status: 'unchanged' | 'would-write' | 'written' | 'unmanaged' | 'absent' | 'skipped';
43
+ reason?: string;
44
+ }
45
+ export interface ProjectOptions {
46
+ root: string;
47
+ corpus: RulesCorpus;
48
+ cursorRules?: string;
49
+ agentsMd?: string;
50
+ claudeMd?: string;
51
+ write: boolean;
52
+ /** Project every rule to Cursor, not only those the sidecar marks `cursor: true`. */
53
+ all?: boolean;
54
+ /** Create `.cursor/rules` when it does not exist (a fresh product repo). Default: only project into an existing dir. */
55
+ createCursorDir?: boolean;
56
+ }
57
+ export declare function projectRules(o: ProjectOptions): ProjectionResult[];
58
+ //# sourceMappingURL=rules-projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules-projection.d.ts","sourceRoot":"","sources":["../src/rules-projection.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oHAAoH;IACpH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AACD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAE5D,MAAM,WAAW,UAAU;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC1E,MAAM,WAAW,WAAW;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE;AAE9F,0HAA0H;AAC1H,eAAO,MAAM,iBAAiB,QAA+D,CAAC;AAE9F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGjE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAkB9H;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE5E;AAED,qFAAqF;AACrF,wBAAgB,SAAS,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,eAAe,uBAAuB,CAAC;AAEpD,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgB3F;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK5E;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,qFAAqF;IACrF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,wHAAwH;IACxH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,cAAc,GAAG,gBAAgB,EAAE,CA+BlE"}
@@ -0,0 +1,135 @@
1
+ // RULES PROJECTION — spec 399 §3.4 / spec 398 §10.5 / ADR-0063 §8. ONE source (the agent-rules corpus: a directory
2
+ // of `<name>.md`, optionally plus the hard-rules block of a root CLAUDE.md), projected to three targets:
3
+ //
4
+ // .cursor/rules/<name>.mdc frontmatter from the SIDECAR (description · globs · alwaysApply) + a blank line + the
5
+ // body byte-for-byte — regenerating a repo's existing files is a no-op (the §3.4 gate)
6
+ // AGENTS.md / CLAUDE.md ONLY the block between `<!-- ap:rules -->` and `<!-- /ap:rules -->`; a file without
7
+ // the markers is UNMANAGED and never rewritten (Ring 0's own CLAUDE.md is hand-written)
8
+ //
9
+ // A product repo may not restate a rule in its own words: it carries the projection and the digest.
10
+ import { createHash } from 'node:crypto';
11
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
12
+ import { dirname, join } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ /** The corpus bundled with this package: copies of the Ring-0 agent-rules, synced at build (`scripts/sync-rules.mjs`). */
15
+ export const BUNDLED_RULES_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'rules');
16
+ export function ruleDigest(body) {
17
+ return `sha256:${createHash('sha256').update(body.replace(/\r\n/g, '\n')).digest('hex')}`;
18
+ }
19
+ /** The hard-rules block of a root guide, as one rule body — the second source id (399 §3.4). */
20
+ export function extractHardRules(guideText) {
21
+ const m = /^## Hard rules\n([\s\S]*?)(?=^## )/m.exec(guideText);
22
+ return m ? `# Hard rules (root CLAUDE.md)\n\n${m[1].trim()}\n` : null;
23
+ }
24
+ export function loadRulesCorpus(opts) {
25
+ const sourceDir = opts.source ? join(opts.root, opts.source) : BUNDLED_RULES_DIR;
26
+ const rules = [];
27
+ if (existsSync(sourceDir)) {
28
+ for (const f of readdirSync(sourceDir).sort()) {
29
+ if (!f.endsWith('.md') || f === 'README.md')
30
+ continue;
31
+ const body = readFileSync(join(sourceDir, f), 'utf8');
32
+ rules.push({ name: f.slice(0, -3), body, digest: ruleDigest(body) });
33
+ }
34
+ }
35
+ // Ring 0: the hard rules live in the root guide, not in the corpus dir; the bundled copy already carries them.
36
+ if (opts.source && opts.hardRulesFrom && existsSync(join(opts.root, opts.hardRulesFrom)) && !rules.some((r) => r.name === 'hard-rules')) {
37
+ const body = extractHardRules(readFileSync(join(opts.root, opts.hardRulesFrom), 'utf8'));
38
+ if (body)
39
+ rules.push({ name: 'hard-rules', body, digest: ruleDigest(body) });
40
+ }
41
+ const sidecarPath = opts.sidecar ? join(opts.root, opts.sidecar) : existsSync(join(sourceDir, 'sidecar.json')) ? join(sourceDir, 'sidecar.json') : join(BUNDLED_RULES_DIR, 'sidecar.json');
42
+ const sidecar = existsSync(sidecarPath) ? JSON.parse(readFileSync(sidecarPath, 'utf8')) : {};
43
+ return { sourceDir, rules, sidecar };
44
+ }
45
+ export function rulesLockEntries(corpus) {
46
+ return Object.fromEntries(corpus.rules.map((r) => [r.name, r.digest]));
47
+ }
48
+ /** The Cursor rule file: frontmatter from the sidecar, blank line, body verbatim. */
49
+ export function renderMdc(entry, body) {
50
+ const fm = [`description: ${entry.description}`];
51
+ if (entry.globs?.length)
52
+ fm.push('globs:', ...entry.globs.map((g) => ` - "${g}"`));
53
+ fm.push(`alwaysApply: ${entry.alwaysApply ?? true}`);
54
+ return `---\n${fm.join('\n')}\n---\n\n${body}`;
55
+ }
56
+ export const RULES_BLOCK_START = '<!-- ap:rules -->';
57
+ export const RULES_BLOCK_END = '<!-- /ap:rules -->';
58
+ /** The managed block for AGENTS.md / CLAUDE.md: the table of rules with their digests. */
59
+ export function renderRulesBlock(corpus, opts) {
60
+ const rows = corpus.rules.map((r) => {
61
+ const s = corpus.sidecar[r.name];
62
+ const cursor = s?.cursor ? ` · \`.cursor/rules/${r.name}.mdc\`` : '';
63
+ return `| ${s?.description ?? r.name} | \`${opts.sourceLabel}/${r.name}.md\`${cursor} | \`${r.digest.slice(0, 19)}…\` |`;
64
+ });
65
+ return [
66
+ RULES_BLOCK_START,
67
+ '<!-- Generated by `ap doctor --rules --write` from the pinned rules source; edit the source, never this block (ADR-0063 §8). -->',
68
+ '',
69
+ '| Rule | Source | Digest |',
70
+ '| --- | --- | --- |',
71
+ ...rows,
72
+ '',
73
+ RULES_BLOCK_END,
74
+ ].join('\n');
75
+ }
76
+ export function replaceRulesBlock(text, block) {
77
+ const a = text.indexOf(RULES_BLOCK_START);
78
+ const b = text.indexOf(RULES_BLOCK_END);
79
+ if (a === -1 || b === -1 || b < a)
80
+ return null;
81
+ return text.slice(0, a) + block + text.slice(b + RULES_BLOCK_END.length);
82
+ }
83
+ export function projectRules(o) {
84
+ const out = [];
85
+ const emit = (path, next) => {
86
+ const abs = join(o.root, path);
87
+ const current = existsSync(abs) ? readFileSync(abs, 'utf8') : null;
88
+ if (current === next) {
89
+ out.push({ path, status: 'unchanged' });
90
+ return;
91
+ }
92
+ if (!o.write) {
93
+ out.push({ path, status: 'would-write', reason: current === null ? 'missing' : 'content' });
94
+ return;
95
+ }
96
+ mkdirSync(dirname(abs), { recursive: true });
97
+ writeFileSync(abs, next);
98
+ out.push({ path, status: 'written' });
99
+ };
100
+ const cursorDir = o.cursorRules ?? '.cursor/rules';
101
+ const cursorExists = existsSync(join(o.root, cursorDir));
102
+ if (cursorExists || o.createCursorDir) {
103
+ for (const r of o.corpus.rules) {
104
+ const s = o.corpus.sidecar[r.name];
105
+ if (!s) {
106
+ out.push({ path: `${cursorDir}/${r.name}.mdc`, status: 'skipped', reason: 'no sidecar entry' });
107
+ continue;
108
+ }
109
+ if (!s.cursor && !o.all) {
110
+ out.push({ path: `${cursorDir}/${r.name}.mdc`, status: 'skipped', reason: 'sidecar: cursor=false' });
111
+ continue;
112
+ }
113
+ emit(`${cursorDir}/${r.name}.mdc`, renderMdc(s, r.body));
114
+ }
115
+ }
116
+ else
117
+ out.push({ path: cursorDir, status: 'absent' });
118
+ const sourceLabel = o.corpus.sourceDir.startsWith(o.root) ? o.corpus.sourceDir.slice(o.root.length + 1) : '@agenticprimitives/devkit/rules';
119
+ const block = renderRulesBlock(o.corpus, { sourceLabel });
120
+ for (const path of [o.agentsMd ?? 'AGENTS.md', o.claudeMd ?? 'CLAUDE.md']) {
121
+ const abs = join(o.root, path);
122
+ if (!existsSync(abs)) {
123
+ out.push({ path, status: 'absent' });
124
+ continue;
125
+ }
126
+ const next = replaceRulesBlock(readFileSync(abs, 'utf8'), block);
127
+ if (next === null) {
128
+ out.push({ path, status: 'unmanaged', reason: 'no <!-- ap:rules --> block' });
129
+ continue;
130
+ }
131
+ emit(path, next);
132
+ }
133
+ return out;
134
+ }
135
+ //# sourceMappingURL=rules-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules-projection.js","sourceRoot":"","sources":["../src/rules-projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export type UpgradeMode = 'canary' | 'pin';
2
+ export interface UpgradeChange {
3
+ manifest: string;
4
+ field: string;
5
+ dep: string;
6
+ from: string;
7
+ to: string;
8
+ }
9
+ export interface UpgradePlan {
10
+ mode: UpgradeMode;
11
+ /** The dist-tag or version asked for. */
12
+ target: string;
13
+ changes: UpgradeChange[];
14
+ /** dep → resolved version. */
15
+ resolved: Record<string, string>;
16
+ unresolved: string[];
17
+ /** Canary only: true when every resolved canary carries the same commit suffix. */
18
+ coherent: boolean;
19
+ notes: string[];
20
+ }
21
+ /** dist-tags for a package, as `npm view <pkg> dist-tags --json` returns them. */
22
+ export type DistTagResolver = (pkg: string) => Promise<Record<string, string>>;
23
+ export declare const npmDistTags: DistTagResolver;
24
+ export declare function planUpgrade(opts: {
25
+ root: string;
26
+ mode: UpgradeMode;
27
+ pin?: string;
28
+ scope?: string;
29
+ resolveDistTags?: DistTagResolver;
30
+ includeWorkspaceAliases?: boolean;
31
+ }): Promise<UpgradePlan>;
32
+ /** Apply a plan: rewrite the manifests and the lock's `packages` set. Returns the manifests touched. */
33
+ export declare function applyUpgradePlan(root: string, plan: UpgradePlan, opts?: {
34
+ devkitVersion?: string;
35
+ }): string[];
36
+ export declare function formatUpgradePlan(plan: UpgradePlan): string;
37
+ //# sourceMappingURL=upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC;AAC3C,MAAM,WAAW,aAAa;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE;AACzG,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,WAAW,CAAC;IAClB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mFAAmF;IACnF,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,kFAAkF;AAClF,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/E,eAAO,MAAM,WAAW,EAAE,eAOzB,CAAC;AAIF,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAAC,uBAAuB,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAwCrM;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,EAAE,CAoBjH;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAM3D"}
@@ -0,0 +1,116 @@
1
+ // `ap upgrade --canary | --pin <version|tag>` — spec 399 §3.1 / §5.2. Rewrites every @agenticprimitives/* dependency
2
+ // across the workspace manifests to ONE coherent exact set, then the caller installs, dedupes and runs doctor.
3
+ // Planning is pure over an injected resolver; applying writes manifests and the lock. Stopping for review when a
4
+ // contract's authority or effects change (398 §10.3) is NOT implemented in W0 — see CLAUDE.md, it is named there.
5
+ import { readFileSync, writeFileSync } from 'node:fs';
6
+ import { join } from 'node:path';
7
+ import { execFileSync } from 'node:child_process';
8
+ import { DevkitError, ERROR_CODES } from './errors.js';
9
+ import { readLock, writeLock } from './lock.js';
10
+ import { workspaceManifests } from './workspace.js';
11
+ export const npmDistTags = async (pkg) => {
12
+ try {
13
+ const out = execFileSync('npm', ['view', pkg, 'dist-tags', '--json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
14
+ return JSON.parse(out);
15
+ }
16
+ catch (e) {
17
+ throw new DevkitError(ERROR_CODES.E_RESOLVE, `npm view ${pkg} dist-tags failed: ${e.message.split('\n')[0]}`);
18
+ }
19
+ };
20
+ const EXACT = /^\d+\.\d+\.\d+(-[0-9A-Za-z.-]+)?$/;
21
+ export async function planUpgrade(opts) {
22
+ const scope = opts.scope ?? '@agenticprimitives/';
23
+ const target = opts.mode === 'canary' ? 'canary' : opts.pin ?? '';
24
+ if (opts.mode === 'pin' && !target)
25
+ throw new DevkitError(ERROR_CODES.E_USAGE, '--pin needs a version or a dist-tag (latest | alpha | canary | 1.2.3)');
26
+ const resolve = opts.resolveDistTags ?? npmDistTags;
27
+ const manifests = workspaceManifests(opts.root);
28
+ const deps = new Set();
29
+ for (const m of manifests)
30
+ for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
31
+ for (const [dep, spec] of Object.entries(m.json[field] ?? {})) {
32
+ if (!dep.startsWith(scope))
33
+ continue;
34
+ if (spec.startsWith('workspace:') && !opts.includeWorkspaceAliases)
35
+ continue;
36
+ deps.add(dep);
37
+ }
38
+ }
39
+ const resolved = {};
40
+ const unresolved = [];
41
+ const notes = [];
42
+ for (const dep of [...deps].sort()) {
43
+ if (opts.mode === 'pin' && EXACT.test(target)) {
44
+ resolved[dep] = target;
45
+ continue;
46
+ }
47
+ let tags;
48
+ try {
49
+ tags = await resolve(dep);
50
+ }
51
+ catch (e) {
52
+ unresolved.push(`${dep}: ${e.message}`);
53
+ continue;
54
+ }
55
+ const v = tags[target];
56
+ if (!v) {
57
+ unresolved.push(`${dep}: no "${target}" dist-tag (has ${Object.keys(tags).join(', ') || 'none'})`);
58
+ continue;
59
+ }
60
+ resolved[dep] = v;
61
+ }
62
+ const changes = [];
63
+ for (const m of manifests)
64
+ for (const field of ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']) {
65
+ for (const [dep, spec] of Object.entries(m.json[field] ?? {})) {
66
+ const to = resolved[dep];
67
+ if (!to || spec === to)
68
+ continue;
69
+ changes.push({ manifest: m.file, field, dep, from: spec, to });
70
+ }
71
+ }
72
+ let coherent = true;
73
+ if (opts.mode === 'canary') {
74
+ const shas = new Set(Object.values(resolved).map((v) => /-canary-([0-9a-f]+)$/.exec(v)?.[1] ?? v));
75
+ coherent = shas.size <= 1;
76
+ if (!coherent)
77
+ notes.push(`the newest canaries span ${shas.size} commits (a canary publishes only what changed) — the set is newest-per-package, review before trusting it as one commit`);
78
+ }
79
+ return { mode: opts.mode, target, changes, resolved, unresolved, coherent, notes };
80
+ }
81
+ /** Apply a plan: rewrite the manifests and the lock's `packages` set. Returns the manifests touched. */
82
+ export function applyUpgradePlan(root, plan, opts = {}) {
83
+ const touched = new Set();
84
+ const byManifest = new Map();
85
+ for (const c of plan.changes)
86
+ byManifest.set(c.manifest, [...(byManifest.get(c.manifest) ?? []), c]);
87
+ for (const [file, changes] of byManifest) {
88
+ const abs = join(root, file);
89
+ const json = JSON.parse(readFileSync(abs, 'utf8'));
90
+ for (const c of changes) {
91
+ const section = json[c.field];
92
+ if (section && section[c.dep] !== undefined)
93
+ section[c.dep] = c.to;
94
+ }
95
+ writeFileSync(abs, `${JSON.stringify(json, null, 2)}\n`);
96
+ touched.add(file);
97
+ }
98
+ const lock = readLock(root) ?? { lockVersion: 1, packages: {}, rules: {} };
99
+ lock.packages = { ...lock.packages, ...plan.resolved };
100
+ if (opts.devkitVersion)
101
+ lock.devkit = opts.devkitVersion;
102
+ writeLock(root, lock);
103
+ touched.add('agentic.lock.json');
104
+ return [...touched];
105
+ }
106
+ export function formatUpgradePlan(plan) {
107
+ const lines = [`ap upgrade --${plan.mode}${plan.mode === 'pin' ? ` ${plan.target}` : ''} · ${plan.changes.length} change(s), ${Object.keys(plan.resolved).length} package(s) resolved${plan.mode === 'canary' ? `, ${plan.coherent ? 'coherent' : 'NOT coherent'}` : ''}`];
108
+ for (const c of plan.changes)
109
+ lines.push(` ${c.manifest} ${c.field}.${c.dep}: ${c.from} → ${c.to}`);
110
+ for (const u of plan.unresolved)
111
+ lines.push(` ✗ unresolved ${u}`);
112
+ for (const n of plan.notes)
113
+ lines.push(` ⚠ ${n}`);
114
+ return lines.join('\n');
115
+ }
116
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface PackageManifest {
2
+ name?: string;
3
+ version?: string;
4
+ private?: boolean;
5
+ dependencies?: Record<string, string>;
6
+ devDependencies?: Record<string, string>;
7
+ peerDependencies?: Record<string, string>;
8
+ optionalDependencies?: Record<string, string>;
9
+ [k: string]: unknown;
10
+ }
11
+ export interface WorkspaceManifest {
12
+ file: string;
13
+ dir: string;
14
+ json: PackageManifest;
15
+ }
16
+ export declare function workspaceGlobs(root: string): string[];
17
+ export declare function workspaceManifests(root: string): WorkspaceManifest[];
18
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE;AAEvF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAerD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAoBpE"}
@@ -0,0 +1,56 @@
1
+ // Workspace manifest discovery — the root package.json plus every package.json a `pnpm-workspace.yaml` glob names.
2
+ // Deliberately small: the globs pnpm uses here are `dir/*` and literal dirs, and a full glob engine is not a
3
+ // dependency this package wants.
4
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { rel } from './fs.js';
7
+ export function workspaceGlobs(root) {
8
+ const p = join(root, 'pnpm-workspace.yaml');
9
+ if (!existsSync(p))
10
+ return [];
11
+ const out = [];
12
+ let inPackages = false;
13
+ for (const raw of readFileSync(p, 'utf8').split('\n')) {
14
+ const line = raw.replace(/#.*$/, '').trimEnd();
15
+ if (/^packages:\s*$/.test(line)) {
16
+ inPackages = true;
17
+ continue;
18
+ }
19
+ if (inPackages) {
20
+ const m = /^\s+-\s*['"]?([^'"]+?)['"]?\s*$/.exec(line);
21
+ if (m?.[1])
22
+ out.push(m[1]);
23
+ else if (line.trim() && !line.startsWith(' '))
24
+ inPackages = false;
25
+ }
26
+ }
27
+ return out;
28
+ }
29
+ export function workspaceManifests(root) {
30
+ const out = [];
31
+ const add = (dir) => {
32
+ const file = join(dir, 'package.json');
33
+ if (!existsSync(file))
34
+ return;
35
+ out.push({ file: rel(root, file) || 'package.json', dir, json: JSON.parse(readFileSync(file, 'utf8')) });
36
+ };
37
+ add(root);
38
+ for (const g of workspaceGlobs(root)) {
39
+ if (g.startsWith('!'))
40
+ continue;
41
+ if (g.endsWith('/*')) {
42
+ const base = join(root, g.slice(0, -2));
43
+ if (!existsSync(base))
44
+ continue;
45
+ for (const e of readdirSync(base).sort()) {
46
+ const d = join(base, e);
47
+ if (statSync(d).isDirectory() && e !== 'node_modules')
48
+ add(d);
49
+ }
50
+ }
51
+ else if (!g.includes('*'))
52
+ add(join(root, g));
53
+ }
54
+ return out;
55
+ }
56
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@agenticprimitives/devkit",
3
+ "version": "0.0.0-alpha.1",
4
+ "description": "The Developer Kit core (spec 398 §10 / spec 399 §3): `ap doctor` runs the doctrine gates as data + pure rules over any tree, `ap doctor --rules` projects one pinned rules source into AGENTS.md / CLAUDE.md / .cursor/rules by digest, `ap upgrade` rewrites every @agenticprimitives/* pin to one coherent exact set, and `ap conform` / `ap test` dispatch to the packages that own conformance and live gates.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
9
+ "directory": "packages/devkit"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "bin": {
15
+ "ap": "./bin/ap.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
+ "rules",
28
+ "spec.md",
29
+ "README.md"
30
+ ],
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "dependencies": {
35
+ "@agenticprimitives/capability-claims": "0.0.0-alpha.19"
36
+ },
37
+ "peerDependencies": {
38
+ "@agenticprimitives/a2a": "0.0.0-alpha.19",
39
+ "@agenticprimitives/evaluation": "0.0.0-alpha.1",
40
+ "@agenticprimitives/mcp-protocol": "0.0.0-alpha.1"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "@agenticprimitives/a2a": {
44
+ "optional": true
45
+ },
46
+ "@agenticprimitives/evaluation": {
47
+ "optional": true
48
+ },
49
+ "@agenticprimitives/mcp-protocol": {
50
+ "optional": true
51
+ }
52
+ },
53
+ "devDependencies": {
54
+ "vitest": "^4.1.8"
55
+ },
56
+ "keywords": [
57
+ "agentic",
58
+ "primitives",
59
+ "devkit",
60
+ "doctor",
61
+ "developer-kit",
62
+ "cli"
63
+ ],
64
+ "scripts": {
65
+ "sync-rules": "node scripts/sync-rules.mjs",
66
+ "build": "node scripts/sync-rules.mjs && rm -rf dist && tsc -p tsconfig.build.json",
67
+ "typecheck": "tsc -p tsconfig.json --noEmit",
68
+ "test": "vitest run",
69
+ "test:unit": "vitest run test/unit --passWithNoTests",
70
+ "test:watch": "vitest",
71
+ "clean": "rm -rf dist"
72
+ }
73
+ }
@@ -0,0 +1,31 @@
1
+ # Coordination vs orchestration (ADR-0044 + ADR-0054)
2
+
3
+ Two planning planes. Never collapse them. Full doc: `docs/architecture/coordination-vs-orchestration.md`.
4
+
5
+ ## One sentence
6
+
7
+ **Agentic coordination** schedules work **between agents** (durable Endeavor + shared CoordinationPlan, participants resolved through **discovery** at the **capability level**); **agent orchestration** sequences work **within one agent** (run-specific ExecutionPlan, informed by **Agent Skill packages / `SKILL.md`** and injected MCP tools).
8
+
9
+ ## Plane map
10
+
11
+ | | Coordination | Orchestration |
12
+ | --- | --- | --- |
13
+ | Scope | between agents, multi-principal | within one agent, one executor |
14
+ | Package | `@agenticprimitives/coordination` | `@agenticprimitives/orchestration` (+ `-anthropic` adapter) |
15
+ | Ontology | `apcoord:` | `apexec:` (+ `apguide:` playbooks) |
16
+ | Plan | `CoordinationPlan` — durable, versioned, adopted by decision | `ExecutionPlan` — one goal, one run |
17
+ | Actors | found via discovery: `agent-naming`, `registry-kit`, `apdisc:` capability matching | given: harness-activated `SKILL.md` packages + `ToolInvoker` tools |
18
+ | Needs stated as | `aps:Capability` requirement on a `PlanStep` | MCP tool invocation guided by a playbook |
19
+ | Binding act | signed `ContributionCommitment` against an exact plan revision hash | `p-plan:correspondsToStep` + qualified association |
20
+
21
+ ## Rules
22
+
23
+ 1. **Name the plane.** Bare "scheduling" is ambiguous: say **allocation** (between agents) or **step ordering** (within a run).
24
+ 2. **Discovery is coordination-plane only.** The orchestration core never imports/queries naming, registry, or `apdisc:` — tools and playbooks are injected through its ports.
25
+ 3. **Coordination speaks capabilities; orchestration speaks tools/playbooks.** MCP tool ids and `SKILL.md` content never appear in `apcoord:` records; capability requirements never appear in `ToolSpec`s.
26
+ 4. **`CoordinationPlan` ≠ `apexec:ExecutionPlan`.** Related only through compilation provenance (`prov:wasDerivedFrom` + `ep-plan:isDecomposedAsPlan` + `p-plan:correspondsToStep`). Never subclass or synonymize.
27
+ 5. **No back-edges.** `coordination` and `orchestration` never import each other; the a2a runtime composes both.
28
+ 6. **Runs never mutate coordination state.** Execution outcomes enter an Endeavor only as signed commands through the coordination reducer.
29
+ 7. **Neither plane is authority** (ADR-0054 §4): allocation, commitment, adoption, playbook activation grant nothing; no gate reads `apcoord:`/`apexec:` terms.
30
+
31
+ **Source:** ADR-0044, ADR-0054, spec 330, spec 332, `plan.ttl`, coordination-vs-orchestration.md.