@intentius/chant-lexicon-fountain 0.45.0 → 0.46.0

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.
@@ -65,6 +65,13 @@ export declare function computeFountainCoverage(specJSON: string | Buffer, surfa
65
65
  export declare function formatSummary(report: FountainCoverageReport): string;
66
66
  export declare function formatVerbose(report: FountainCoverageReport): string;
67
67
  /** Run coverage analysis for the fountain lexicon. */
68
+ /**
69
+ * The offline path behind `coverageReport()` (#1330): the same computation
70
+ * `coverage.test.ts` runs, over the committed spec snapshot and surface
71
+ * baseline. Never `fetchSchemas()` — check-lexicon runs on every PR and must
72
+ * not do network I/O.
73
+ */
74
+ export declare function coverageReportFromSnapshots(basePath?: string): FountainCoverageReport;
68
75
  export declare function analyzeFountainCoverage(opts?: {
69
76
  basePath?: string;
70
77
  verbose?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,uDAAuD;AACvD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQjD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUxD,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yEAAyE;IACzE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC7D;AAOD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,OAAO,EAAE,eAAe,GACvB,sBAAsB,CAkDxB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAGpE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAkCpE;AAED,sDAAsD;AACtD,wBAAsB,uBAAuB,CAAC,IAAI,CAAC,EAAE;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAsBlC"}
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH,uDAAuD;AACvD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQjD,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUxD,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yEAAyE;IACzE,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,8CAA8C;IAC9C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC7D;AAOD,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,OAAO,EAAE,eAAe,GACvB,sBAAsB,CAkDxB;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAGpE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAkCpE;AAED,sDAAsD;AACtD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,sBAAsB,CASrF;AAED,wBAAsB,uBAAuB,CAAC,IAAI,CAAC,EAAE;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAsBlC"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "28dd49dfa56314218e8f0679b05ad176cd7996e751444eb51e6887633c04a4ba",
4
+ "manifest.json": "8537e5940612ea9a51cc42d190619c524e38be641ae6a875bc9bf27d6917e79f",
5
5
  "meta.json": "6666b7a77db9210a329219c6a5e107e5ae8794a34542f7310ce16d9bf95c64f5",
6
6
  "types/index.d.ts": "1dfdcba184fffcf464dac7d1d71ef7abed2ae02a8d638c0de50e0b0317b7eb01",
7
7
  "rules/ftn001-no-secret-literals.ts": "897a4ce1ec790b3c1540d32892603bd33ff4bf30eb6ba4cd2565dee356d4962e",
@@ -17,5 +17,5 @@
17
17
  "skills/chant-fountain-secrets.md": "27e349a91589510a92e518c7d7824a4a322cab5ef242cf5799373a55cbfcd1cd",
18
18
  "skills/chant-fountain-locked-sandboxes.md": "de82f06cb3a08ba6bf3ae45fb9869e21d6da18b9ebe0fc769da8aebaceea7dd1"
19
19
  },
20
- "composite": "b7579f9b30c25525a5424d24868d39e12858de8ea2da23773c3760edca697810"
20
+ "composite": "c6e025975a4ae6d4a79a848081a92da287e26aa85d01f42e63813bc858a22760"
21
21
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fountain",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "Fountain",
6
6
  "specVersion": "v0.3.0"
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAiC,MAAM,0BAA0B,CAAC;AAsB7F;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,aA8I5B,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAiC,MAAM,0BAA0B,CAAC;AAsB7F;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,aAsJ5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-fountain",
3
- "version": "0.45.0",
3
+ "version": "0.46.0",
4
4
  "type": "module",
5
5
  "description": "Fountain lexicon for chant — sandboxed agent environments, vaults, and agents as typed estate",
6
6
  "license": "Apache-2.0",
@@ -50,7 +50,7 @@
50
50
  "bundle": "tsx src/package-cli.ts"
51
51
  },
52
52
  "peerDependencies": {
53
- "@intentius/chant": "^0.45.0",
53
+ "@intentius/chant": "^0.46.0",
54
54
  "typescript": "^5.9.3"
55
55
  },
56
56
  "devDependencies": {
@@ -1,8 +1,15 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it, vi } from "vitest";
2
2
  import { readFileSync } from "fs";
3
3
  import { join, dirname } from "path";
4
4
  import { fileURLToPath } from "url";
5
- import { computeFountainCoverage, formatVerbose, EXCLUDED_KINDS, UNSPECIFIED_ENDPOINTS } from "./coverage";
5
+ import {
6
+ computeFountainCoverage,
7
+ coverageReportFromSnapshots,
8
+ formatVerbose,
9
+ EXCLUDED_KINDS,
10
+ UNSPECIFIED_ENDPOINTS,
11
+ } from "./coverage";
12
+ import { fountainPlugin } from "./plugin";
6
13
  import { fetchSchemas } from "./spec/fetch";
7
14
 
8
15
  const srcDir = dirname(fileURLToPath(import.meta.url));
@@ -63,6 +70,30 @@ describe("fountain coverage", () => {
63
70
  });
64
71
  });
65
72
 
73
+ // chant #1330 — the same accounting, exposed to check-lexicon through the
74
+ // plugin contract. It must agree with the direct computation above and must
75
+ // stay offline: check-lexicon runs on every PR.
76
+ describe("coverageReport plugin contract", () => {
77
+ it("reports no unaccounted kinds over the committed snapshots", async () => {
78
+ const report = await fountainPlugin.coverageReport!();
79
+ expect(report.unaccountedKinds).toEqual([]);
80
+ expect(report.unaccountedKinds).toEqual(
81
+ computeFountainCoverage(spec, surface).unaccountedKinds,
82
+ );
83
+ });
84
+
85
+ it("does no network I/O", async () => {
86
+ const spy = vi.spyOn(globalThis, "fetch");
87
+ try {
88
+ await fountainPlugin.coverageReport!();
89
+ coverageReportFromSnapshots();
90
+ expect(spy).not.toHaveBeenCalled();
91
+ } finally {
92
+ spy.mockRestore();
93
+ }
94
+ });
95
+ });
96
+
66
97
  describe("unspecified upstream endpoints", () => {
67
98
  it("records a decision for every endpoint the spec cannot describe", () => {
68
99
  // The point of the list is the reasoning, not the route string. An entry
package/src/coverage.ts CHANGED
@@ -190,6 +190,23 @@ export function formatVerbose(report: FountainCoverageReport): string {
190
190
  }
191
191
 
192
192
  /** Run coverage analysis for the fountain lexicon. */
193
+ /**
194
+ * The offline path behind `coverageReport()` (#1330): the same computation
195
+ * `coverage.test.ts` runs, over the committed spec snapshot and surface
196
+ * baseline. Never `fetchSchemas()` — check-lexicon runs on every PR and must
197
+ * not do network I/O.
198
+ */
199
+ export function coverageReportFromSnapshots(basePath?: string): FountainCoverageReport {
200
+ const base = basePath ?? dirname(dirname(fileURLToPath(import.meta.url)));
201
+
202
+ const spec = readFileSync(join(base, "src", "spec", "fountain-openapi.snapshot.json"), "utf-8");
203
+ const surface = JSON.parse(
204
+ readFileSync(join(base, "surface.snapshot.json"), "utf-8"),
205
+ ) as SurfaceSnapshot;
206
+
207
+ return computeFountainCoverage(spec, surface);
208
+ }
209
+
193
210
  export async function analyzeFountainCoverage(opts?: {
194
211
  basePath?: string;
195
212
  verbose?: boolean;
package/src/plugin.ts CHANGED
@@ -63,6 +63,14 @@ export const fountainPlugin: LexiconPlugin = {
63
63
 
64
64
  // ── Optional extensions ────────────────────────────────────
65
65
 
66
+ // #1330 — the fact check-lexicon gates on, computed offline from the
67
+ // committed spec snapshot + surface baseline. Never fetchSchemas():
68
+ // check-lexicon runs per-PR, no network.
69
+ async coverageReport(): Promise<{ unaccountedKinds?: string[] }> {
70
+ const { coverageReportFromSnapshots } = await import("./coverage");
71
+ return { unaccountedKinds: coverageReportFromSnapshots().unaccountedKinds };
72
+ },
73
+
66
74
  lintRules() {
67
75
  return rules;
68
76
  },