@subseam/mcp 0.4.45 → 0.4.47

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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/main.js +46 -133
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  subseam reads your repository's history and checks every pull request against the rules your
4
4
  team writes down: "this package never imports that one", "only this module talks to the
5
- database". You write a rule as a one-line note, subseam turns it into a definition you approve,
5
+ database". You write a rule as a one-line note, subseam turns it into a definition,
6
6
  and from then on each PR shows where it breaks the rule, with the file, the line and the cause.
7
7
 
8
8
  This package is the MCP server that gives your coding agent (Claude Code, or any MCP host) the
package/dist/main.js CHANGED
@@ -20287,6 +20287,9 @@ init_esm_shims();
20287
20287
  // ../execution-contract/src/unit/test-shard.ts
20288
20288
  init_esm_shims();
20289
20289
 
20290
+ // ../execution-contract/src/unit/default-test-file.ts
20291
+ init_esm_shims();
20292
+
20290
20293
  // ../execution-contract/src/unit/footprint-segment.ts
20291
20294
  init_esm_shims();
20292
20295
 
@@ -20296,6 +20299,9 @@ init_esm_shims();
20296
20299
  // ../execution-contract/src/unit/lint-report.ts
20297
20300
  init_esm_shims();
20298
20301
 
20302
+ // ../execution-contract/src/unit/output-tail.ts
20303
+ init_esm_shims();
20304
+
20299
20305
  // ../execution-contract/src/unit/typecheck-report.ts
20300
20306
  init_esm_shims();
20301
20307
 
@@ -30647,7 +30653,7 @@ function renderDraft(d, atTip = true) {
30647
30653
  const tip = d.atTip.failures.length > 0 ? `${tipAt}: ${d.atTip.failures.length} failing: ` + shown.join("; ") + (more > 0 ? `; \u2026 and ${more} more` : "") : notEvaluated !== null ? `${tipAt}: not evaluated (${notEvaluated})` : `${tipAt}: holds`;
30648
30654
  const tipRest = d.atTip.failures.length > 0 && notEvaluated !== null ? [`${tipAt}, the rest was not evaluated (${notEvaluated})`] : [];
30649
30655
  const open7 = notComputedLines(d.atTip.uncomputed, atTip);
30650
- const rung = d.rung === void 0 ? [] : [` on approval, in force at ${d.rung.means}`];
30656
+ const rung = d.rung === void 0 ? [] : [` in force at ${d.rung.means}`];
30651
30657
  if (typeof d.gated === "string") return [` ${d.statement}`, ` gated: ${d.gated} This definition is not evaluated.`, ...rung, ` conflicts: ${d.conflicts}`].join("\n");
30652
30658
  return [` ${d.statement}`, ...exampleLines(d.examples), ` history: ${history}`, ...floor, tip, ...tipRest, ...open7, ...rung, ` conflicts: ${d.conflicts}`].join("\n");
30653
30659
  }
@@ -30773,7 +30779,7 @@ var seedBody = external_exports.discriminatedUnion("status", [
30773
30779
  })),
30774
30780
  rejectedCandidates: external_exports.number(),
30775
30781
  gateErrorDistribution: external_exports.record(external_exports.number()),
