@mnmal-ai/cortext 1.0.0-alpha.10 → 1.0.0-alpha.12

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/dist/bootstrap.js CHANGED
@@ -1,5 +1,5 @@
1
- import { E as isMonotonicAuth, t as createCortextPlugin, w as DEFAULT_AUTH } from "./src-DAeiNhDw.js";
2
- import { A as CORTEXT_NAMESPACE, O as ARCHITECTURE_NAMESPACE } from "./plugin-CujP_pvT.js";
1
+ import { D as isMonotonicAuth, T as DEFAULT_AUTH, t as createCortextPlugin } from "./src-4GYqbw6S.js";
2
+ import { A as CORTEXT_NAMESPACE, O as ARCHITECTURE_NAMESPACE } from "./plugin-BtBVkZpZ.js";
3
3
  import "./kernel.js";
4
4
  import { defineBootstrap } from "@mnmal-ai/substrate/sdk";
5
5
  import { z } from "zod";
package/dist/index.d.ts CHANGED
@@ -26,7 +26,7 @@ import type { CortextPluginConfig } from './config.js';
26
26
  export { buildAuthPolicies, DEFAULT_AUTH, isMonotonicAuth } from './auth-policy.js';
27
27
  export { type CompactResult, registerCompactRoute, runCompact } from './compact.js';
28
28
  export type { CortextAuthConfig, CortextAuthMode, CortextPluginConfig } from './config.js';
29
- export { AGENT_MESSAGE_STATUS_VOCAB, AGENT_RULE_CATEGORY_VOCAB, AGENT_RULE_SEVERITY_ALIASES, AGENT_RULE_SEVERITY_VOCAB, ARCHITECTURE_TYPE_NAMES, buildArchitectureNamespace, buildClaudeNamespace, CLAUDE_TYPE_NAMES, DECISION_STATUS_ALIASES, DECISION_STATUS_VOCAB, HOST_INSTALL_CHECK_STATES, HOST_INSTALL_FRAGMENT_STATES, TODO_RESOLUTION_ALIASES, TODO_STATUS_ALIASES, TODO_STATUS_IMPLIES } from './namespace.js';
29
+ export { AGENT_MESSAGE_STATUS_VOCAB, AGENT_RULE_CATEGORY_VOCAB, AGENT_RULE_SEVERITY_ALIASES, AGENT_RULE_SEVERITY_VOCAB, ARCHITECTURE_TYPE_NAMES, buildArchitectureNamespace, buildClaudeNamespace, CLAUDE_TYPE_NAMES, DECISION_STATUS_ALIASES, DECISION_STATUS_VOCAB, HOST_INSTALL_CHECK_STATES, HOST_INSTALL_FRAGMENT_STATES, TASK_STATUS_VOCAB, TODO_RESOLUTION_ALIASES, TODO_STATUS_ALIASES, TODO_STATUS_IMPLIES } from './namespace.js';
30
30
  export { registerOnboardRoute } from './onboard.js';
31
31
  export { buildReleaseSurface, bumpClass, classifySurfaceChange, classSatisfies, type ReleaseClass, type ReleaseSurface, type SurfaceChange, type SurfaceField } from './release-surface.js';
32
32
  export { type ClosedTodoText, inferTodoResolution, type TodoResolution } from './todo-resolution.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { C as runCompact, E as isMonotonicAuth, S as registerCompactRoute, T as buildAuthPolicies, _ as TODO_RESOLUTION_ALIASES, a as classSatisfies, b as buildArchitectureNamespace, c as AGENT_RULE_CATEGORY_VOCAB, d as ARCHITECTURE_TYPE_NAMES, f as CLAUDE_TYPE_NAMES, g as HOST_INSTALL_FRAGMENT_STATES, h as HOST_INSTALL_CHECK_STATES, i as bumpClass, l as AGENT_RULE_SEVERITY_ALIASES, m as DECISION_STATUS_VOCAB, n as inferTodoResolution, o as classifySurfaceChange, p as DECISION_STATUS_ALIASES, r as buildReleaseSurface, s as registerOnboardRoute, t as createCortextPlugin, u as AGENT_RULE_SEVERITY_VOCAB, v as TODO_STATUS_ALIASES, w as DEFAULT_AUTH, x as buildClaudeNamespace, y as TODO_STATUS_IMPLIES } from "./src-DAeiNhDw.js";
2
- import { _ as AGENT_MESSAGE_STATUS_VOCAB } from "./plugin-CujP_pvT.js";
1
+ import { C as registerCompactRoute, D as isMonotonicAuth, E as buildAuthPolicies, S as buildClaudeNamespace, T as DEFAULT_AUTH, _ as TASK_STATUS_VOCAB, a as classSatisfies, b as TODO_STATUS_IMPLIES, c as AGENT_RULE_CATEGORY_VOCAB, d as ARCHITECTURE_TYPE_NAMES, f as CLAUDE_TYPE_NAMES, g as HOST_INSTALL_FRAGMENT_STATES, h as HOST_INSTALL_CHECK_STATES, i as bumpClass, l as AGENT_RULE_SEVERITY_ALIASES, m as DECISION_STATUS_VOCAB, n as inferTodoResolution, o as classifySurfaceChange, p as DECISION_STATUS_ALIASES, r as buildReleaseSurface, s as registerOnboardRoute, t as createCortextPlugin, u as AGENT_RULE_SEVERITY_VOCAB, v as TODO_RESOLUTION_ALIASES, w as runCompact, x as buildArchitectureNamespace, y as TODO_STATUS_ALIASES } from "./src-4GYqbw6S.js";
2
+ import { _ as AGENT_MESSAGE_STATUS_VOCAB } from "./plugin-BtBVkZpZ.js";
3
3
  import "./kernel.js";
4
4
 
5
- export { AGENT_MESSAGE_STATUS_VOCAB, AGENT_RULE_CATEGORY_VOCAB, AGENT_RULE_SEVERITY_ALIASES, AGENT_RULE_SEVERITY_VOCAB, ARCHITECTURE_TYPE_NAMES, CLAUDE_TYPE_NAMES, DECISION_STATUS_ALIASES, DECISION_STATUS_VOCAB, DEFAULT_AUTH, HOST_INSTALL_CHECK_STATES, HOST_INSTALL_FRAGMENT_STATES, TODO_RESOLUTION_ALIASES, TODO_STATUS_ALIASES, TODO_STATUS_IMPLIES, buildArchitectureNamespace, buildAuthPolicies, buildClaudeNamespace, buildReleaseSurface, bumpClass, classSatisfies, classifySurfaceChange, createCortextPlugin, inferTodoResolution, isMonotonicAuth, registerCompactRoute, registerOnboardRoute, runCompact };
5
+ export { AGENT_MESSAGE_STATUS_VOCAB, AGENT_RULE_CATEGORY_VOCAB, AGENT_RULE_SEVERITY_ALIASES, AGENT_RULE_SEVERITY_VOCAB, ARCHITECTURE_TYPE_NAMES, CLAUDE_TYPE_NAMES, DECISION_STATUS_ALIASES, DECISION_STATUS_VOCAB, DEFAULT_AUTH, HOST_INSTALL_CHECK_STATES, HOST_INSTALL_FRAGMENT_STATES, TASK_STATUS_VOCAB, TODO_RESOLUTION_ALIASES, TODO_STATUS_ALIASES, TODO_STATUS_IMPLIES, buildArchitectureNamespace, buildAuthPolicies, buildClaudeNamespace, buildReleaseSurface, bumpClass, classSatisfies, classifySurfaceChange, createCortextPlugin, inferTodoResolution, isMonotonicAuth, registerCompactRoute, registerOnboardRoute, runCompact };
@@ -1,16 +1,22 @@
1
1
  /**
2
- * Which storage layout `rows` has: one shared table (`legacy`) or a table
3
- * partitioned by namespace and type (`partitioned`).
2
+ * How the store keeps rows: one shared `rows` table (`legacy`), `rows`
3
+ * partitioned by namespace and type (`partitioned`), or one table per type
4
+ * listed in `substrate_type_tables` (`tables`, the only layout substrate
5
+ * 1.0.0-alpha.12 and later boots).
4
6
  *
5
- * On a partitioned `rows`, Postgres refuses a UNIQUE index that lacks the
6
- * partition keys, and clones every parent-level index and CHECK onto every
7
- * other plugin's partitions. So cortext's raw DDL runs on `legacy` only; on
8
- * `partitioned` the engine builds cortext's declared and `indexed: true`
9
- * indexes per partition.
7
+ * cortext's raw DDL targets `rows` on `legacy` only. On `partitioned`,
8
+ * Postgres refuses a UNIQUE index that lacks the partition keys and clones
9
+ * every parent-level index and CHECK onto other plugins' partitions; on
10
+ * `tables` there is no `rows` at all. On both, the engine builds cortext's
11
+ * declared indexes, `indexed: true` fields and enum CHECKs per type.
10
12
  */
11
- export type StoreLayout = 'legacy' | 'partitioned';
13
+ export type StoreLayout = 'legacy' | 'partitioned' | 'tables';
14
+ /** Whether `layout` has a shared `rows` table for cortext's raw DDL to target. */
15
+ export declare const hasRowsTable: (layout: unknown) => boolean;
12
16
  /**
13
17
  * The layout as the catalog reports it. Migrations read `ctx.layout` instead;
14
18
  * this is for boot-time code, whose lifecycle context does not carry it.
19
+ * A schema with neither table reads as `legacy`, whose audit then reports
20
+ * every object missing.
15
21
  */
16
22
  export declare function storeLayout(sql: unknown): Promise<StoreLayout>;
@@ -3,6 +3,10 @@
3
3
  * body (see `CORTEXT_PROMOTED_COLUMNS`), their indexes, and the invariants
4
4
  * on cortext's own types.
5
5
  *
6
+ * Only a store with a shared `rows` table gets any of it; on per-type tables
7
+ * the engine builds the columns, indexes and enum CHECKs from cortext's
8
+ * namespace definition, so both `apply` and `rollback` return first.
9
+ *
6
10
  * The kernel runner does not wrap `apply` in a transaction, so each statement
7
11
  * commits on its own and a run that dies part-way re-applies cleanly: every
8
12
  * statement is idempotent.
@@ -3,7 +3,8 @@
3
3
  * the engine serves the same reads: the derived recipient index for the
4
4
  * inbox, and the `indexed: true` indexes on project and status.
5
5
  *
6
- * A partitioned `rows` never had them. Idempotent, like 0001: the runner does
6
+ * A partitioned `rows` never had them, and a per-type tables store has no
7
+ * `rows` at all. Idempotent, like 0001: the runner does
7
8
  * not wrap `apply` in a transaction.
8
9
  */
9
10
  import type { KernelMigration } from '@mnmal-ai/substrate/sdk';
@@ -16,4 +16,4 @@
16
16
  * by reflex: widen it only after reading what the new major changed.
17
17
  * `substrate-contract-parity.test.ts` holds the manifest to this literal.
18
18
  */
19
- export declare const SUBSTRATE_CONTRACT_RANGE = ">=1.0.0-alpha.10 <2.0.0";
19
+ export declare const SUBSTRATE_CONTRACT_RANGE = ">=1.0.0-alpha.12 <2.0.0";
@@ -1,4 +1,4 @@
1
- import { t as createCortextKernelPlugin } from "./plugin-CujP_pvT.js";
1
+ import { t as createCortextKernelPlugin } from "./plugin-BtBVkZpZ.js";
2
2
  import { defineBootstrap } from "@mnmal-ai/substrate/sdk";
3
3
  import { z } from "zod";
4
4
 
package/dist/kernel.js CHANGED
@@ -1,3 +1,3 @@
1
- import { A as CORTEXT_NAMESPACE, C as auditObjects, D as scopedNamespace, E as resolveCortextNamespaces, O as ARCHITECTURE_NAMESPACE, S as auditNamespaceCoverage, T as reportInvariantAudit, _ as AGENT_MESSAGE_STATUS_VOCAB, a as repairInvariants, b as TODO_RESOLUTION_VOCAB, c as ENGINE_OWNED_INDEXES, d as VOCAB_CONSTRAINTS, f as countDuplicateHostInstallKeys, g as rescopeVocabConstraint, h as rescopeKidUniqueIndex, i as repairIfRequested, k as CORTEXT_COORDINATOR_NAME, l as cortextDropEngineOwnedIndexesMigration, m as rescopeHostInstallKeyIndex, n as SUBSTRATE_CONTRACT_RANGE, o as repairOutcomeMessage, p as countDuplicateKids, r as REPAIR_ENV_VAR, s as repairRequested, t as createCortextKernelPlugin, u as cortextBaselineMigration, v as TODO_LIFECYCLE_VOCAB, w as findingMessage, x as INVARIANT_OBJECTS, y as TODO_PRIORITY_VOCAB } from "./plugin-CujP_pvT.js";
1
+ import { A as CORTEXT_NAMESPACE, C as auditObjects, D as scopedNamespace, E as resolveCortextNamespaces, O as ARCHITECTURE_NAMESPACE, S as auditNamespaceCoverage, T as reportInvariantAudit, _ as AGENT_MESSAGE_STATUS_VOCAB, a as repairInvariants, b as TODO_RESOLUTION_VOCAB, c as ENGINE_OWNED_INDEXES, d as VOCAB_CONSTRAINTS, f as countDuplicateHostInstallKeys, g as rescopeVocabConstraint, h as rescopeKidUniqueIndex, i as repairIfRequested, k as CORTEXT_COORDINATOR_NAME, l as cortextDropEngineOwnedIndexesMigration, m as rescopeHostInstallKeyIndex, n as SUBSTRATE_CONTRACT_RANGE, o as repairOutcomeMessage, p as countDuplicateKids, r as REPAIR_ENV_VAR, s as repairRequested, t as createCortextKernelPlugin, u as cortextBaselineMigration, v as TODO_LIFECYCLE_VOCAB, w as findingMessage, x as INVARIANT_OBJECTS, y as TODO_PRIORITY_VOCAB } from "./plugin-BtBVkZpZ.js";
2
2
 
3
3
  export { AGENT_MESSAGE_STATUS_VOCAB, ARCHITECTURE_NAMESPACE, CORTEXT_COORDINATOR_NAME, CORTEXT_NAMESPACE, ENGINE_OWNED_INDEXES, INVARIANT_OBJECTS, REPAIR_ENV_VAR, SUBSTRATE_CONTRACT_RANGE, TODO_LIFECYCLE_VOCAB, TODO_PRIORITY_VOCAB, TODO_RESOLUTION_VOCAB, VOCAB_CONSTRAINTS, auditNamespaceCoverage, auditObjects, cortextBaselineMigration, cortextDropEngineOwnedIndexesMigration, countDuplicateHostInstallKeys, countDuplicateKids, createCortextKernelPlugin, findingMessage, repairIfRequested, repairInvariants, repairOutcomeMessage, repairRequested, reportInvariantAudit, rescopeHostInstallKeyIndex, rescopeKidUniqueIndex, rescopeVocabConstraint, resolveCortextNamespaces, scopedNamespace };
@@ -141,9 +141,10 @@ export { AGENT_MESSAGE_STATUS_VOCAB } from './kernel/index.js';
141
141
  export declare const HOST_INSTALL_FRAGMENT_STATES: readonly ['current', 'stale', 'missing', 'undigested', 'uncomparable', 'source', 'absent'];
142
142
  /** HostInstall's per-check verdicts: the worst finding each check produced. */
143
143
  export declare const HOST_INSTALL_CHECK_STATES: readonly ['ok', 'warn', 'unknown'];
144
+ export declare const TASK_STATUS_VOCAB: readonly ['active', 'paused', 'done'];
144
145
  export declare function buildClaudeNamespace(ns: string): NamespaceDefinition;
145
146
  /** The canonical ordered list of type names registered by this namespace. */
146
- export declare const CLAUDE_TYPE_NAMES: readonly ['SessionLog', 'Decision', 'Todo', 'AgentRule', 'CouncilSession', 'CouncilAdvisor', 'Memory', 'AnchorIntent', 'Concept', 'ConceptLink', 'Skill', 'AgentIdentity', 'AgentMessage', 'HostInstall'];
147
+ export declare const CLAUDE_TYPE_NAMES: readonly ['SessionLog', 'Decision', 'Todo', 'AgentRule', 'CouncilSession', 'CouncilAdvisor', 'Memory', 'AnchorIntent', 'Concept', 'ConceptLink', 'Skill', 'AgentIdentity', 'AgentMessage', 'HostInstall', 'Task', 'ExecutionCheckpoint'];
147
148
  /**
148
149
  * Architecture namespace — Claude-lineage code-review findings. Kept separate
149
150
  * from the claude context namespace so lifecycle (compaction, retention,
@@ -11,7 +11,15 @@
11
11
  * An operator is an identity granted `admin` (or `*`) in this namespace.
12
12
  */
13
13
  import type { NamespaceInstallContext, RegistryEntryResolver, RequestContext } from '@mnmal-ai/substrate/sdk';
14
- /** Whether the caller holds `admin` (or `*`) in the namespace it is calling. */
14
+ /**
15
+ * Whether `identity` is an operator: it holds `admin` (or `*`) in `namespace`,
16
+ * or the deployment admin capability (`SUBSTRATE_ADMIN_CAPABILITY`, default
17
+ * `admin`) in `_system`, as substrate's own admin gate reads it.
18
+ */
19
+ export declare function isOperatorIdentity(identity: RequestContext['identity'], namespace: string, env?: {
20
+ SUBSTRATE_ADMIN_CAPABILITY?: string;
21
+ }): boolean;
22
+ /** Whether the caller is an operator in the namespace it is calling. */
15
23
  export declare function isOperator(ctx: RequestContext): boolean;
16
24
  /**
17
25
  * AgentMessage update/delete: the sender, the recipient, or an operator.
@@ -98,15 +98,22 @@ const CORTEXT_PROMOTED_COLUMNS = {
98
98
 
99
99
  //#endregion
100
100
  //#region src/kernel/layout.ts
101
+ /** Whether `layout` has a shared `rows` table for cortext's raw DDL to target. */
102
+ const hasRowsTable = (layout) => layout === "legacy" || layout === "partitioned";
101
103
  /**
102
104
  * The layout as the catalog reports it. Migrations read `ctx.layout` instead;
103
105
  * this is for boot-time code, whose lifecycle context does not carry it.
106
+ * A schema with neither table reads as `legacy`, whose audit then reports
107
+ * every object missing.
104
108
  */
105
109
  async function storeLayout(sql) {
106
110
  const [row] = await sql`
107
- SELECT c.relkind AS kind FROM pg_class c WHERE c.oid = to_regclass('rows')
111
+ SELECT (SELECT c.relkind FROM pg_class c WHERE c.oid = to_regclass('rows')) AS kind,
112
+ to_regclass('substrate_type_tables') IS NOT NULL AS tables
108
113
  `;
109
- return row?.kind === "p" ? "partitioned" : "legacy";
114
+ if (row?.kind === "p") return "partitioned";
115
+ if (row?.kind == null && row?.tables === true) return "tables";
116
+ return "legacy";
110
117
  }
111
118
 
112
119
  //#endregion
@@ -360,11 +367,11 @@ function findingMessage(finding) {
360
367
  * structured channel this belongs in.
361
368
  */
362
369
  async function reportInvariantAudit(ctx, warn = console.warn) {
363
- let findings = [...auditNamespaceCoverage(ctx.coordinatorNamespaces, ctx.coordinatorNamespacesByPlugin)];
364
- const target = ctx.coordinatorNamespaces.includes("cortext") ? CORTEXT_NAMESPACE : resolveCortextNamespaces(ctx.coordinatorNamespacesByPlugin)?.[0] ?? "cortext";
365
370
  const catalogRead = ctx.sql !== null && ctx.sql !== void 0;
366
- let objectsChecked = 0;
367
371
  const layout = catalogRead ? await storeLayout(ctx.sql).catch(() => "legacy") : null;
372
+ let findings = layout !== null && layout !== "legacy" ? [] : auditNamespaceCoverage(ctx.coordinatorNamespaces, ctx.coordinatorNamespacesByPlugin);
373
+ const target = ctx.coordinatorNamespaces.includes("cortext") ? CORTEXT_NAMESPACE : resolveCortextNamespaces(ctx.coordinatorNamespacesByPlugin)?.[0] ?? "cortext";
374
+ let objectsChecked = 0;
368
375
  if (catalogRead && layout === "legacy") try {
369
376
  const result = await auditObjects(ctx.sql, target);
370
377
  if (target !== "cortext" && result.findings.length === 0) findings = findings.filter((f) => f.kind !== "namespace_drifted");
@@ -602,7 +609,7 @@ const cortextBaselineMigration = {
602
609
  id: "0001_baseline",
603
610
  apply: async (ctx) => {
604
611
  const { sql, metric } = ctx;
605
- if (sql === null) return;
612
+ if (sql === null || !hasRowsTable(ctx.layout)) return;
606
613
  const s = sql;
607
614
  await s.unsafe(`
608
615
  ALTER TABLE rows
@@ -620,8 +627,8 @@ const cortextBaselineMigration = {
620
627
  await rescopeKidUniqueIndex(s, CORTEXT_NAMESPACE);
621
628
  await rescopeHostInstallKeyIndex(s, CORTEXT_NAMESPACE);
622
629
  },
623
- rollback: async ({ sql }) => {
624
- if (sql === null) return;
630
+ rollback: async ({ sql, layout }) => {
631
+ if (sql === null || !hasRowsTable(layout)) return;
625
632
  const s = sql;
626
633
  for (const { constraint } of VOCAB_CONSTRAINTS) await s.unsafe(`ALTER TABLE rows DROP CONSTRAINT IF EXISTS ${constraint}`);
627
634
  await s.unsafe("DROP INDEX IF EXISTS rows_agent_identity_kid_unique, rows_host_install_key_unique");
@@ -641,7 +648,7 @@ const ENGINE_OWNED_INDEXES = [
641
648
  const cortextDropEngineOwnedIndexesMigration = {
642
649
  id: "0002_drop_engine_owned_indexes",
643
650
  apply: async ({ sql, layout }) => {
644
- if (sql === null || layout === "partitioned") return;
651
+ if (sql === null || layout !== "legacy") return;
645
652
  await sql.unsafe(`DROP INDEX IF EXISTS ${ENGINE_OWNED_INDEXES.join(", ")}`);
646
653
  },
647
654
  rollback: async () => {}
@@ -740,9 +747,10 @@ async function repairIfRequested(ctx, warn = console.warn) {
740
747
  ctx.metric("cortext_kernel.repair_declined", { reason: "target_unknown" });
741
748
  return null;
742
749
  }
743
- if (await storeLayout(ctx.sql).catch(() => "legacy") === "partitioned") {
744
- warn(`[cortext-kernel] ${REPAIR_ENV_VAR} is set, but rows is partitioned: the engine owns cortext's indexes there and there are no parent-level objects to repair. Nothing to do.`);
745
- ctx.metric("cortext_kernel.repair_declined", { reason: "partitioned" });
750
+ const layout = await storeLayout(ctx.sql).catch(() => "legacy");
751
+ if (layout !== "legacy") {
752
+ warn(`[cortext-kernel] ${REPAIR_ENV_VAR} is set, but the store layout is ${layout}: the engine owns cortext's indexes and CHECKs there, and there are no objects on rows to repair. Nothing to do.`);
753
+ ctx.metric("cortext_kernel.repair_declined", { reason: layout });
746
754
  return null;
747
755
  }
748
756
  warn(`[cortext-kernel] ${REPAIR_ENV_VAR} is set — re-scoping kernel invariants to '${ctx.namespace}'. This takes ACCESS EXCLUSIVE on rows and briefly blocks writes.` + (ctx.namespace === "cortext" ? " Target matches the built-in scope literal, so this is a no-op rebuild." : ""));
@@ -789,7 +797,7 @@ async function repairIfRequested(ctx, warn = console.warn) {
789
797
  * by reflex: widen it only after reading what the new major changed.
790
798
  * `substrate-contract-parity.test.ts` holds the manifest to this literal.
791
799
  */
792
- const SUBSTRATE_CONTRACT_RANGE = ">=1.0.0-alpha.10 <2.0.0";
800
+ const SUBSTRATE_CONTRACT_RANGE = ">=1.0.0-alpha.12 <2.0.0";
793
801
 
794
802
  //#endregion
795
803
  //#region src/kernel/plugin.ts
@@ -1,5 +1,5 @@
1
- import { A as CORTEXT_NAMESPACE, O as ARCHITECTURE_NAMESPACE, _ as AGENT_MESSAGE_STATUS_VOCAB, b as TODO_RESOLUTION_VOCAB, j as CORTEXT_PROMOTED_COLUMNS, k as CORTEXT_COORDINATOR_NAME, n as SUBSTRATE_CONTRACT_RANGE, v as TODO_LIFECYCLE_VOCAB, y as TODO_PRIORITY_VOCAB } from "./plugin-CujP_pvT.js";
2
- import { JSON_HEADERS, RESERVED_AUTOCRUD_FIELDS, ResolverFrameError, and, createResolverWithEdges, defineNamespace, deleteResolver, denyAll, denyVerbs, field, formatQualifiedKey, getResolver, grantOf, grantedIn, jsonResponse, listResolver, makeCtx, or, queryAll, requireIdentity, resolveEntityRow, resolveIdentity, selectAll, updateResolver } from "@mnmal-ai/substrate/sdk";
1
+ import { A as CORTEXT_NAMESPACE, O as ARCHITECTURE_NAMESPACE, _ as AGENT_MESSAGE_STATUS_VOCAB, b as TODO_RESOLUTION_VOCAB, j as CORTEXT_PROMOTED_COLUMNS, k as CORTEXT_COORDINATOR_NAME, n as SUBSTRATE_CONTRACT_RANGE, v as TODO_LIFECYCLE_VOCAB, y as TODO_PRIORITY_VOCAB } from "./plugin-BtBVkZpZ.js";
2
+ import { JSON_HEADERS, RESERVED_AUTOCRUD_FIELDS, ResolverFrameError, SYSTEM_NAMESPACE, and, createResolverWithEdges, defineNamespace, deleteResolver, denyAll, denyVerbs, field, formatQualifiedKey, getResolver, grantOf, grantedIn, jsonResponse, listResolver, makeCtx, or, queryAll, requireIdentity, resolveEntityRow, resolveIdentity, selectAll, updateResolver } from "@mnmal-ai/substrate/sdk";
3
3
 
4
4
  //#region src/auth-policy.ts
5
5
  /**
@@ -40,6 +40,154 @@ function buildAuthPolicies(auth) {
40
40
  return [];
41
41
  }
42
42
 
43
+ //#endregion
44
+ //#region src/participants.ts
45
+ /**
46
+ * Whether `identity` is an operator: it holds `admin` (or `*`) in `namespace`,
47
+ * or the deployment admin capability (`SUBSTRATE_ADMIN_CAPABILITY`, default
48
+ * `admin`) in `_system`, as substrate's own admin gate reads it.
49
+ */
50
+ function isOperatorIdentity(identity, namespace, env = process.env) {
51
+ const grant = grantOf(identity);
52
+ const caps = grantedIn(grant, namespace);
53
+ if (caps.includes("admin") || caps.includes("*")) return true;
54
+ const adminCap = env.SUBSTRATE_ADMIN_CAPABILITY || "admin";
55
+ const system = grantedIn(grant, SYSTEM_NAMESPACE);
56
+ return system.includes(adminCap) || system.includes("*");
57
+ }
58
+ /** Whether the caller is an operator in the namespace it is calling. */
59
+ function isOperator(ctx) {
60
+ return isOperatorIdentity(ctx.identity, ctx.namespace);
61
+ }
62
+ function rowId(args) {
63
+ const raw = args.params?.id;
64
+ return typeof raw === "string" || typeof raw === "number" ? raw : void 0;
65
+ }
66
+ function callerKid(ctx) {
67
+ const id = ctx.identity?.id;
68
+ return typeof id === "string" && id !== "" ? id : null;
69
+ }
70
+ /**
71
+ * AgentMessage update/delete: the sender, the recipient, or an operator.
72
+ * The sender is the key that signed the send (`_metadata.createdBy`); the
73
+ * recipient is the kid on the addressed directory row. Archiving someone
74
+ * else's mail hides it from their inbox, and deleting it destroys it, so
75
+ * neither is a bystander's call.
76
+ */
77
+ function messageParticipantsOnly(installCtx, name, inner) {
78
+ return async (ctx, args) => {
79
+ const id = rowId(args);
80
+ if (id === void 0 || isOperator(ctx)) return inner(ctx, args);
81
+ const ds = args.dataset ?? installCtx.dataset;
82
+ const message = await resolveEntityRow(ds, "AgentMessage", id);
83
+ if (message === null) return inner(ctx, args);
84
+ const caller = callerKid(ctx);
85
+ const sender = message._metadata?.createdBy?.id;
86
+ let recipient = null;
87
+ if (typeof message.recipient === "string" && message.recipient !== "") {
88
+ const { rows } = await ds.read("AgentIdentity", { id: message.recipient });
89
+ recipient = rows[0]?.kid ?? null;
90
+ }
91
+ if (caller !== null && (caller === sender || caller === recipient)) return inner(ctx, args);
92
+ throw new ResolverFrameError("not_participant", `${name}: only this message's sender ('${String(sender ?? "unknown")}') or recipient ('${String(recipient ?? "unknown")}'), or an operator, may change or delete it`, { id: message.id });
93
+ };
94
+ }
95
+ /**
96
+ * Whether `host` names the machine in `kid`'s `@host` part, ignoring case.
97
+ * A kid with no `@` names no machine, so it may carry no host.
98
+ */
99
+ function hostMatchesKid(host, kid) {
100
+ if (host === void 0 || host === null) return true;
101
+ if (typeof kid !== "string" || !kid.includes("@")) return false;
102
+ return String(host).toLowerCase() === kid.slice(kid.lastIndexOf("@") + 1).toLowerCase();
103
+ }
104
+ function refuseForeignHost(name, host, kid) {
105
+ if (hostMatchesKid(host, kid)) return;
106
+ throw new ResolverFrameError("operator_only", `${name}: 'host' must be the machine in the kid ('${String(kid)}'); only an operator may set another`, { field: "host" });
107
+ }
108
+ /**
109
+ * AgentIdentity create: a non-operator may not file a row whose `host` is a
110
+ * machine other than the one its kid names. The fleet audit trusts `host`
111
+ * (and `roaming` on that host) when it decides who may write a host's
112
+ * HostInstall rows.
113
+ */
114
+ function identityCreateGuard(installCtx, name, inner) {
115
+ return async (ctx, args) => {
116
+ const params = args.params ?? {};
117
+ if (!isOperator(ctx)) refuseForeignHost(name, params.host, params.kid);
118
+ if (typeof params.kid === "string") {
119
+ const { rows } = await (args.dataset ?? installCtx.dataset).read("AgentIdentity", {
120
+ where: { kid: { eq: params.kid } },
121
+ limit: 1
122
+ });
123
+ if (rows.length > 0) throw new ResolverFrameError("duplicate_kid", `${name}: an AgentIdentity row for '${params.kid}' already exists; update it instead`, { field: "kid" });
124
+ }
125
+ return inner(ctx, args);
126
+ };
127
+ }
128
+ /**
129
+ * AgentIdentity update: the identity itself (the caller's kid is the row's
130
+ * kid) or an operator. `kid` is the row's identity, so changing it is an
131
+ * operator act even on your own row: otherwise a row could be renamed onto a
132
+ * kid whose mail it would then receive. `host` must stay the kid's machine,
133
+ * and reactivating a retired row is an operator act.
134
+ */
135
+ function identitySelfOnly(installCtx, name, inner) {
136
+ return async (ctx, args) => {
137
+ const id = rowId(args);
138
+ if (id === void 0 || isOperator(ctx)) return inner(ctx, args);
139
+ const ds = args.dataset ?? installCtx.dataset;
140
+ const row = await resolveEntityRow(ds, "AgentIdentity", id);
141
+ if (row === null) return inner(ctx, args);
142
+ const params = args.params ?? {};
143
+ if ("kid" in params && params.kid !== row.kid) throw new ResolverFrameError("operator_only", `${name}: 'kid' is the row's identity and only an operator may change it`, { field: "kid" });
144
+ if (callerKid(ctx) === row.kid) {
145
+ if ("host" in params || "roaming" in params || "project" in params) refuseForeignHost(name, "host" in params ? params.host : row.host, row.kid);
146
+ if (params.active === true && row.active === false) throw new ResolverFrameError("operator_only", `${name}: a retired identity may only be reactivated by an operator`, { field: "active" });
147
+ return inner(ctx, args);
148
+ }
149
+ throw new ResolverFrameError("not_self", `${name}: only '${String(row.kid)}' itself, or an operator, may edit this identity row`, { id: row.id });
150
+ };
151
+ }
152
+ /**
153
+ * Todo create/update: `resolution` says why a CLOSED Todo stopped, so a live
154
+ * Todo carries none. A resolution with a live resulting status is refused,
155
+ * and moving a Todo back to a live status clears the one it had.
156
+ */
157
+ function todoResolutionGuard(installCtx, name, inner, statusAliases) {
158
+ const canon = (v) => {
159
+ const s = String(v).trim().toLowerCase();
160
+ return statusAliases[s] ?? s;
161
+ };
162
+ return async (ctx, args) => {
163
+ const params = { ...args.params ?? {} };
164
+ const statusGiven = params.status !== void 0 && params.status !== null;
165
+ let resulting = statusGiven ? canon(params.status) : null;
166
+ let current = null;
167
+ const id = rowId(args);
168
+ if (id !== void 0) {
169
+ const ds = args.dataset ?? installCtx.dataset;
170
+ current = await resolveEntityRow(ds, "Todo", id);
171
+ if (resulting === null && current !== null) resulting = canon(current.status);
172
+ }
173
+ if (resulting === null) resulting = "open";
174
+ if (resulting === "closed") return inner(ctx, args);
175
+ if (params.resolution !== void 0 && params.resolution !== null) throw new ResolverFrameError("resolution_on_live_todo", `${name}: 'resolution' is for closed Todos; this one would be '${resulting}'`, { field: "resolution" });
176
+ if (statusGiven && current !== null && current.resolution != null && !("resolution" in params)) params.resolution = null;
177
+ return inner(ctx, {
178
+ ...args,
179
+ params
180
+ });
181
+ };
182
+ }
183
+ /** AgentIdentity delete: operators only. Mail hangs off these rows. */
184
+ function operatorOnly(name, inner) {
185
+ return async (ctx, args) => {
186
+ if (isOperator(ctx)) return inner(ctx, args);
187
+ throw new ResolverFrameError("operator_only", `${name}: only an operator may delete an identity row; retire it with active: false instead`, {});
188
+ };
189
+ }
190
+
43
191
  //#endregion
44
192
  //#region src/compact.ts
45
193
  /**
@@ -173,10 +321,9 @@ function parseBody(req) {
173
321
  function registerCompactRoute(router, ctx, retention, namespace, auth = DEFAULT_AUTH) {
174
322
  router.post("/compact", async (req) => {
175
323
  if (auth.writes === "identity") {
176
- const caps = grantedIn(grantOf(req.identity ?? null), namespace);
177
- if (!caps.includes("admin") && !caps.includes("*")) return jsonResponse(403, {
324
+ if (!isOperatorIdentity(req.identity ?? null, namespace)) return jsonResponse(403, {
178
325
  code: "operator_only",
179
- message: `POST /compact archives across every project and needs an operator (admin in '${namespace}')`
326
+ message: `POST /compact archives across every project and needs an operator (admin in '${namespace}', or the deployment admin)`
180
327
  });
181
328
  }
182
329
  const parsed = parseBody(req);
@@ -258,142 +405,6 @@ function reportUncoveredNamespaces(cfg, metric, warn = console.warn) {
258
405
  return uncovered;
259
406
  }
260
407
 
261
- //#endregion
262
- //#region src/participants.ts
263
- /** Whether the caller holds `admin` (or `*`) in the namespace it is calling. */
264
- function isOperator(ctx) {
265
- const caps = grantedIn(grantOf(ctx.identity), ctx.namespace);
266
- return caps.includes("admin") || caps.includes("*");
267
- }
268
- function rowId(args) {
269
- const raw = args.params?.id;
270
- return typeof raw === "string" || typeof raw === "number" ? raw : void 0;
271
- }
272
- function callerKid(ctx) {
273
- const id = ctx.identity?.id;
274
- return typeof id === "string" && id !== "" ? id : null;
275
- }
276
- /**
277
- * AgentMessage update/delete: the sender, the recipient, or an operator.
278
- * The sender is the key that signed the send (`_metadata.createdBy`); the
279
- * recipient is the kid on the addressed directory row. Archiving someone
280
- * else's mail hides it from their inbox, and deleting it destroys it, so
281
- * neither is a bystander's call.
282
- */
283
- function messageParticipantsOnly(installCtx, name, inner) {
284
- return async (ctx, args) => {
285
- const id = rowId(args);
286
- if (id === void 0 || isOperator(ctx)) return inner(ctx, args);
287
- const ds = args.dataset ?? installCtx.dataset;
288
- const message = await resolveEntityRow(ds, "AgentMessage", id);
289
- if (message === null) return inner(ctx, args);
290
- const caller = callerKid(ctx);
291
- const sender = message._metadata?.createdBy?.id;
292
- let recipient = null;
293
- if (typeof message.recipient === "string" && message.recipient !== "") {
294
- const { rows } = await ds.read("AgentIdentity", { id: message.recipient });
295
- recipient = rows[0]?.kid ?? null;
296
- }
297
- if (caller !== null && (caller === sender || caller === recipient)) return inner(ctx, args);
298
- throw new ResolverFrameError("not_participant", `${name}: only this message's sender ('${String(sender ?? "unknown")}') or recipient ('${String(recipient ?? "unknown")}'), or an operator, may change or delete it`, { id: message.id });
299
- };
300
- }
301
- /**
302
- * Whether `host` names the machine in `kid`'s `@host` part, ignoring case.
303
- * A kid with no `@` names no machine, so it may carry no host.
304
- */
305
- function hostMatchesKid(host, kid) {
306
- if (host === void 0 || host === null) return true;
307
- if (typeof kid !== "string" || !kid.includes("@")) return false;
308
- return String(host).toLowerCase() === kid.slice(kid.lastIndexOf("@") + 1).toLowerCase();
309
- }
310
- function refuseForeignHost(name, host, kid) {
311
- if (hostMatchesKid(host, kid)) return;
312
- throw new ResolverFrameError("operator_only", `${name}: 'host' must be the machine in the kid ('${String(kid)}'); only an operator may set another`, { field: "host" });
313
- }
314
- /**
315
- * AgentIdentity create: a non-operator may not file a row whose `host` is a
316
- * machine other than the one its kid names. The fleet audit trusts `host`
317
- * (and `roaming` on that host) when it decides who may write a host's
318
- * HostInstall rows.
319
- */
320
- function identityCreateGuard(installCtx, name, inner) {
321
- return async (ctx, args) => {
322
- const params = args.params ?? {};
323
- if (!isOperator(ctx)) refuseForeignHost(name, params.host, params.kid);
324
- if (typeof params.kid === "string") {
325
- const { rows } = await (args.dataset ?? installCtx.dataset).read("AgentIdentity", {
326
- where: { kid: { eq: params.kid } },
327
- limit: 1
328
- });
329
- if (rows.length > 0) throw new ResolverFrameError("duplicate_kid", `${name}: an AgentIdentity row for '${params.kid}' already exists; update it instead`, { field: "kid" });
330
- }
331
- return inner(ctx, args);
332
- };
333
- }
334
- /**
335
- * AgentIdentity update: the identity itself (the caller's kid is the row's
336
- * kid) or an operator. `kid` is the row's identity, so changing it is an
337
- * operator act even on your own row: otherwise a row could be renamed onto a
338
- * kid whose mail it would then receive. `host` must stay the kid's machine,
339
- * and reactivating a retired row is an operator act.
340
- */
341
- function identitySelfOnly(installCtx, name, inner) {
342
- return async (ctx, args) => {
343
- const id = rowId(args);
344
- if (id === void 0 || isOperator(ctx)) return inner(ctx, args);
345
- const ds = args.dataset ?? installCtx.dataset;
346
- const row = await resolveEntityRow(ds, "AgentIdentity", id);
347
- if (row === null) return inner(ctx, args);
348
- const params = args.params ?? {};
349
- if ("kid" in params && params.kid !== row.kid) throw new ResolverFrameError("operator_only", `${name}: 'kid' is the row's identity and only an operator may change it`, { field: "kid" });
350
- if (callerKid(ctx) === row.kid) {
351
- if ("host" in params || "roaming" in params || "project" in params) refuseForeignHost(name, "host" in params ? params.host : row.host, row.kid);
352
- if (params.active === true && row.active === false) throw new ResolverFrameError("operator_only", `${name}: a retired identity may only be reactivated by an operator`, { field: "active" });
353
- return inner(ctx, args);
354
- }
355
- throw new ResolverFrameError("not_self", `${name}: only '${String(row.kid)}' itself, or an operator, may edit this identity row`, { id: row.id });
356
- };
357
- }
358
- /**
359
- * Todo create/update: `resolution` says why a CLOSED Todo stopped, so a live
360
- * Todo carries none. A resolution with a live resulting status is refused,
361
- * and moving a Todo back to a live status clears the one it had.
362
- */
363
- function todoResolutionGuard(installCtx, name, inner, statusAliases) {
364
- const canon = (v) => {
365
- const s = String(v).trim().toLowerCase();
366
- return statusAliases[s] ?? s;
367
- };
368
- return async (ctx, args) => {
369
- const params = { ...args.params ?? {} };
370
- const statusGiven = params.status !== void 0 && params.status !== null;
371
- let resulting = statusGiven ? canon(params.status) : null;
372
- let current = null;
373
- const id = rowId(args);
374
- if (id !== void 0) {
375
- const ds = args.dataset ?? installCtx.dataset;
376
- current = await resolveEntityRow(ds, "Todo", id);
377
- if (resulting === null && current !== null) resulting = canon(current.status);
378
- }
379
- if (resulting === null) resulting = "open";
380
- if (resulting === "closed") return inner(ctx, args);
381
- if (params.resolution !== void 0 && params.resolution !== null) throw new ResolverFrameError("resolution_on_live_todo", `${name}: 'resolution' is for closed Todos; this one would be '${resulting}'`, { field: "resolution" });
382
- if (statusGiven && current !== null && current.resolution != null && !("resolution" in params)) params.resolution = null;
383
- return inner(ctx, {
384
- ...args,
385
- params
386
- });
387
- };
388
- }
389
- /** AgentIdentity delete: operators only. Mail hangs off these rows. */
390
- function operatorOnly(name, inner) {
391
- return async (ctx, args) => {
392
- if (isOperator(ctx)) return inner(ctx, args);
393
- throw new ResolverFrameError("operator_only", `${name}: only an operator may delete an identity row; retire it with active: false instead`, {});
394
- };
395
- }
396
-
397
408
  //#endregion
398
409
  //#region src/mailbox.ts
399
410
  const TYPE = "AgentMessage";
@@ -932,6 +943,11 @@ const HOST_INSTALL_CHECK_STATES = [
932
943
  "warn",
933
944
  "unknown"
934
945
  ];
946
+ const TASK_STATUS_VOCAB = [
947
+ "active",
948
+ "paused",
949
+ "done"
950
+ ];
935
951
  const CONCEPT_NAME_TTL_MS = 6e4;
936
952
  /** Long-form length past which `embed.source` appends the long form to the synopsis. */
937
953
  const LONGFORM_EMBED_CHARS = 1200;
@@ -1349,6 +1365,45 @@ function buildClaudeNamespace(ns) {
1349
1365
  where: "live",
1350
1366
  name: "rows_host_install_key_unique"
1351
1367
  }]
1368
+ },
1369
+ Task: { fields: {
1370
+ title: field.string(),
1371
+ status: field.enum(TASK_STATUS_VOCAB, { default: "active" }),
1372
+ todo: field.crossRef(ns, "Todo", {
1373
+ nullable: true,
1374
+ onDelete: "set_null"
1375
+ }),
1376
+ archived: field.boolean({ default: false }),
1377
+ project: field.string({
1378
+ nullable: true,
1379
+ indexed: true
1380
+ })
1381
+ } },
1382
+ ExecutionCheckpoint: {
1383
+ fields: {
1384
+ task: field.crossRef(ns, "Task", { onDelete: "cascade" }),
1385
+ revision: field.number(),
1386
+ completed: field.string({ indexed: false }),
1387
+ nextAction: field.string({ indexed: false }),
1388
+ blockers: field.string({
1389
+ nullable: true,
1390
+ indexed: false
1391
+ }),
1392
+ refs: field.list(field.string(), { nullable: true }),
1393
+ project: field.string({
1394
+ nullable: true,
1395
+ indexed: true
1396
+ })
1397
+ },
1398
+ indexes: [{
1399
+ fields: ["task", {
1400
+ field: "revision",
1401
+ dir: "desc"
1402
+ }],
1403
+ unique: true,
1404
+ where: "live",
1405
+ name: "rows_execution_checkpoint_task_revision_unique"
1406
+ }]
1352
1407
  }
1353
1408
  };
1354
1409
  const definition = defineNamespace(ns, types, {
@@ -1393,7 +1448,9 @@ const CLAUDE_TYPE_NAMES = [
1393
1448
  "Skill",
1394
1449
  "AgentIdentity",
1395
1450
  "AgentMessage",
1396
- "HostInstall"
1451
+ "HostInstall",
1452
+ "Task",
1453
+ "ExecutionCheckpoint"
1397
1454
  ];
1398
1455
  /**
1399
1456
  * Architecture namespace — Claude-lineage code-review findings. Kept separate
@@ -1690,6 +1747,32 @@ function buildBody(namespace, retention) {
1690
1747
  settingsEnv: "json — allowlisted non-secret switch values, plus whether the identity keys are set (nullable)"
1691
1748
  },
1692
1749
  writeWhen: ["Written by the cold-start of every session with an agent identity; agents read it, they do not write it"]
1750
+ },
1751
+ Task: {
1752
+ purpose: "A unit of work in flight: the stable identity a fresh session resumes by after a reset, independent of session id. Not a backlog ticket; link one via `todo`",
1753
+ fields: {
1754
+ id: "auto-generated",
1755
+ title: "what the work is",
1756
+ status: `${vocabUnion(TASK_STATUS_VOCAB)} (default active)`,
1757
+ todo: "UUID crossRef to the Todo this work implements, set_null on delete (nullable)",
1758
+ archived: "true if retired",
1759
+ project: "repo basename; null = cross-cutting"
1760
+ },
1761
+ writeWhen: ["When starting work that may outlive the context window", "Flip status to done when the work is finished, paused when set aside"]
1762
+ },
1763
+ ExecutionCheckpoint: {
1764
+ purpose: "One acknowledged step of a Task: what was completed and the next action. The latest is the Task's highest revision",
1765
+ fields: {
1766
+ id: "auto-generated",
1767
+ task: "UUID crossRef to the Task, cascade on delete",
1768
+ revision: "one higher than the Task's latest; unique per Task, so a second write at the same revision is refused",
1769
+ completed: "what this step finished (not indexed)",
1770
+ nextAction: "the exact next operation (not indexed)",
1771
+ blockers: "what stands in the way (not indexed, nullable)",
1772
+ refs: "file paths, #shortIds, PR or commit references (nullable)",
1773
+ project: "repo basename; null = cross-cutting"
1774
+ },
1775
+ writeWhen: ["After a completed subtask, a blocker, or before a reset; point at files and rows, never retell them", "Treat the step as done only once the write is acknowledged; on a refused revision, re-read the latest and retry"]
1693
1776
  }
1694
1777
  },
1695
1778
  mutations: buildMutations(),
@@ -2069,4 +2152,4 @@ function createCortextPlugin(cfg) {
2069
2152
  }
2070
2153
 
2071
2154
  //#endregion
2072
- export { runCompact as C, isMonotonicAuth as E, registerCompactRoute as S, buildAuthPolicies as T, TODO_RESOLUTION_ALIASES as _, classSatisfies as a, buildArchitectureNamespace as b, AGENT_RULE_CATEGORY_VOCAB as c, ARCHITECTURE_TYPE_NAMES as d, CLAUDE_TYPE_NAMES as f, HOST_INSTALL_FRAGMENT_STATES as g, HOST_INSTALL_CHECK_STATES as h, bumpClass as i, AGENT_RULE_SEVERITY_ALIASES as l, DECISION_STATUS_VOCAB as m, inferTodoResolution as n, classifySurfaceChange as o, DECISION_STATUS_ALIASES as p, buildReleaseSurface as r, registerOnboardRoute as s, createCortextPlugin as t, AGENT_RULE_SEVERITY_VOCAB as u, TODO_STATUS_ALIASES as v, DEFAULT_AUTH as w, buildClaudeNamespace as x, TODO_STATUS_IMPLIES as y };
2155
+ export { registerCompactRoute as C, isMonotonicAuth as D, buildAuthPolicies as E, buildClaudeNamespace as S, DEFAULT_AUTH as T, TASK_STATUS_VOCAB as _, classSatisfies as a, TODO_STATUS_IMPLIES as b, AGENT_RULE_CATEGORY_VOCAB as c, ARCHITECTURE_TYPE_NAMES as d, CLAUDE_TYPE_NAMES as f, HOST_INSTALL_FRAGMENT_STATES as g, HOST_INSTALL_CHECK_STATES as h, bumpClass as i, AGENT_RULE_SEVERITY_ALIASES as l, DECISION_STATUS_VOCAB as m, inferTodoResolution as n, classifySurfaceChange as o, DECISION_STATUS_ALIASES as p, buildReleaseSurface as r, registerOnboardRoute as s, createCortextPlugin as t, AGENT_RULE_SEVERITY_VOCAB as u, TODO_RESOLUTION_ALIASES as v, runCompact as w, buildArchitectureNamespace as x, TODO_STATUS_ALIASES as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnmal-ai/cortext",
3
- "version": "1.0.0-alpha.10",
3
+ "version": "1.0.0-alpha.12",
4
4
  "description": "Cortext: the agent-neutral coordination context store for Substrate (Todos, Decisions, SessionLogs, AgentRules, Memory, Concepts, Councils, …) plus architecture findings. One package carrying two plugins: the coordinator that registers the namespaces, and the kernel plugin that owns their Postgres invariants.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -62,10 +62,10 @@
62
62
  "zod": "^4.6.5"
63
63
  },
64
64
  "peerDependencies": {
65
- "@mnmal-ai/substrate": ">=1.0.0-alpha.10 <2.0.0"
65
+ "@mnmal-ai/substrate": ">=1.0.0-alpha.12 <2.0.0"
66
66
  },
67
67
  "devDependencies": {
68
- "@mnmal-ai/substrate": "1.0.0-alpha.10",
68
+ "@mnmal-ai/substrate": "1.0.0-alpha.12",
69
69
  "@types/node": "^26.6.4",
70
70
  "tsdown": "^0.23.0",
71
71
  "typescript": "^7.0.2",