30776
- admittedDefaulted: external_exports.array(external_exports.object({ name: external_exports.string(), definitionId: external_exports.string(), conceptId: external_exports.string() })),
30782
+ admitted: external_exports.array(external_exports.object({ name: external_exports.string(), definitionId: external_exports.string(), conceptId: external_exports.string() })),
30777
30783
  routedContested: external_exports.array(external_exports.object({
30778
30784
  name: external_exports.string(),
30779
30785
  definitionId: external_exports.string(),
@@ -30794,11 +30800,8 @@ var input2 = external_exports.object({
30794
30800
  source: external_exports.record(external_exports.unknown()).optional(),
30795
30801
  nlIntent: external_exports.string().min(1).optional(),
30796
30802
  createdBy: external_exports.string().min(1).optional(),
30797
- // OPTIONAL IN THE SCHEMA, MANDATORY IN EFFECT ON `source` (the shape `invoke-define-admit-route.ts`
30798
- // takes): the `source` arm's admission is `authored`, and Core refuses a blank basis with a typed
30799
- // MISSING_BASIS carrying its repair hint. Declaring it required here would trade that named
30800
- // refusal for a Zod 400 with nothing to act on, and the `dry_run`/`mine` arms need none. The
30801
- // `nlIntent` arm forwards it when given and otherwise cites its own sentence.
30803
+ // Optional on every arm: a citation is recorded as the version's history and nothing routes on it.
30804
+ // The `nlIntent` arm forwards it when given and otherwise cites its own sentence.
30802
30805
  basis: external_exports.string().min(1).optional(),
30803
30806
  dry_run: external_exports.boolean().optional(),
30804
30807
  mine: external_exports.object({
@@ -30816,7 +30819,7 @@ var input2 = external_exports.object({
30816
30819
  });
30817
30820
  var defineTool = {
30818
30821
  name: "define",
30819
- description: "Write a definition into this tenant's governing corpus. Pass exactly one of `source` (the SDL definition object \u2014 deterministic, no LLM) or `nlIntent` (a natural-language note: your own agent decomposes it into slices by pull \u2014 the first call answers with the task to pull, then re-issue the same call unchanged \u2014 and each slice is authored through the CEGIS loop), plus `repo` (org-qualified) and optional `commit` (defaults to resolved tip). Pass `basis` on either arm: free text citing what the definition stood on \u2014 the source doc plus its section (there is no fixed vocabulary), or `capture-note:<id>` for a captured note, which also marks that note formalized. It is required in effect with `source`; an admission that cites nothing is refused. With `nlIntent` it defaults to the note, with the slice number appended. Authoring answers within about 45 s; if it is still queued or iterating it returns a job id: call `define` again with `authorJobId` to read it. An admission of `source` answers the same way: a job id still running is read with `admitJobId`, and a `dry_run` still running with `compileJobId`. `dry_run: true` with `source` validates against the live graph and admits NOTHING, returning per-gate errors with repair hints. `dry_run: true` with `source` and no `repo` answers only whether the language can say it (bind, capability and strength are deferred until a repo is named). `mine: {repo}` submits a whole-repo candidate mining pass instead (async \u2014 poll with `mine: {jobId}`). New versions land defaulted until approved. `gap: { construct, witness, issue }` records a construct the language cannot say yet (witness is the file:line that needed it) and admits nothing.",
30822
+ description: "Write a definition into this tenant's governing corpus. Pass exactly one of `source` (the SDL definition object \u2014 deterministic, no LLM) or `nlIntent` (a natural-language note: your own agent decomposes it into slices by pull \u2014 the first call answers with the task to pull, then re-issue the same call unchanged \u2014 and each slice is authored through the CEGIS loop), plus `repo` (org-qualified) and optional `commit` (defaults to resolved tip). Pass `basis` on either arm: free text citing what the definition stood on \u2014 the source doc plus its section (there is no fixed vocabulary), or `capture-note:<id>` for a captured note, which also marks that note formalized. It is kept as the version's history. With `nlIntent` it defaults to the note, with the slice number appended. Authoring answers within about 45 s; if it is still queued or iterating it returns a job id: call `define` again with `authorJobId` to read it. An admission of `source` answers the same way: a job id still running is read with `admitJobId`, and a `dry_run` still running with `compileJobId`. `dry_run: true` with `source` validates against the live graph and admits NOTHING, returning per-gate errors with repair hints. `dry_run: true` with `source` and no `repo` answers only whether the language can say it (bind, capability and strength are deferred until a repo is named). `mine: {repo}` submits a whole-repo candidate mining pass instead (async \u2014 poll with `mine: {jobId}`). `gap: { construct, witness, issue }` records a construct the language cannot say yet (witness is the file:line that needed it) and admits nothing.",
30820
30823
  capability: "define",
30821
30824
  inputSchema: input2.shape,
30822
30825
  async handler(raw, ctx) {
@@ -30961,7 +30964,7 @@ function renderSlice(r) {
30961
30964
  const rungs = r.rungs === void 0 || r.rungs.length === 0 ? "" : `
30962
30965
  Model calls: ${rungLine(r.rungs)}`;
30963
30966
  if (r.ok) {
30964
- const head = `admitted definition ${r.definitionId} v${r.version} in ${r.iterations} iteration(s). Clover: ${r.clover.agreeCount} agreeing${r.clover.agreed ? "" : " \u2014 no consensus"}. It is defaulted until approved.`;
30967
+ const head = `admitted definition ${r.definitionId} v${r.version} in ${r.iterations} iteration(s). Clover: ${r.clover.agreeCount} agreeing${r.clover.agreed ? "" : " \u2014 no consensus"}.`;
30965
30968
  return (r.draft === void 0 ? head : `${head}
30966
30969
  ${renderDraft(r.draft)}`) + rungs;
30967
30970
  }
@@ -31007,8 +31010,7 @@ function renderAdmit(r) {
31007
31010
  return r.status === "running" ? `define: admission job ${r.jobId} is still running (the gates and the first verdict). Call define with admitJobId: "${r.jobId}" to read it.` : `define: admission job ${r.jobId} failed: ${r.error}`;
31008
31011
  }
31009
31012
  if (r.ok) {
31010
- const standing = r.changeClass === "strengthen" ? "carries its predecessor's standing forward" : r.changeClass === "initial" ? "defaulted until approved" : "re-enters review (defaulted until approved)";
31011
- const head = `define: admitted ${r.definitionId} v${r.version} [${r.changeClass}] \u2014 ${standing}.`;
31013
+ const head = `define: admitted ${r.definitionId} v${r.version} [${r.changeClass}].`;
31012
31014
  return r.draft === void 0 ? head : `${head}
31013
31015
  ${renderDraft(r.draft)}`;
31014
31016
  }
@@ -31030,7 +31032,7 @@ ${renderSummary(r.summary)}`;
31030
31032
  }
31031
31033
  function renderSummary(s) {
31032
31034
  const lines = [
31033
- `Mined ${s.candidatesMined} candidate(s): ${s.admittedDefaulted.length} admitted (defaulted), ${s.routedContested.length} contested, ${s.rejectedCandidates} rejected, ${s.droppedRedundant.count} redundant, ${s.discardedUnsupported.length} unsupported.`
31035
+ `Mined ${s.candidatesMined} candidate(s): ${s.admitted.length} admitted, ${s.routedContested.length} contested, ${s.rejectedCandidates} rejected, ${s.droppedRedundant.count} redundant, ${s.discardedUnsupported.length} unsupported.`
31034
31036
  ];
31035
31037
  if (s.discardedUnsupported.length > 0) {
31036
31038
  lines.push("Discarded by measurement (support vs exceptions against the live graph):");
@@ -31038,9 +31040,9 @@ function renderSummary(s) {
31038
31040
  lines.push(` \u2022 ${d.name} \u2014 ${d.reason}: support ${d.support}, exceptions ${d.exceptions} (${d.grain} grain)`);
31039
31041
  }
31040
31042
  }
31041
- if (s.admittedDefaulted.length > 0) {
31042
- lines.push("Admitted (defaulted \u2014 approve to promote):");
31043
- for (const a of s.admittedDefaulted) lines.push(` \u2022 ${a.name} (${a.definitionId})`);
31043
+ if (s.admitted.length > 0) {
31044
+ lines.push("Admitted:");
31045
+ for (const a of s.admitted) lines.push(` \u2022 ${a.name} (${a.definitionId})`);
31044
31046
  }
31045
31047
  if (s.routedContested.length > 0) {
31046
31048
  lines.push("Contested (in the decision queue):");
@@ -31296,12 +31298,7 @@ var input3 = external_exports.object({
31296
31298
  definitionId: external_exports.string().uuid().optional(),
31297
31299
  repo: external_exports.string().min(1).optional(),
31298
31300
  status: external_exports.enum(["active", "contested", "abandoned", "superseded"]).optional(),
31299
- // F6d discovery (ruling 2026-08-02). Seeded/defaulted definitions are deliberately NOT pushed
31300
- // into the drift backlog, so they have to be FINDABLE: by standing (`versionStatus: 'defaulted'`
31301
- // is the un-affirmed corpus), by how they got here (`provenance`), and by area
31302
- // (`locationPrefix`). Dashboard-mode filters; meaningless beside `definitionId`.
31303
- versionStatus: external_exports.enum(["defaulted", "ratified", "corrected"]).optional(),
31304
- provenance: external_exports.enum(["authored", "mined", "witness-derived"]).optional(),
31301
+ // Findable by area (`locationPrefix`). Dashboard-mode filter; meaningless beside `definitionId`.
31305
31302
  locationPrefix: external_exports.string().min(1).optional(),
31306
31303
  // The practice library (direction/define/language.md §9.6): a search over product content, never
31307
31304
  // over this tenant's definitions, so it is an arm of its own and takes no other field beside it.
@@ -31312,13 +31309,8 @@ var statusBody = external_exports.object({
31312
31309
  definitionId: external_exports.string(),
31313
31310
  name: external_exports.string(),
31314
31311
  class: external_exports.string(),
31315
- versionStatus: external_exports.string(),
31316
31312
  epistemicStatus: external_exports.string(),
31317
- currentVersion: external_exports.number(),
31318
- ratifiedBy: external_exports.string().nullable(),
31319
- ratifiedAt: external_exports.string().nullable(),
31320
- ratifiedBasis: external_exports.string().nullable(),
31321
- ratifiedActorKind: external_exports.string().nullable()
31313
+ currentVersion: external_exports.number()
31322
31314
  })),
31323
31315
  driftBacklog: external_exports.array(external_exports.object({
31324
31316
  driftEventId: external_exports.string(),
@@ -31335,8 +31327,6 @@ var statusBody = external_exports.object({
31335
31327
  });
31336
31328
  var showVersion = external_exports.object({
31337
31329
  version: external_exports.number(),
31338
- status: external_exports.string(),
31339
- provenance: external_exports.string(),
31340
31330
  changeClass: external_exports.string(),
31341
31331
  class: external_exports.string(),
31342
31332
  modality: external_exports.string(),
@@ -31347,10 +31337,6 @@ var showVersion = external_exports.object({
31347
31337
  // such, while an absent field is a wire skew — without this it would render as "absent
31348
31338
  // (pre-#911)" for a version that has an envelope.
31349
31339
  authoredEnvelope: external_exports.unknown().refine((v) => v !== void 0, { message: "Required" }),
31350
- ratifiedBy: external_exports.string().nullable(),
31351
- ratifiedAt: external_exports.string().nullable(),
31352
- ratifiedBasis: external_exports.string().nullable(),
31353
- ratifiedActorKind: external_exports.string().nullable(),
31354
31340
  witnesses: external_exports.object({ corroboration: external_exports.number(), pinned: external_exports.number(), counterexample: external_exports.number() })
31355
31341
  });
31356
31342
  var showViolation = external_exports.object({
@@ -31396,7 +31382,7 @@ var showBody = external_exports.discriminatedUnion("ok", [
31396
31382
  ]);
31397
31383
  var showTool = {
31398
31384
  name: "show",
31399
- description: 'Show this tenant\'s definitions. With `definitionId`: ONE definition as a coherent object \u2014 every version with its status and provenance, the approval stamp, subject bindings, standing violations, live suppressions, and banked witnesses. Without: the corpus dashboard (admitted definitions, the open drift backlog, corpus size + evaluation staleness), optionally filtered by `repo`, epistemic `status`, `versionStatus` (use `defaulted` to see the un-affirmed definitions), `provenance`, or `locationPrefix` (e.g. `app/src/billing/`). With `practice` (words, e.g. "one integration point for an external API" or "least privilege"): the practice library \u2014 how to state a coding best practice as definitions on your code\'s concepts, with the plain sentences to enter through `define`.',
31385
+ description: 'Show this tenant\'s definitions. With `definitionId`: ONE definition as a coherent object \u2014 every version with its change class, subject bindings, standing violations, live suppressions, and banked witnesses. Without: the corpus dashboard (admitted definitions, the open drift backlog, corpus size + evaluation staleness), optionally filtered by `repo`, epistemic `status`, or `locationPrefix` (e.g. `app/src/billing/`). With `practice` (words, e.g. "one integration point for an external API" or "least privilege"): the practice library \u2014 how to state a coding best practice as definitions on your code\'s concepts, with the plain sentences to enter through `define`.',
31400
31386
  capability: "define",
31401
31387
  inputSchema: input3.shape,
31402
31388
  async handler(raw, ctx) {
@@ -31474,13 +31460,7 @@ function json(value) {
31474
31460
  }
31475
31461
  function versionLines(v, currentVersion) {
31476
31462
  const current = v.version === currentVersion ? " \u2190 current" : "";
31477
- const lines = [` \u2022 v${v.version}#${v.canonicalHash.slice(0, 12)} [${v.class}/${v.modality}/${v.status}] ${v.provenance}, ${v.changeClass}${current}`];
31478
- if (v.ratifiedBy !== null) {
31479
- const kind = v.ratifiedActorKind === null ? "" : ` (${v.ratifiedActorKind})`;
31480
- const when = v.ratifiedAt === null ? "" : ` on ${v.ratifiedAt}`;
31481
- const basis = v.ratifiedBasis === null ? "" : ` \u2014 basis: ${v.ratifiedBasis}`;
31482
- lines.push(` approved by ${v.ratifiedBy}${kind}${when}${basis}`);
31483
- }
31463
+ const lines = [` \u2022 v${v.version}#${v.canonicalHash.slice(0, 12)} [${v.class}/${v.modality}] ${v.changeClass}${current}`];
31484
31464
  const w = v.witnesses;
31485
31465
  const banked = w.corroboration + w.pinned + w.counterexample;
31486
31466
  if (banked > 0) {
@@ -31517,13 +31497,7 @@ Definitions:
31517
31497
  ${defs}${queue}`;
31518
31498
  }
31519
31499
  function renderDefinition(d) {
31520
- const line = ` \u2022 ${d.name} [${d.class}/${d.versionStatus}] v${d.currentVersion} (${d.definitionId})`;
31521
- if (d.ratifiedBy === null) return line;
31522
- const kind = d.ratifiedActorKind === null ? "" : ` (${d.ratifiedActorKind})`;
31523
- const when = d.ratifiedAt === null ? "" : ` on ${d.ratifiedAt}`;
31524
- const basis = d.ratifiedBasis === null ? "" : ` \u2014 basis: ${d.ratifiedBasis}`;
31525
- return `${line}
31526
- approved by ${d.ratifiedBy}${kind}${when}${basis}`;
31500
+ return ` \u2022 ${d.name} [${d.class}] v${d.currentVersion} (${d.definitionId})`;
31527
31501
  }
31528
31502
  function renderBacklogItem(q) {
31529
31503
  const line = ` \u2022 ${q.kind}: ${q.definitionName} (drift ${q.driftEventId})`;
@@ -31548,7 +31522,6 @@ var conformanceBody = external_exports.object({
31548
31522
  canonicalHash: external_exports.string(),
31549
31523
  class: external_exports.string(),
31550
31524
  modality: external_exports.string(),
31551
- versionStatus: external_exports.string(),
31552
31525
  verdict: external_exports.string(),
31553
31526
  reason: external_exports.string().optional(),
31554
31527
  witness: external_exports.object({
@@ -31591,7 +31564,7 @@ var generationBody = external_exports.object({
31591
31564
  planned: external_exports.number(),
31592
31565
  cached: external_exports.number(),
31593
31566
  witnessesStored: external_exports.number(),
31594
- kinds: external_exports.object({ corroboration: external_exports.number(), pinned: external_exports.number(), counterexample: external_exports.number() }),
31567
+ kinds: external_exports.object({ corroboration: external_exports.number(), counterexample: external_exports.number() }),
31595
31568
  partitions: external_exports.object({
31596
31569
  hit: external_exports.array(external_exports.string()),
31597
31570
  skipped: external_exports.array(external_exports.object({ key: external_exports.string(), reason: external_exports.string() }))
@@ -31607,7 +31580,7 @@ var input4 = external_exports.object({
31607
31580
  });
31608
31581
  var evalTool = {
31609
31582
  name: "eval",
31610
- description: "Evaluate definitions against a repo's code as-built. With `definitionIds`: verdicts for those definitions, plus generated-and-executed behavioral checks (banked witnesses) where applicable. Without: the whole admitted corpus. Provide `repo` and optional `commit` (defaults to resolved tip). Returns conformant/violated/unevaluable per definition; violations carry a witness. Approved (store: ratified) MUST/MUST-NEVER violations are blocking. A pass that is still evaluating answers a job id: call again with `conformanceJobId` to read it.",
31583
+ description: "Evaluate definitions against a repo's code as-built. With `definitionIds`: verdicts for those definitions, plus generated-and-executed behavioral checks (banked witnesses) where applicable. Without: the whole admitted corpus. Provide `repo` and optional `commit` (defaults to resolved tip). Returns conformant/violated/unevaluable per definition; violations carry a witness. MUST/MUST-NEVER violations are blocking. A pass that is still evaluating answers a job id: call again with `conformanceJobId` to read it.",
31611
31584
  capability: "define",
31612
31585
  inputSchema: input4.shape,
31613
31586
  async handler(raw, ctx) {
@@ -31652,9 +31625,6 @@ var evalTool = {
31652
31625
  function isHard(e) {
31653
31626
  return e.modality === "MUST" || e.modality === "MUST-NEVER";
31654
31627
  }
31655
- function isCertified(e) {
31656
- return e.versionStatus === "ratified" || e.versionStatus === "corrected";
31657
- }
31658
31628
  function witnessOf(e) {
31659
31629
  const f = e.witness?.structuralFacts;
31660
31630
  if (f !== void 0) return ` \u2014 concept is kind=${f.kind}, name=${f.name} at ${f.location}`;
@@ -31695,7 +31665,7 @@ function successorStamp(e) {
31695
31665
  return e.evaluatedOnSuccessor !== void 0 ? ` {evaluated on ${e.evaluatedOnSuccessor.name} at ${e.evaluatedOnSuccessor.location}}` : "";
31696
31666
  }
31697
31667
  function violationLine(e) {
31698
- return [` \u2022 ${e.name}${versionStamp(e)} [${e.modality}/${e.versionStatus}]${grainStamp(e)}${successorStamp(e)}${witnessOf(e)}`, ...witnessDetailLines(e)];
31668
+ return [` \u2022 ${e.name}${versionStamp(e)} [${e.modality}]${grainStamp(e)}${successorStamp(e)}${witnessOf(e)}`, ...witnessDetailLines(e)];
31699
31669
  }
31700
31670
  function violationLines2(entries) {
31701
31671
  return entries.flatMap(violationLine);
@@ -31707,7 +31677,7 @@ function suppressedLine(e) {
31707
31677
  const sup = e.suppression;
31708
31678
  if (sup === void 0) return violationLine(e);
31709
31679
  return [
31710
- ` \u2022 ${e.name}${versionStamp(e)} [${e.modality}/${e.versionStatus}]${grainStamp(e)}${successorStamp(e)} \u2014 violated, suppressed until ${sup.expiresAt} by ${sup.attributedTo}: ${sup.reason}${witnessOf(e)}`,
31680
+ ` \u2022 ${e.name}${versionStamp(e)} [${e.modality}]${grainStamp(e)}${successorStamp(e)} \u2014 violated, suppressed until ${sup.expiresAt} by ${sup.attributedTo}: ${sup.reason}${witnessOf(e)}`,
31711
31681
  ...witnessDetailLines(e)
31712
31682
  ];
31713
31683
  }
@@ -31721,14 +31691,12 @@ function guaranteeLine() {
31721
31691
  function laneLines(entries, behavioralHeader) {
31722
31692
  const violated = entries.filter((e) => e.verdict === "violated");
31723
31693
  const suppressed = violated.filter(isSuppressed);
31724
- const blocking = violated.filter((e) => isHard(e) && isCertified(e) && !isSuppressed(e));
31725
- const approvalQuestions = violated.filter((e) => isHard(e) && e.versionStatus === "defaulted" && !isSuppressed(e));
31694
+ const blocking = violated.filter((e) => isHard(e) && !isSuppressed(e));
31726
31695
  const shoulds = violated.filter((e) => e.modality === "SHOULD" && !isSuppressed(e));
31727
31696
  const unevaluable = entries.filter((e) => e.verdict === "unevaluable");
31728
31697
  const behavioral = entries.filter((e) => e.verdict === "static-unevaluable");
31729
31698
  const out2 = [];
31730
- if (blocking.length > 0) out2.push("\nBLOCKING \u2014 approved (store: ratified) MUST/MUST-NEVER violations:", ...violationLines2(blocking));
31731
- if (approvalQuestions.length > 0) out2.push("\nApprove or correct? \u2014 defaulted violations:", ...violationLines2(approvalQuestions));
31699
+ if (blocking.length > 0) out2.push("\nBLOCKING \u2014 MUST/MUST-NEVER violations:", ...violationLines2(blocking));
31732
31700
  if (shoulds.length > 0) out2.push("\nSHOULD reports:", ...violationLines2(shoulds));
31733
31701
  if (suppressed.length > 0) out2.push("\nSuppressed \u2014 still violated, not blocking (expiring):", ...suppressed.flatMap(suppressedLine));
31734
31702
  if (unevaluable.length > 0) out2.push("\nUnevaluable (no fact backing):", ...unevaluable.map((e) => ` \u2022 ${e.name}${versionStamp(e)}: ${e.reason ?? "no reason given"}`));
@@ -31775,18 +31743,13 @@ function renderGeneration(r) {
31775
31743
  lines.push("No witnesses banked this run.");
31776
31744
  } else {
31777
31745
  lines.push(
31778
- `Witnesses banked (${r.witnessesStored}): ${r.kinds.corroboration} corroboration, ${r.kinds.pinned} pinned, ${r.kinds.counterexample} counterexample.`
31746
+ `Witnesses banked (${r.witnessesStored}): ${r.kinds.corroboration} corroboration, ${r.kinds.counterexample} counterexample.`
31779
31747
  );
31780
31748
  if (r.kinds.counterexample > 0) {
31781
31749
  lines.push(
31782
31750
  ` ! ${r.kinds.counterexample} COUNTEREXAMPLE(S): the code as-built contradicts the definition's own claim. Either the code is wrong or the definition is \u2014 this is not a passing run.`
31783
31751
  );
31784
31752
  }
31785
- if (r.kinds.pinned > 0) {
31786
- lines.push(
31787
- ` \xB7 ${r.kinds.pinned} pinned: these came from DEFAULTED definitions, so they pin current behavior rather than certify an approved intent. Approve the definitions to promote them to corroboration.`
31788
- );
31789
- }
31790
31753
  }
31791
31754
  if (r.partitions.hit.length > 0) {
31792
31755
  lines.push(`Checked partitions (${r.partitions.hit.length}):`);
@@ -31809,13 +31772,6 @@ var repinObserved = external_exports.object({
31809
31772
  observations: external_exports.array(external_exports.object({ kind: external_exports.enum(["return", "raise"]), value: external_exports.unknown() }))
31810
31773
  });
31811
31774
  var ratifyBody = external_exports.discriminatedUnion("kind", [
31812
- external_exports.object({
31813
- kind: external_exports.literal("ratify-version"),
31814
- result: external_exports.discriminatedUnion("ok", [
31815
- external_exports.object({ ok: external_exports.literal(true), definitionId: external_exports.string(), version: external_exports.number(), status: external_exports.enum(["ratified", "corrected"]) }),
31816
- refusal(["not-found", "not-defaulted", "missing-ratifier", "missing-basis", "ratifier-mismatch"])
31817
- ])
31818
- }),
31819
31775
  external_exports.object({
31820
31776
  kind: external_exports.literal("resolve-drift-item"),
31821
31777
  result: external_exports.discriminatedUnion("ok", [external_exports.object({ ok: external_exports.literal(true) }), refusal(["not-found", "already-resolved"])])
@@ -31856,21 +31812,8 @@ var ratifyBody = external_exports.discriminatedUnion("kind", [
31856
31812
  })
31857
31813
  ]);
31858
31814
  var input5 = external_exports.object({
31859
- kind: external_exports.enum(["ratify-version", "resolve-drift-item", "supersede", "suppress", "unsuppress", "repin-witness"]),
31815
+ kind: external_exports.enum(["resolve-drift-item", "supersede", "suppress", "unsuppress", "repin-witness"]),
31860
31816
  definitionId: external_exports.string().min(1).optional(),
31861
- version: external_exports.number().int().optional(),
31862
- status: external_exports.enum(["ratified", "corrected"]).optional(),
31863
- // A4 + CL-E/F2. Optional because the gateway ALWAYS stamps the authenticated caller; passing it
31864
- // is only allowed as a restatement of who you already are, and passing anybody else's name is
31865
- // refused (`ratifier-mismatch`) rather than honoured. What it never does is go unrecorded.
31866
- ratifiedBy: external_exports.string().min(1).optional(),
31867
- // What the approval was judged against. Unnamed, it is the version's provenance basis (for a
31868
- // drafted note, the note), so approving a draft asks for nothing beyond the approval.
31869
- ratifiedBasis: external_exports.string().min(1).optional(),
31870
- // NO `ratifiedActorKind` (CL-F, operator direction 2026-08-05 on PR #96). The store records what
31871
- // was OBSERVED about a ratifier, never what a caller declares itself to be, so there is nothing
31872
- // for a caller to pass. `z.object` strips unknown keys, so a caller that sends one anyway is
31873
- // silently ignored here and it never reaches the gateway or the column.
31874
31817
  driftEventId: external_exports.string().min(1).optional(),
31875
31818
  resolvedBy: external_exports.string().min(1).optional(),
31876
31819
  anchorConceptId: external_exports.string().min(1).optional(),
@@ -31883,7 +31826,7 @@ var input5 = external_exports.object({
31883
31826
  });
31884
31827
  var defineRatifyTool = {
31885
31828
  name: "define_ratify",
31886
- description: "Ratify/retire the overlay. kind `ratify-version` needs {definitionId, version, status: ratified|corrected} and promotes a defaulted version (approving a draft). EVERY promotion is stamped: ratifiedBasis (optional) is what you judged it AGAINST, and when omitted it is what the version was drafted from (its note). You do NOT state what kind of actor you are and there is no field for it \u2014 the record holds what was observed about the ratifier, never a self-description. Your name and the moment are recorded automatically; ratifiedBy is optional and may only restate your own principal. The promotion is refused outright, by name, if any part of the stamp is missing. kind `resolve-drift-item` needs {driftEventId} (+ optional resolvedBy) and acknowledges a drift-backlog item. kind `supersede` needs {definitionId} and retires a definition from the active corpus. kind `suppress` needs {definitionId, anchorConceptId, attributedTo, reason, expiresAt} and marks a violation non-blocking until that date \u2014 it does NOT make it conformant, and there is no permanent suppression: past the date the violation blocks again and lands in the drift backlog. kind `unsuppress` needs {suppressionId, reason} (+ optional revokedBy, defaults to you) and REVOKES a suppression before its date \u2014 the violation blocks again on the next conformance run, and the revocation is recorded in the drift backlog with who/why. Extending a suppression is unsuppress then suppress, two explicit acts; there is no second live suppression per target. kind `repin-witness` needs {ledgerRowId} and reports the outcome of repinning a ledger-row witness; it returns whether the witness stands on the current determinant, or refuses with a reason when it cannot \u2014 row-not-found, not-witness-determinant, witness-absent, or not-pinnable.",
31829
+ description: "Close out the overlay. kind `resolve-drift-item` needs {driftEventId} (+ optional resolvedBy) and acknowledges a drift-backlog item. kind `supersede` needs {definitionId} and retires a definition from the active corpus. kind `suppress` needs {definitionId, anchorConceptId, attributedTo, reason, expiresAt} and marks a violation non-blocking until that date \u2014 it does NOT make it conformant, and there is no permanent suppression: past the date the violation blocks again and lands in the drift backlog. kind `unsuppress` needs {suppressionId, reason} (+ optional revokedBy, defaults to you) and REVOKES a suppression before its date \u2014 the violation blocks again on the next conformance run, and the revocation is recorded in the drift backlog with who/why. Extending a suppression is unsuppress then suppress, two explicit acts; there is no second live suppression per target. kind `repin-witness` needs {ledgerRowId} and reports the outcome of repinning a ledger-row witness; it returns whether the witness stands on the current determinant, or refuses with a reason when it cannot \u2014 row-not-found, not-witness-determinant, witness-absent, or not-pinnable.",
31887
31830
  capability: "define",
31888
31831
  inputSchema: input5.shape,
31889
31832
  async handler(raw, ctx) {
@@ -31895,20 +31838,6 @@ var defineRatifyTool = {
31895
31838
  }
31896
31839
  };
31897
31840
  function renderRatify(r) {
31898
- if (r.kind === "ratify-version") {
31899
- if (r.result.ok) return `define_ratify: ${r.result.definitionId} v${r.result.version} is now ${r.result.status}, in force at rung *new code only* (the default): a PR that adds a violation fails its check; violations already on the trunk do not. \`define_config\` sets it to warn or off.`;
31900
- if (r.result.reason === "not-defaulted") return "define_ratify: refused \u2014 that version is not defaulted (already ratified/corrected).";
31901
- if (r.result.reason === "missing-ratifier") {
31902
- return "define_ratify: refused \u2014 the ratification names nobody. Ratifying is an act someone performs, and the record of it is permanent; pass ratifiedBy, or call as an authenticated principal.";
31903
- }
31904
- if (r.result.reason === "missing-basis") {
31905
- return "define_ratify: refused \u2014 this version cites nothing it was drafted from, so there is nothing to say it was judged against. Pass ratifiedBasis (a contract, a docstring, an issue).";
31906
- }
31907
- if (r.result.reason === "ratifier-mismatch") {
31908
- return "define_ratify: refused \u2014 ratifiedBy named somebody other than you. A ratification is a signature, and the signature is the signer; you cannot affirm on another principal's behalf. Drop ratifiedBy (your identity is recorded automatically), or have them ratify.";
31909
- }
31910
- return "define_ratify: refused \u2014 no such definition/version.";
31911
- }
31912
31841
  if (r.kind === "suppress") {
31913
31842
  if (r.result.ok) {
31914
31843
  return `define_ratify: suppressed until ${r.result.expiresAt}. The violation still reads violated \u2014 it is non-blocking until then, and blocks again afterwards.`;
@@ -32012,7 +31941,7 @@ var input6 = external_exports.object({
32012
31941
  });
32013
31942
  var defineInboxTool = {
32014
31943
  name: "define_inbox",
32015
- description: "The decision inbox: everything Define is currently waiting on a human for, open questions first and oldest first. Gathers the drift backlog (every drift kind, including expired and revoked suppressions), refinements that are still defaulted and so need re-review, and failure-ledger snoozes that have run out or are about to. Every line carries the id you act on. Optional `limit` caps the rendered list; the counts always describe the whole answer.",
31944
+ description: "The decision inbox: everything Define is currently waiting on a human for, open questions first and oldest first. Gathers the drift backlog (every drift kind, including expired and revoked suppressions), and failure-ledger snoozes that have run out or are about to. Every line carries the id you act on. Optional `limit` caps the rendered list; the counts always describe the whole answer.",
32016
31945
  capability: "decision",
32017
31946
  inputSchema: input6.shape,
32018
31947
  async handler(raw, ctx) {
@@ -32025,8 +31954,6 @@ var defineInboxTool = {
32025
31954
  };
32026
31955
  var LABELS = {
32027
31956
  drift: "drift",
32028
- draft: "draft",
32029
- "refinement-pending": "refinement",
32030
31957
  "snooze-expired": "snooze expired",
32031
31958
  "snooze-expiring": "snooze due",
32032
31959
  proposal: "proposal"
@@ -32035,15 +31962,6 @@ var HOW = {
32035
31962
  // Both facts held: `item.id` IS the driftEventId this call takes (the wire's own contract for
32036
31963
  // the field). A complete, runnable call.
32037
31964
  drift: (item) => `define_ratify {kind:'resolve-drift-item', driftEventId:'${item.id}'}`,
32038
- // PARTIAL BY NECESSITY, and it says so rather than filling the hole. `item.id` is the
32039
- // definitionId, but `ratify-version` also needs `version` and `status`, and the version is NOT on
32040
- // the wire — it survives only as prose inside `detail` ("… v2 is a weaken refinement …"), and
32041
- // parsing a number back out of a sentence to put it in a tool call is precisely the guessed
32042
- // content the ruling forbids. So the call is named with the id it does hold and the remaining
32043
- // arguments are stated as arguments the caller supplies.
32044
- // A first draft is version 1, so the call is complete.
32045
- draft: (item) => `define_ratify {kind:'ratify-version', definitionId:'${item.id}', version:1, status:'ratified'|'corrected'}`,
32046
- "refinement-pending": (item) => `define_ratify {kind:'ratify-version', definitionId:'${item.id}', version:\u2026, status:'ratified'|'corrected'} \u2014 supply the version shown in this line`,
32047
31965
  // The read shows the alteration, verdict and definition; the adjudication follows it.
32048
31966
  proposal: (item) => `define_proposal_read {taskId:'${item.id}'}, then define_adjudicate {taskId:'${item.id}', decision:'accept'|'reject', reason:\u2026}`
32049
31967
  };
@@ -47431,10 +47349,8 @@ var VerificationQuestionSchema = contractObject({
47431
47349
  presentation: PresentationSchema
47432
47350
  }).readonly();
47433
47351
  var DivergenceKindSchema = external_exports2.enum(["missing", "spurious", "divergent"]);
47434
- var DivergenceInterpretationSchema = external_exports2.enum(["ratify-or-correct", "conformance-violation"]);
47435
47352
  var ConformanceDivergenceSchema = contractObject({
47436
47353
  kind: DivergenceKindSchema,
47437
- interpretation: DivergenceInterpretationSchema,
47438
47354
  presentation: PresentationSchema
47439
47355
  }).readonly();
47440
47356
  var VerificationContextSchema = contractObject({
@@ -47559,7 +47475,6 @@ init_esm_shims();
47559
47475
  init_esm_shims();
47560
47476
  var DEFINITION_CLASSES = ["structural", "relational", "behavioral", "judgment"];
47561
47477
  var MODALITIES = ["MUST", "MUST-NEVER", "SHOULD", "MAY"];
47562
- var VERSION_STATUSES = ["defaulted", "ratified", "corrected"];
47563
47478
  var CONFORMANCE_VERDICTS = ["conformant", "violated", "unevaluable", "static-unevaluable"];
47564
47479
  var CARDINALITY_GRAINS = ["concept", "element"];
47565
47480
  var CONFORMANCE_SCOPES = ["corpus", "cone", "scratch"];
@@ -47590,7 +47505,6 @@ var ConformanceEntrySchema = contractObject({
47590
47505
  canonicalHash: external_exports2.string(),
47591
47506
  class: external_exports2.enum(DEFINITION_CLASSES),
47592
47507
  modality: external_exports2.enum(MODALITIES),
47593
- versionStatus: external_exports2.enum(VERSION_STATUSES),
47594
47508
  verdict: external_exports2.enum(CONFORMANCE_VERDICTS),
47595
47509
  reason: external_exports2.string().optional(),
47596
47510
  witness: ConformanceWitnessSchema.optional(),
@@ -47831,6 +47745,7 @@ var BUILD_REFUSAL_CODES = [
47831
47745
  "origin-moved",
47832
47746
  "overlay-blob-missing",
47833
47747
  "overlay-path-ignored",
47748
+ "path-file-and-directory",
47834
47749
  "path-invalid",
47835
47750
  "repo-name-invalid",
47836
47751
  "repo-not-found",
@@ -47973,28 +47888,26 @@ var BuildRunOutcomeShape = {
47973
47888
  shardPlan: ShardPlanSchema.nullable()
47974
47889
  };
47975
47890
  var LandDefineViolationSchema = contractObject({
47976
- name: external_exports2.string(),
47977
- definitionId: external_exports2.string(),
47978
- versionId: external_exports2.string(),
47979
- modality: external_exports2.string(),
47980
- versionStatus: external_exports2.string(),
47981
- /** The evaluator's own words, or null when the verdict carried none. */
47982
- reason: external_exports2.string().nullable(),
47983
- /** THE PAIRS THAT CARRY IT. The definition name says a boundary was crossed; these say where.
47984
- * Empty when the verdict named none. */
47985
- offendingEdges: external_exports2.array(contractObject({ edge: external_exports2.string(), from: external_exports2.string(), to: external_exports2.string() }))
47891
+ definitionName: external_exports2.string(),
47892
+ path: external_exports2.string(),
47893
+ line: external_exports2.number().int(),
47894
+ /** Why, in the check's words: what the change adds that the definition forbids. */
47895
+ cause: external_exports2.string()
47986
47896
  });
47987
47897
  var LandDefineVerdictSchema = external_exports2.discriminatedUnion("kind", [
47988
47898
  contractObject({
47989
47899
  kind: external_exports2.literal("judged"),
47990
47900
  commit: external_exports2.string(),
47991
- /** What the pass covered, in its own words — a cone pass is a PARTIAL corpus. */
47901
+ /** What the pass covered, in its own words: the definitions the change reaches. */
47992
47902
  coverage: external_exports2.string(),
47993
- verdict: external_exports2.enum(["clean", "violated"]),
47994
- /** The violations that block: ratified MUST / MUST-NEVER, unsuppressed. */
47903
+ /** `undecided`: nothing blocks, but part of the change was not computed. Never read as clean. */
47904
+ verdict: external_exports2.enum(["clean", "violated", "undecided"]),
47905
+ /** The divergences that block, by the check's own rule. */
47995
47906
  violations: external_exports2.array(LandDefineViolationSchema),
47996
- /** Violated but not blocking — soft modality, unratified, or suppressed. */
47907
+ /** Diverged but not blocking (rung `warn` or suppressed). */
47997
47908
  reported: external_exports2.array(LandDefineViolationSchema),
47909
+ /** Where the check could not compute a definition's answer, and why. */
47910
+ uncomputed: external_exports2.array(contractObject({ definitionName: external_exports2.string(), path: external_exports2.string(), reason: external_exports2.string() })),
47998
47911
  /** When Define judged: the served report row's recordedAt, an ISO instant. */
47999
47912
  judgedAt: external_exports2.iso.datetime()
48000
47913
  }),
@@ -48767,7 +48680,7 @@ var workReadTools = createWorkReadToolProviders({ capability: "work" });
48767
48680
  var bundledProviders = [src_default2, src_default, tension_default, ...defineTools, ...decisionTools, ...captureTools, ...buildTools, secureTool, ...workTools, ...workReadTools];
48768
48681
 
48769
48682
  // package.json
48770
- var version2 = "0.4.45";
48683
+ var version2 = "0.4.47";
48771
48684
 
48772
48685
  // src/server.ts
48773
48686
  var SERVER_VERSION = version2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subseam/mcp",
3
- "version": "0.4.45",
3
+ "version": "0.4.47",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {