superbee 0.4.2 → 0.4.3-pre.2

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/superbee.mjs CHANGED
@@ -44,7 +44,7 @@ var __toESM = (mod, isNodeMode, target3) => (target3 = mod != null ? __create(__
44
44
  var define_SUPERBEE_BUILD_IDENTITY_default;
45
45
  var init_define_SUPERBEE_BUILD_IDENTITY = __esm({
46
46
  "<define:__SUPERBEE_BUILD_IDENTITY__>"() {
47
- define_SUPERBEE_BUILD_IDENTITY_default = { schema: "superbee.build-identity.v1", package: { name: "superbee", version: "0.4.2" }, source: { commit: "069a42092f39d8261ccd4322c0dc7ff5488aa2c8", dirty: false }, artifact: { channel: "npm-package" }, compatibility_contracts: { skill: 1, hook: 1, mcp: 1 } };
47
+ define_SUPERBEE_BUILD_IDENTITY_default = { schema: "superbee.build-identity.v1", package: { name: "superbee", version: "0.4.3-pre.2" }, source: { commit: "9a0a564d4096ec7fe51a7f337e7e001542e8e6d5", dirty: false }, artifact: { channel: "npm-package" }, compatibility_contracts: { skill: 1, hook: 1, mcp: 1 } };
48
48
  }
49
49
  });
50
50
 
@@ -4943,6 +4943,12 @@ async function probeSegment(port, candidate, rel, segment) {
4943
4943
  function hasExact(listing, segment) {
4944
4944
  return listing.some((entry) => entry.name === segment);
4945
4945
  }
4946
+ function freshListings(port) {
4947
+ return async (dir) => {
4948
+ const listing = await port.entries(dir);
4949
+ return listing === null ? null : { has: (name) => hasExact(listing, name) };
4950
+ };
4951
+ }
4946
4952
  async function walkExact(port, rootResolved, segments, rel) {
4947
4953
  let parent = rootResolved;
4948
4954
  for (let index2 = 0; index2 < segments.length; index2++) {
@@ -4973,14 +4979,14 @@ async function recordWalk(port, rootResolved, segments, rel) {
4973
4979
  }
4974
4980
  return recorded;
4975
4981
  }
4976
- async function confirmedWalk(port, rootResolved, segments, rel, recorded, handle) {
4982
+ async function confirmedWalk(port, rootResolved, segments, rel, recorded, handle, listings = freshListings(port)) {
4977
4983
  let parent = rootResolved;
4978
4984
  for (let index2 = 0; index2 < segments.length; index2++) {
4979
4985
  const segment = segments[index2];
4980
4986
  const candidate = path2.join(parent, segment);
4981
- const listing = await port.entries(parent);
4987
+ const listing = await listings(parent);
4982
4988
  if (listing === null) return "absent";
4983
- const listed2 = hasExact(listing, segment);
4989
+ const listed2 = listing.has(segment);
4984
4990
  if (handle !== null && index2 === segments.length - 1) {
4985
4991
  const verdict = classifyLeaf({ listed: listed2, probe: await probeSegment(port, candidate, rel, segment), handle });
4986
4992
  if (verdict === "aliased") throw new FilesystemIdentityAliasError(rel, segment);
@@ -5000,13 +5006,15 @@ function countRestart(restarts, rel) {
5000
5006
  return restarts + 1;
5001
5007
  }
5002
5008
  async function observeExact(port, root, rel, read) {
5009
+ return observeWith(port, path2.resolve(root), rel, read, freshListings(port));
5010
+ }
5011
+ async function observeWith(port, rootResolved, rel, read, listings, onExact) {
5003
5012
  const segments = relSegments(rel);
5004
- const rootResolved = path2.resolve(root);
5005
5013
  const target3 = path2.join(rootResolved, ...segments);
5006
5014
  for (let restarts = 0; ; ) {
5007
5015
  const recorded = await recordWalk(port, rootResolved, segments, rel);
5008
5016
  if (recorded === null) return { state: "absent" };
5009
- const verified2 = await confirmedWalk(port, rootResolved, segments, rel, recorded, null);
5017
+ const verified2 = await confirmedWalk(port, rootResolved, segments, rel, recorded, null, listings);
5010
5018
  if (verified2 === "absent") return { state: "absent" };
5011
5019
  if (verified2 === "restart") {
5012
5020
  restarts = countRestart(restarts, rel);
@@ -5028,11 +5036,14 @@ async function observeExact(port, root, rel, read) {
5028
5036
  try {
5029
5037
  value = await read(opened.handle, target3);
5030
5038
  if (value === null) return { state: "absent" };
5031
- verdict = await confirmedWalk(port, rootResolved, segments, rel, recorded, opened);
5039
+ verdict = await confirmedWalk(port, rootResolved, segments, rel, recorded, opened, listings);
5032
5040
  } finally {
5033
5041
  await port.close(opened.handle);
5034
5042
  }
5035
- if (verdict === "exact") return { state: "exact", value };
5043
+ if (verdict === "exact") {
5044
+ onExact?.(recorded, { dev: opened.dev, ino: opened.ino });
5045
+ return { state: "exact", value };
5046
+ }
5036
5047
  if (verdict === "absent") return { state: "absent" };
5037
5048
  restarts = countRestart(restarts, rel);
5038
5049
  }
@@ -5051,6 +5062,99 @@ async function probeExact(port, root, rel) {
5051
5062
  restarts = countRestart(restarts, rel);
5052
5063
  }
5053
5064
  }
5065
+ function witnessKey(witness) {
5066
+ return `${witness.dev}:${witness.ino}:${witness.mtimeNs}:${witness.ctimeNs}`;
5067
+ }
5068
+ function openObservationPass(port, root, now = Date.now) {
5069
+ const rootResolved = path2.resolve(root);
5070
+ const kept = /* @__PURE__ */ new Map();
5071
+ const reusedVerdicts = [];
5072
+ const fresh = freshListings(port);
5073
+ const witnessOf = port.directoryWitness?.bind(port);
5074
+ const settled = (witness) => {
5075
+ const nowNs = BigInt(Math.floor(now())) * 1000000n;
5076
+ const latest = witness.mtimeNs > witness.ctimeNs ? witness.mtimeNs : witness.ctimeNs;
5077
+ return nowNs - latest >= SETTLED_AFTER_NS;
5078
+ };
5079
+ const listingsFor = () => {
5080
+ let reused = false;
5081
+ if (witnessOf === void 0) return { source: fresh, reused: () => false };
5082
+ const source = async (dir) => {
5083
+ const keep = kept.get(dir);
5084
+ if (keep !== void 0) {
5085
+ const current = await witnessOf(dir);
5086
+ if (current !== null && witnessKey(current) === keep.witness) {
5087
+ reused = true;
5088
+ return keep.names;
5089
+ }
5090
+ kept.delete(dir);
5091
+ }
5092
+ const before = await witnessOf(dir);
5093
+ const listing = await port.entries(dir);
5094
+ if (listing === null) return null;
5095
+ const names = new Set(listing.map((entry) => entry.name));
5096
+ const after = await witnessOf(dir);
5097
+ if (before !== null && after !== null && witnessKey(before) === witnessKey(after) && settled(after)) {
5098
+ kept.set(dir, { witness: witnessKey(after), names });
5099
+ }
5100
+ return names;
5101
+ };
5102
+ return { source, reused: () => reused };
5103
+ };
5104
+ return {
5105
+ async observe(rel, read) {
5106
+ const listings = listingsFor();
5107
+ let exact;
5108
+ let observed;
5109
+ try {
5110
+ observed = await observeWith(port, rootResolved, rel, read, listings.source, (recorded, handle) => {
5111
+ exact = { rel, segments: relSegments(rel), recorded, handle };
5112
+ });
5113
+ } catch (error51) {
5114
+ if (!listings.reused()) throw error51;
5115
+ return observeExact(port, rootResolved, rel, read);
5116
+ }
5117
+ if (!listings.reused()) return observed;
5118
+ if (observed.state === "absent") return observeExact(port, rootResolved, rel, read);
5119
+ if (exact !== void 0) reusedVerdicts.push(exact);
5120
+ return observed;
5121
+ },
5122
+ async finish() {
5123
+ const retry = /* @__PURE__ */ new Set();
5124
+ const endListings = /* @__PURE__ */ new Map();
5125
+ const listedAtEnd = async (dir) => {
5126
+ if (!endListings.has(dir)) {
5127
+ const listing = await port.entries(dir);
5128
+ endListings.set(dir, listing === null ? null : new Set(listing.map((entry) => entry.name)));
5129
+ }
5130
+ return endListings.get(dir);
5131
+ };
5132
+ try {
5133
+ for (const verdict of reusedVerdicts) {
5134
+ if (!await holdsAtEnd(port, rootResolved, verdict, listedAtEnd)) retry.add(verdict.rel);
5135
+ }
5136
+ } finally {
5137
+ kept.clear();
5138
+ reusedVerdicts.length = 0;
5139
+ }
5140
+ return [...retry];
5141
+ }
5142
+ };
5143
+ }
5144
+ async function holdsAtEnd(port, rootResolved, verdict, listedAtEnd) {
5145
+ let parent = rootResolved;
5146
+ for (let index2 = 0; index2 < verdict.segments.length; index2++) {
5147
+ const segment = verdict.segments[index2];
5148
+ const listing = await listedAtEnd(parent);
5149
+ if (listing === null || !listing.has(segment)) return false;
5150
+ const candidate = path2.join(parent, segment);
5151
+ const probed = await port.probe(candidate);
5152
+ const expected = index2 === verdict.segments.length - 1 ? verdict.handle : verdict.recorded[index2];
5153
+ if (probed === null || probed.kind === "symlink" || !sameWitness(probed, expected)) return false;
5154
+ parent = candidate;
5155
+ }
5156
+ return true;
5157
+ }
5054
5158
  function unsupportedLinkRoots(port) {
5055
5159
  let roots = linkUnsupportedRoots.get(port);
5056
5160
  if (!roots) {
@@ -5201,8 +5305,28 @@ function kindOf(stats) {
5201
5305
  if (stats.isFile()) return "file";
5202
5306
  return "other";
5203
5307
  }
5308
+ function directoryWitnessTrusted(platform, filesystemType) {
5309
+ if (platform !== "linux") return true;
5310
+ return filesystemType !== null && LOCAL_LINUX_FILESYSTEMS.has(filesystemType);
5311
+ }
5312
+ function witnessTrust() {
5313
+ const devices = /* @__PURE__ */ new Map();
5314
+ return (dev, dir) => {
5315
+ if (process.platform !== "linux") return Promise.resolve(true);
5316
+ let trusted = devices.get(dev);
5317
+ if (trusted === void 0) {
5318
+ trusted = fs2.statfs(dir).then(
5319
+ (info) => directoryWitnessTrusted("linux", Number(info.type)),
5320
+ () => false
5321
+ );
5322
+ devices.set(dev, trusted);
5323
+ }
5324
+ return trusted;
5325
+ };
5326
+ }
5204
5327
  function createNodeFilesystemIdentityPort(hostPolicy) {
5205
5328
  const policy = captureFilesystemHostPolicy(hostPolicy);
5329
+ const witnessTrustedOn = witnessTrust();
5206
5330
  return Object.freeze({
5207
5331
  isTransientOpenError: policy.isTransientOpenError,
5208
5332
  isReplacementConflict: policy.isReplacementConflict,
@@ -5225,6 +5349,17 @@ function createNodeFilesystemIdentityPort(hostPolicy) {
5225
5349
  throw err;
5226
5350
  }
5227
5351
  },
5352
+ async directoryWitness(dir) {
5353
+ let stats;
5354
+ try {
5355
+ stats = await fs2.stat(dir, { bigint: true });
5356
+ } catch (err) {
5357
+ if (isAbsentPathError(err)) return null;
5358
+ throw err;
5359
+ }
5360
+ if (!await witnessTrustedOn(stats.dev, dir)) return null;
5361
+ return { dev: stats.dev, ino: stats.ino, mtimeNs: stats.mtimeNs, ctimeNs: stats.ctimeNs };
5362
+ },
5228
5363
  async open(target3) {
5229
5364
  const handle = await fs2.open(target3, "r");
5230
5365
  try {
@@ -5279,7 +5414,7 @@ function createNodeFilesystemIdentityPort(hostPolicy) {
5279
5414
  }
5280
5415
  });
5281
5416
  }
5282
- var FilesystemSymlinkEntryError, FilesystemShapeMismatchError, ABSENT_PATH_CODES, MAX_RESTARTS, linkUnsupportedRoots, queues, ABSENT_FILE_CODES;
5417
+ var FilesystemSymlinkEntryError, FilesystemShapeMismatchError, ABSENT_PATH_CODES, MAX_RESTARTS, SETTLED_AFTER_NS, linkUnsupportedRoots, queues, ABSENT_FILE_CODES, LOCAL_LINUX_FILESYSTEMS;
5283
5418
  var init_filesystem_identity = __esm({
5284
5419
  "../core/src/filesystem-identity.ts"() {
5285
5420
  "use strict";
@@ -5310,9 +5445,38 @@ var init_filesystem_identity = __esm({
5310
5445
  };
5311
5446
  ABSENT_PATH_CODES = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
5312
5447
  MAX_RESTARTS = 3;
5448
+ SETTLED_AFTER_NS = 3000000000n;
5313
5449
  linkUnsupportedRoots = /* @__PURE__ */ new WeakMap();
5314
5450
  queues = /* @__PURE__ */ new Map();
5315
5451
  ABSENT_FILE_CODES = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR", "EISDIR"]);
5452
+ LOCAL_LINUX_FILESYSTEMS = /* @__PURE__ */ new Set([
5453
+ 61267,
5454
+ // ext2/3/4
5455
+ 1481003842,
5456
+ // xfs
5457
+ 2435016766,
5458
+ // btrfs
5459
+ 16914836,
5460
+ // tmpfs
5461
+ 2240043254,
5462
+ // ramfs
5463
+ 2035054128,
5464
+ // overlayfs
5465
+ 801189825,
5466
+ // zfs
5467
+ 4076150800,
5468
+ // f2fs
5469
+ 3393526350,
5470
+ // bcachefs
5471
+ 19780,
5472
+ // vfat
5473
+ 538032816,
5474
+ // exfat
5475
+ 1936094318,
5476
+ // ntfs3
5477
+ 18475
5478
+ // hfsplus
5479
+ ]);
5316
5480
  }
5317
5481
  });
5318
5482
 
@@ -5627,10 +5791,11 @@ var init_backend = __esm({
5627
5791
  return void 0;
5628
5792
  }
5629
5793
  }
5630
- async #readWithEdition(id, edition) {
5794
+ async #readWithEdition(id, edition, pass) {
5631
5795
  assertSafeConceptId(id);
5632
5796
  const rel = pathFromConceptId(id);
5633
- const observed = await observeExact(this.#port, this.#root, rel, (handle) => readBytes(this.#port, handle));
5797
+ const read = (handle) => readBytes(this.#port, handle);
5798
+ const observed = pass ? await pass.observe(rel, read) : await observeExact(this.#port, this.#root, rel, read);
5634
5799
  if (observed.state === "absent") throw notFound(this.#root, rel);
5635
5800
  const raw = observed.value.toString("utf8");
5636
5801
  const { frontmatter, body } = parseMarkdown(raw, rel, { okfVersion: await edition() });
@@ -5645,7 +5810,12 @@ var init_backend = __esm({
5645
5810
  }
5646
5811
  let editionPromise;
5647
5812
  const edition = () => editionPromise ??= this.#readEdition();
5648
- for (const id of ids) out.push(await this.#readWithEdition(id, edition));
5813
+ const pass = openObservationPass(this.#port, this.#root);
5814
+ for (const id of ids) out.push(await this.#readWithEdition(id, edition, pass));
5815
+ const retry = new Set(await pass.finish());
5816
+ for (let index2 = 0; index2 < ids.length; index2++) {
5817
+ if (retry.has(pathFromConceptId(ids[index2]))) out[index2] = await this.#readWithEdition(ids[index2], edition);
5818
+ }
5649
5819
  return out;
5650
5820
  }
5651
5821
  async write(id, doc2, options = {}) {
@@ -6070,15 +6240,15 @@ function lexicalPosixHookTokens(command) {
6070
6240
  const raw = command.slice(start, i);
6071
6241
  const current = renderGeneratedHookToken(token);
6072
6242
  const historical = renderHistoricalDoubleQuotedHookToken(token);
6073
- const envelope2 = raw === current ? "current" : raw === historical ? "historical_double" : void 0;
6074
- if (!envelope2) return void 0;
6075
- tokens.push({ raw, value: token, envelope: envelope2 });
6243
+ const envelope3 = raw === current ? "current" : raw === historical ? "historical_double" : void 0;
6244
+ if (!envelope3) return void 0;
6245
+ tokens.push({ raw, value: token, envelope: envelope3 });
6076
6246
  if (i < command.length) {
6077
6247
  i += 1;
6078
6248
  if (i === command.length || command[i] === " ") return void 0;
6079
6249
  }
6080
6250
  }
6081
- if (tokens.some(({ envelope: envelope2 }) => envelope2 === "historical_double")) {
6251
+ if (tokens.some(({ envelope: envelope3 }) => envelope3 === "historical_double")) {
6082
6252
  const exactHistoricalCommand = tokens.length === 2 && tokens[0]?.envelope === "historical_double" && tokens[1]?.envelope === "current" && tokens[1]?.raw === "session-start";
6083
6253
  if (!exactHistoricalCommand) return void 0;
6084
6254
  }
@@ -7980,8 +8150,8 @@ function render(value, mode) {
7980
8150
  `;
7981
8151
  }
7982
8152
  }
7983
- function renderErrorEnvelope(envelope2) {
7984
- return `${encode(envelope2)}
8153
+ function renderErrorEnvelope(envelope3) {
8154
+ return `${encode(envelope3)}
7985
8155
  `;
7986
8156
  }
7987
8157
  function renderUsage(usage3) {
@@ -8892,8 +9062,8 @@ function assertValidExpectedVersion(expectedVersion) {
8892
9062
  }
8893
9063
  async function refusesIdentity(res) {
8894
9064
  try {
8895
- const envelope2 = await res.json();
8896
- return envelope2?.error?.code === "USAGE" && envelope2.error.message === IDENTITY_UNSUPPORTED;
9065
+ const envelope3 = await res.json();
9066
+ return envelope3?.error?.code === "USAGE" && envelope3.error.message === IDENTITY_UNSUPPORTED;
8897
9067
  } catch {
8898
9068
  return false;
8899
9069
  }
@@ -8911,8 +9081,8 @@ function etagForm(token) {
8911
9081
  async function namesMalformedDocument(res) {
8912
9082
  if (res.status !== 500) return false;
8913
9083
  try {
8914
- const envelope2 = await res.clone().json();
8915
- return typeof envelope2?.error?.details?.malformed?.reason === "string";
9084
+ const envelope3 = await res.clone().json();
9085
+ return typeof envelope3?.error?.details?.malformed?.reason === "string";
8916
9086
  } catch {
8917
9087
  return false;
8918
9088
  }
@@ -9006,26 +9176,26 @@ var init_remote_backend = __esm({
9006
9176
  }
9007
9177
  /** Parse a non-2xx response into the typed error the engine expects. */
9008
9178
  async toError(res, fallbackId) {
9009
- let envelope2 = null;
9179
+ let envelope3 = null;
9010
9180
  try {
9011
- envelope2 = await res.json();
9181
+ envelope3 = await res.json();
9012
9182
  } catch {
9013
- envelope2 = null;
9183
+ envelope3 = null;
9014
9184
  }
9015
9185
  if (res.status === 412) {
9016
- const expected = envelope2?.error?.details?.expected ?? null;
9017
- const actual = envelope2?.error?.details?.actual ?? null;
9186
+ const expected = envelope3?.error?.details?.expected ?? null;
9187
+ const actual = envelope3?.error?.details?.actual ?? null;
9018
9188
  return new VersionConflict(fallbackId, expected, actual);
9019
9189
  }
9020
- const malformedDoc = envelope2?.error?.details?.malformed;
9190
+ const malformedDoc = envelope3?.error?.details?.malformed;
9021
9191
  if (malformedDoc && typeof malformedDoc.reason === "string") {
9022
9192
  return new MalformedDocumentError(
9023
9193
  typeof malformedDoc.id === "string" ? malformedDoc.id : fallbackId,
9024
9194
  new Error(malformedDoc.reason)
9025
9195
  );
9026
9196
  }
9027
- const message = envelope2?.error?.message ?? `wire request failed with status ${res.status}`;
9028
- const code3 = envelope2?.error?.code ?? (res.status === 401 ? "AUTH_REQUIRED" : res.status >= 500 ? "RUNTIME" : "USAGE");
9197
+ const message = envelope3?.error?.message ?? `wire request failed with status ${res.status}`;
9198
+ const code3 = envelope3?.error?.code ?? (res.status === 401 ? "AUTH_REQUIRED" : res.status >= 500 ? "RUNTIME" : "USAGE");
9029
9199
  return new RemoteError(message, code3, res.status);
9030
9200
  }
9031
9201
  async read(id) {
@@ -9048,8 +9218,8 @@ var init_remote_backend = __esm({
9048
9218
  if (res.status === 404) {
9049
9219
  let missing2 = [];
9050
9220
  try {
9051
- const envelope2 = await res.json();
9052
- missing2 = envelope2.error.details?.missing ?? [];
9221
+ const envelope3 = await res.json();
9222
+ missing2 = envelope3.error.details?.missing ?? [];
9053
9223
  } catch {
9054
9224
  }
9055
9225
  throw notFound3(missing2[0] ?? ids[0]);
@@ -11728,6 +11898,184 @@ var init_governed_body_write = __esm({
11728
11898
  }
11729
11899
  });
11730
11900
 
11901
+ // ../core/src/kind-coverage.ts
11902
+ function bodyProse(body) {
11903
+ let relatedLevel;
11904
+ for (const line2 of body.split("\n")) {
11905
+ const text5 = line2.trim();
11906
+ const heading = /^(#{1,6})[ \t]+(.+?)\s*#*\s*$/.exec(text5);
11907
+ if (heading) {
11908
+ const level2 = heading[1].length;
11909
+ if (relatedLevel !== void 0 && level2 <= relatedLevel) relatedLevel = void 0;
11910
+ if (heading[2].trim().toLowerCase() === "related" && relatedLevel === void 0) relatedLevel = level2;
11911
+ continue;
11912
+ }
11913
+ if (relatedLevel !== void 0) continue;
11914
+ const prose = text5.replace(/^[-*] +/, "");
11915
+ if (!prose) continue;
11916
+ const links = extractMarkdownLinks(prose);
11917
+ if (!(links.length === 1 && prose === `[${links[0].text}](${links[0].href})`)) return true;
11918
+ }
11919
+ return false;
11920
+ }
11921
+ function fieldStats(docs, value) {
11922
+ let present = 0, sentinels = 0, used = 0;
11923
+ for (const doc2 of docs) {
11924
+ const v2 = value(doc2);
11925
+ if (v2 !== void 0) used++;
11926
+ if (filled(v2)) present++;
11927
+ else if (sentinel(v2)) sentinels++;
11928
+ }
11929
+ return { present: used, filled: present, sentinel: sentinels, empty: docs.length - present - sentinels, rate: ratio(present, docs.length) };
11930
+ }
11931
+ function checkedOn(kind2, docs, now) {
11932
+ const buckets = { future: 0, "0-7d": 0, "8-30d": 0, "31-90d": 0, "91-180d": 0, "181-365d": 0, ">365d": 0 };
11933
+ let missing2 = 0, invalid = 0, older = 0;
11934
+ const horizon = freshnessHorizonMs(kind2);
11935
+ for (const doc2 of docs) {
11936
+ const value = doc2.frontmatter.checked_on;
11937
+ if (!filled(value)) {
11938
+ missing2++;
11939
+ continue;
11940
+ }
11941
+ const ms = typeof value === "string" ? parseTimestamp(/^\d{4}-\d{2}-\d{2}$/.test(value) ? `${value}T00:00:00Z` : value, "0.2") : null;
11942
+ if (ms === null) {
11943
+ invalid++;
11944
+ continue;
11945
+ }
11946
+ const ageMs2 = now.getTime() - ms;
11947
+ const days = Math.floor(ageMs2 / DAY);
11948
+ const bucket = days < 0 ? "future" : days <= 7 ? "0-7d" : days <= 30 ? "8-30d" : days <= 90 ? "31-90d" : days <= 180 ? "91-180d" : days <= 365 ? "181-365d" : ">365d";
11949
+ buckets[bucket]++;
11950
+ if (horizon !== void 0 && ageMs2 > horizon) older++;
11951
+ }
11952
+ return { clock: "checked_on", horizon: kind2.freshnessHorizon ?? null, horizon_ms: horizon ?? null, missing: missing2, invalid, buckets, older_than_horizon: horizon === void 0 ? null : older };
11953
+ }
11954
+ function sourceStats(docs) {
11955
+ const domains = /* @__PURE__ */ new Map();
11956
+ const distribution2 = { "0": 0, "1": 0, "2": 0, "3": 0, "4": 0, "5+": 0 };
11957
+ let total = 0, zero2 = 0, invalid = 0, nonUrl = 0;
11958
+ for (const doc2 of docs) {
11959
+ const raw = doc2.frontmatter.sources;
11960
+ const list4 = Array.isArray(raw) ? raw : raw == null ? [] : [raw];
11961
+ let count5 = 0;
11962
+ for (const item of list4) {
11963
+ const resource = typeof item === "string" ? item : item && typeof item === "object" && !Array.isArray(item) ? item.resource : void 0;
11964
+ if (typeof resource !== "string" || !filled(resource)) {
11965
+ invalid++;
11966
+ continue;
11967
+ }
11968
+ count5++;
11969
+ try {
11970
+ const domain3 = new URL(resource).hostname.toLowerCase().replace(/^www\./, "");
11971
+ if (!domain3) {
11972
+ nonUrl++;
11973
+ continue;
11974
+ }
11975
+ domains.set(domain3, (domains.get(domain3) ?? 0) + 1);
11976
+ } catch {
11977
+ nonUrl++;
11978
+ }
11979
+ }
11980
+ if (!count5) zero2++;
11981
+ total += count5;
11982
+ distribution2[count5 >= 5 ? "5+" : String(count5)]++;
11983
+ }
11984
+ const ordered = [...domains].sort((a, b) => b[1] - a[1] || compare(a[0], b[0]));
11985
+ return { zero: zero2, total, invalid_entries: invalid, non_url_resources: nonUrl, per_record: distribution2, distinct_domains: domains.size, domains_shown: Math.min(domains.size, DOMAIN_LIMIT), top_domains: ordered.slice(0, DOMAIN_LIMIT).map(([domain3, sources]) => ({ domain: domain3, sources })) };
11986
+ }
11987
+ function kindCoverage(registry2, documents, options) {
11988
+ if (!Number.isFinite(options.now.getTime())) throw new TypeError("Coverage now must be a valid date");
11989
+ const docs = [...documents].sort((a, b) => compare(a.id, b.id));
11990
+ const index2 = new Map(docs.map((doc2) => [doc2.id, doc2]));
11991
+ const edges = new Map(docs.map((doc2) => [doc2.id, parseLinksFromDoc(doc2)]));
11992
+ const inbound = new Set([...edges.values()].flat().map((link4) => link4.to));
11993
+ const groups = /* @__PURE__ */ new Map();
11994
+ for (const doc2 of docs) {
11995
+ const type = doc2.frontmatter.type;
11996
+ const group = groups.get(type) ?? [];
11997
+ group.push(doc2);
11998
+ groups.set(type, group);
11999
+ }
12000
+ const kinds2 = [...registry2.kinds.values()].filter((kind2) => options.kind === void 0 || kind2.governs === options.kind).map((kind2) => {
12001
+ const records = groups.get(kind2.governs) ?? [];
12002
+ const authoring = projectKindForAuthoring(options.okfVersion, kind2);
12003
+ const fields2 = [.../* @__PURE__ */ new Set([...authoring.fields.required, ...authoring.fields.optional])].sort(compare);
12004
+ const stats = fields2.map((field) => ({ field, required: authoring.fields.required.includes(field), ...fieldStats(records, (doc2) => readKindField(options.okfVersion, kind2, doc2.frontmatter, field)) }));
12005
+ const declaredStorage = new Set(fields2.map((field) => resolveKindFieldCoordinate(options.okfVersion, kind2, field)?.storageField ?? field));
12006
+ const undeclared = /* @__PURE__ */ new Map(), envelopes = /* @__PURE__ */ new Map();
12007
+ for (const doc2 of records) for (const key2 of Object.keys(doc2.frontmatter)) {
12008
+ if (envelope(key2)) {
12009
+ envelopes.set(key2, (envelopes.get(key2) ?? 0) + 1);
12010
+ continue;
12011
+ }
12012
+ if (!declaredStorage.has(key2)) {
12013
+ const ids = undeclared.get(key2) ?? [];
12014
+ ids.push(doc2.id);
12015
+ undeclared.set(key2, ids);
12016
+ }
12017
+ }
12018
+ const relations = /* @__PURE__ */ new Map();
12019
+ let citations = 0, dangling = 0, withLinks = 0;
12020
+ const danglingExamples = [];
12021
+ for (const doc2 of records) {
12022
+ const links = edges.get(doc2.id);
12023
+ if (links.length) withLinks++;
12024
+ for (const link4 of links) {
12025
+ const target3 = index2.get(link4.to);
12026
+ if (!target3) {
12027
+ dangling++;
12028
+ if (danglingExamples.length < EXAMPLES) danglingExamples.push(doc2.id);
12029
+ }
12030
+ if (!Object.hasOwn(kind2.links ?? {}, link4.text)) {
12031
+ citations++;
12032
+ continue;
12033
+ }
12034
+ const targetKind = target3?.frontmatter.type ?? null;
12035
+ const key2 = JSON.stringify([link4.text, targetKind]);
12036
+ const row4 = relations.get(key2) ?? { relation: link4.text, target_kind: targetKind, target_matches: targetKind === null ? null : targetKind === kind2.links[link4.text], records: /* @__PURE__ */ new Set(), links: 0 };
12037
+ row4.records.add(doc2.id);
12038
+ row4.links++;
12039
+ relations.set(key2, row4);
12040
+ }
12041
+ }
12042
+ const used = new Set([...relations.values()].map((row4) => row4.relation));
12043
+ return {
12044
+ governs: kind2.governs,
12045
+ records: records.length,
12046
+ coverage: { fields: stats, body_prose: { filled: records.filter((doc2) => bodyProse(doc2.body)).length, rate: ratio(records.filter((doc2) => bodyProse(doc2.body)).length, records.length) } },
12047
+ drift: { undeclared: [...undeclared].sort(([a], [b]) => compare(a, b)).map(([key2, ids]) => ({ key: key2, records: ids.length, rate: ratio(ids.length, records.length), examples: ids.slice(0, EXAMPLES), examples_total: ids.length })), declared_unused: stats.filter((row4) => row4.present === 0).map((row4) => row4.field), envelope: [...envelopes].sort(([a], [b]) => compare(a, b)).map(([key2, records2]) => ({ key: key2, records: records2 })) },
12048
+ links: { with_links: withLinks, typed: [...relations.values()].sort((a, b) => compare(a.relation, b.relation) || compare(a.target_kind ?? "", b.target_kind ?? "")).map((row4) => ({ relation: row4.relation, target_kind: row4.target_kind, target_matches: row4.target_matches, records: row4.records.size, links: row4.links, rate: ratio(row4.records.size, records.length) })), untyped_citations: citations, declared_never_used: Object.keys(kind2.links ?? {}).filter((relation) => !used.has(relation)).sort(compare), dangling, dangling_examples: danglingExamples, no_inbound: records.filter((doc2) => !inbound.has(doc2.id)).length },
12049
+ freshness: checkedOn(kind2, records, options.now),
12050
+ sources: sourceStats(records)
12051
+ };
12052
+ });
12053
+ return { now: options.now.toISOString(), documents: docs.length, undeclared_kinds: [...groups.keys()].filter((type) => !registry2.kinds.has(type)).sort(compare), kinds: kinds2 };
12054
+ }
12055
+ var SENTINELS, EXAMPLES, DOMAIN_LIMIT, DAY, compare, ratio, empty, sentinel, filled, envelope;
12056
+ var init_kind_coverage = __esm({
12057
+ "../core/src/kind-coverage.ts"() {
12058
+ "use strict";
12059
+ init_define_SUPERBEE_BUILD_IDENTITY();
12060
+ init_define_SUPERBEE_UPDATE_POLICY();
12061
+ init_document_field_actions();
12062
+ init_kinds();
12063
+ init_links();
12064
+ init_managed_document_metadata();
12065
+ init_freshness();
12066
+ SENTINELS = /* @__PURE__ */ new Set(["unknown", "n/a", "na", "none", "tbd", "null", "-", "?"]);
12067
+ EXAMPLES = 3;
12068
+ DOMAIN_LIMIT = 15;
12069
+ DAY = 864e5;
12070
+ compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
12071
+ ratio = (n, total) => total ? Math.round(n / total * 1e4) / 1e4 : null;
12072
+ empty = (value) => value == null || typeof value === "string" && value.trim() === "" || (Array.isArray(value) ? value.length === 0 : typeof value === "object" && Object.keys(value).length === 0);
12073
+ sentinel = (value) => typeof value === "string" && SENTINELS.has(value.trim().toLowerCase());
12074
+ filled = (value) => !empty(value) && !sentinel(value);
12075
+ envelope = (key2) => isManagedDocumentMetadataField(key2) || isStandardDocumentSetField(key2, "0.2") || key2 === "sources" || key2 === "tags";
12076
+ }
12077
+ });
12078
+
11731
12079
  // ../core/src/index.ts
11732
12080
  var init_src = __esm({
11733
12081
  "../core/src/index.ts"() {
@@ -11771,6 +12119,7 @@ var init_src = __esm({
11771
12119
  init_document_mutation();
11772
12120
  init_kind_field_mutation();
11773
12121
  init_managed_document_metadata();
12122
+ init_kind_coverage();
11774
12123
  }
11775
12124
  });
11776
12125
 
@@ -15822,12 +16171,12 @@ function resolveCompatibleScalarEnv(opts) {
15822
16171
  const env = opts.env ?? process.env;
15823
16172
  const present = [opts.canonical, opts.legacy].filter((name) => hasOwn4(env, name)).map((name) => ({ name, value: (env[name] ?? "").trim() }));
15824
16173
  if (!present.length) return void 0;
15825
- const empty2 = present.filter((entry) => entry.value === "");
15826
- if (opts.requireNonEmpty && empty2.length) {
15827
- const sources = empty2.map((entry) => entry.name).join(" and ");
16174
+ const empty3 = present.filter((entry) => entry.value === "");
16175
+ if (opts.requireNonEmpty && empty3.length) {
16176
+ const sources = empty3.map((entry) => entry.name).join(" and ");
15828
16177
  throw new CliError(
15829
16178
  "USAGE",
15830
- `${sources} ${empty2.length === 1 ? "was" : "were"} given an empty value - pass a ${opts.label} or unset the environment variable.`,
16179
+ `${sources} ${empty3.length === 1 ? "was" : "were"} given an empty value - pass a ${opts.label} or unset the environment variable.`,
15831
16180
  opts.help ? { help: opts.help } : {}
15832
16181
  );
15833
16182
  }
@@ -17513,7 +17862,7 @@ var init_command_spec = __esm({
17513
17862
  {
17514
17863
  id: "kinds",
17515
17864
  leaves: [publicLeaf("kinds", "kinds", zero, 14, DIR_SURFACE)],
17516
- usage: "kinds [--dir <path>] [--remote <url>]",
17865
+ usage: "kinds [--coverage [--kind <Kind>] [--now <ISO>]] [--dir <path>] [--remote <url>]",
17517
17866
  summary: "List the kind conventions this bundle declares (purpose, described fields, exact required body headings, typed-link vocabulary, horizon)"
17518
17867
  },
17519
17868
  {
@@ -25772,10 +26121,10 @@ function boundedLines(body, maximum) {
25772
26121
  );
25773
26122
  }
25774
26123
  function decodeDocumentRead(id, body, route) {
25775
- const envelope2 = body;
25776
- const data = envelope2?.data;
26124
+ const envelope3 = body;
26125
+ const data = envelope3?.data;
25777
26126
  const document4 = data?.document;
25778
- if (envelope2?.operationId !== "documents.read.v1" || envelope2.ok !== true || typeof data !== "object" || data === null || !isContentVersion(data.version) || typeof document4 !== "object" || document4 === null || document4.id !== id || typeof document4.frontmatter !== "object" || document4.frontmatter === null || Array.isArray(document4.frontmatter) || typeof document4.body !== "string")
26127
+ if (envelope3?.operationId !== "documents.read.v1" || envelope3.ok !== true || typeof data !== "object" || data === null || !isContentVersion(data.version) || typeof document4 !== "object" || document4 === null || document4.id !== id || typeof document4.frontmatter !== "object" || document4.frontmatter === null || Array.isArray(document4.frontmatter) || typeof document4.body !== "string")
25779
26128
  throw malformed("document read answered an envelope that is not documents.read.v1's result for this document", route);
25780
26129
  return { doc: { id, frontmatter: document4.frontmatter, body: document4.body }, version: data.version };
25781
26130
  }
@@ -25792,9 +26141,9 @@ function decodeDocumentHistory(request3, body, route) {
25792
26141
  const fail4 = (why) => {
25793
26142
  throw malformed(`history answered ${why}`, route);
25794
26143
  };
25795
- const envelope2 = body;
25796
- if (envelope2?.operationId !== HISTORY_OPERATION_ID || envelope2.ok !== true) fail4(`an envelope that is not ${HISTORY_OPERATION_ID}'s result`);
25797
- const data = envelope2.data;
26144
+ const envelope3 = body;
26145
+ if (envelope3?.operationId !== HISTORY_OPERATION_ID || envelope3.ok !== true) fail4(`an envelope that is not ${HISTORY_OPERATION_ID}'s result`);
26146
+ const data = envelope3.data;
25798
26147
  if (typeof data !== "object" || data === null || Array.isArray(data)) fail4("without its data");
25799
26148
  if (data.documentId !== request3.documentId) fail4("for another document");
25800
26149
  if (!Array.isArray(data.versions) || data.versions.length > request3.limit) fail4("more versions than asked for, or none as a list");
@@ -25836,10 +26185,10 @@ function decodeDocumentHistory(request3, body, route) {
25836
26185
  return Object.freeze({ documentId: request3.documentId, versions: Object.freeze(versions), more: data.more, ...total === void 0 ? {} : { total } });
25837
26186
  }
25838
26187
  function operationRefusal(body, operationId, route) {
25839
- const envelope2 = body;
25840
- if (envelope2?.ok !== false) return void 0;
25841
- const error51 = envelope2.error;
25842
- if (envelope2.operationId !== operationId || typeof error51 !== "object" || error51 === null || typeof error51.code !== "string" || !REFUSAL_CODE.test(error51.code))
26188
+ const envelope3 = body;
26189
+ if (envelope3?.ok !== false) return void 0;
26190
+ const error51 = envelope3.error;
26191
+ if (envelope3.operationId !== operationId || typeof error51 !== "object" || error51 === null || typeof error51.code !== "string" || !REFUSAL_CODE.test(error51.code))
25843
26192
  throw malformed(`answered a refusal that is not ${operationId}'s`, route);
25844
26193
  return refusalOf(error51.code, error51.message, error51.retryable);
25845
26194
  }
@@ -30216,10 +30565,10 @@ function ffSwallowToError(reason, inv, boardPath) {
30216
30565
  function syncEnvelope(home2, counts = {}) {
30217
30566
  return { home: home2, sent: counts.sent ?? 0, received: counts.received ?? 0, conflicts: counts.conflicts ?? 0, held: counts.held ?? 0, next: counts.next ?? [] };
30218
30567
  }
30219
- function withSyncEnvelope(receipt3, envelope2) {
30568
+ function withSyncEnvelope(receipt3, envelope3) {
30220
30569
  const out = { ...receipt3 };
30221
30570
  if (!("schema_version" in out)) out.schema_version = SYNC_RECEIPT_SCHEMA_VERSION;
30222
- for (const key2 of SYNC_ENVELOPE_KEYS) if (!(key2 in out)) out[key2] = envelope2[key2];
30571
+ for (const key2 of SYNC_ENVELOPE_KEYS) if (!(key2 in out)) out[key2] = envelope3[key2];
30223
30572
  return out;
30224
30573
  }
30225
30574
  function syncVerbNotApplicable(flags, home2, why, help2) {
@@ -31141,8 +31490,8 @@ async function showIncoming(id, values, deps, route) {
31141
31490
  try {
31142
31491
  await run();
31143
31492
  } catch (err) {
31144
- const { envelope: envelope2 } = toExit(err);
31145
- stderr(renderErrorEnvelope(envelope2));
31493
+ const { envelope: envelope3 } = toExit(err);
31494
+ stderr(renderErrorEnvelope(envelope3));
31146
31495
  throw asHandled(err);
31147
31496
  }
31148
31497
  }
@@ -35607,8 +35956,8 @@ async function sync(argv2, deps = {}) {
35607
35956
  try {
35608
35957
  await run();
35609
35958
  } catch (err) {
35610
- const { envelope: envelope2, handled } = toExit(err);
35611
- if (!handled) stderr(renderErrorEnvelope(envelope2));
35959
+ const { envelope: envelope3, handled } = toExit(err);
35960
+ if (!handled) stderr(renderErrorEnvelope(envelope3));
35612
35961
  throw handled ? err : asHandled(err);
35613
35962
  }
35614
35963
  }
@@ -35958,8 +36307,8 @@ async function failGate(run, board, commitResult, delta, reason, details) {
35958
36307
  );
35959
36308
  partial2.code = "GATE_FAILED";
35960
36309
  partial2.help = help2;
35961
- const envelope2 = syncEnvelope("git", { received: delta.originDelta.length, next: [`${run.inv} sync`] });
35962
- run.stdout(render(withSyncEnvelope(partial2, envelope2), run.mode));
36310
+ const envelope3 = syncEnvelope("git", { received: delta.originDelta.length, next: [`${run.inv} sync`] });
36311
+ run.stdout(render(withSyncEnvelope(partial2, envelope3), run.mode));
35963
36312
  await writeAwarenessCache(board.key, board.boardPath, delta.changes, delta.reanchorNote);
35964
36313
  throw new CliError("GATE_FAILED", `the sync gate ${reason}; nothing was pushed`, {
35965
36314
  help: help2,
@@ -36003,8 +36352,8 @@ function reportHeld(run, board, delta, held2, where, notPulled) {
36003
36352
  receipt3.held_documents = held2.map((doc2) => ({ id: doc2.id, path: doc2.relPath, reason: doc2.reason, detail: doc2.detail }));
36004
36353
  const fix = `fix the lines between the --- markers of ${held2.map((doc2) => doc2.relPath).join(", ")} (quote any value that contains ': '), check with ${run.inv} status, then run ${run.inv} sync`;
36005
36354
  receipt3.held_help = `not published: the YAML frontmatter of these documents does not parse, and publishing it would break every reader of the board, so this sync sent nothing. Your files are untouched; ${fix}` + (where === "committed locally" ? " (the fix is committed on top and both go out together)" : "");
36006
- const envelope2 = syncEnvelope("git", { received: delta.originDelta.length, held: held2.length, next: [`${run.inv} sync`] });
36007
- run.stdout(render(withSyncEnvelope(receipt3, envelope2), run.mode));
36355
+ const envelope3 = syncEnvelope("git", { received: delta.originDelta.length, held: held2.length, next: [`${run.inv} sync`] });
36356
+ run.stdout(render(withSyncEnvelope(receipt3, envelope3), run.mode));
36008
36357
  throw new CliError(
36009
36358
  "CONFLICT",
36010
36359
  `${held2.length} document(s) have invalid frontmatter (${held2.map((doc2) => doc2.id).join(", ")}); nothing was published`,
@@ -47352,7 +47701,7 @@ function visitParents(tree, test, visitor, reverse) {
47352
47701
  }
47353
47702
  return visit2;
47354
47703
  function visit2() {
47355
- let result3 = empty;
47704
+ let result3 = empty2;
47356
47705
  let subresult;
47357
47706
  let offset;
47358
47707
  let grandparents;
@@ -47391,16 +47740,16 @@ function toResult(value) {
47391
47740
  if (typeof value === "number") {
47392
47741
  return [CONTINUE, value];
47393
47742
  }
47394
- return value === null || value === void 0 ? empty : [value];
47743
+ return value === null || value === void 0 ? empty2 : [value];
47395
47744
  }
47396
- var empty, CONTINUE, EXIT2, SKIP;
47745
+ var empty2, CONTINUE, EXIT2, SKIP;
47397
47746
  var init_lib5 = __esm({
47398
47747
  "../../node_modules/unist-util-visit-parents/lib/index.js"() {
47399
47748
  init_define_SUPERBEE_BUILD_IDENTITY();
47400
47749
  init_define_SUPERBEE_UPDATE_POLICY();
47401
47750
  init_unist_util_is();
47402
47751
  init_color_node();
47403
- empty = [];
47752
+ empty2 = [];
47404
47753
  CONTINUE = true;
47405
47754
  EXIT2 = false;
47406
47755
  SKIP = "skip";
@@ -48375,11 +48724,11 @@ var require_react_production = __commonJS({
48375
48724
  _init: lazyInitializer
48376
48725
  };
48377
48726
  };
48378
- exports.memo = function(type, compare) {
48727
+ exports.memo = function(type, compare2) {
48379
48728
  return {
48380
48729
  $$typeof: REACT_MEMO_TYPE,
48381
48730
  type,
48382
- compare: void 0 === compare ? null : compare
48731
+ compare: void 0 === compare2 ? null : compare2
48383
48732
  };
48384
48733
  };
48385
48734
  exports.startTransition = function(scope) {
@@ -49307,18 +49656,18 @@ var require_react_development = __commonJS({
49307
49656
  lazyType2._debugInfo = [{ awaited: ioInfo }];
49308
49657
  return lazyType2;
49309
49658
  };
49310
- exports.memo = function(type, compare) {
49659
+ exports.memo = function(type, compare2) {
49311
49660
  null == type && console.error(
49312
49661
  "memo: The first argument must be a component. Instead received: %s",
49313
49662
  null === type ? "null" : typeof type
49314
49663
  );
49315
- compare = {
49664
+ compare2 = {
49316
49665
  $$typeof: REACT_MEMO_TYPE,
49317
49666
  type,
49318
- compare: void 0 === compare ? null : compare
49667
+ compare: void 0 === compare2 ? null : compare2
49319
49668
  };
49320
49669
  var ownName;
49321
- Object.defineProperty(compare, "displayName", {
49670
+ Object.defineProperty(compare2, "displayName", {
49322
49671
  enumerable: false,
49323
49672
  configurable: true,
49324
49673
  get: function() {
@@ -49329,7 +49678,7 @@ var require_react_development = __commonJS({
49329
49678
  type.name || type.displayName || (Object.defineProperty(type, "name", { value: name }), type.displayName = name);
49330
49679
  }
49331
49680
  });
49332
- return compare;
49681
+ return compare2;
49333
49682
  };
49334
49683
  exports.startTransition = function(scope) {
49335
49684
  var prevTransition = ReactSharedInternals.T, currentTransition = {};
@@ -76362,8 +76711,8 @@ async function docRead(argv2, deps) {
76362
76711
  try {
76363
76712
  await docReadInner(argv2, deps);
76364
76713
  } catch (err) {
76365
- const { envelope: envelope2, handled } = toExit(err);
76366
- if (!handled) stderr(renderErrorEnvelope(envelope2));
76714
+ const { envelope: envelope3, handled } = toExit(err);
76715
+ if (!handled) stderr(renderErrorEnvelope(envelope3));
76367
76716
  throw handled ? err : asHandled(err);
76368
76717
  }
76369
76718
  }
@@ -76558,8 +76907,8 @@ async function docReadInner(argv2, deps) {
76558
76907
  }
76559
76908
  stdout(formatFieldValue(resolveField(parsed2, version4, field, id)));
76560
76909
  } catch (err) {
76561
- const { envelope: envelope2 } = toExit(err);
76562
- stderr(renderErrorEnvelope(envelope2));
76910
+ const { envelope: envelope3 } = toExit(err);
76911
+ stderr(renderErrorEnvelope(envelope3));
76563
76912
  throw asHandled(err);
76564
76913
  }
76565
76914
  return;
@@ -77164,7 +77513,7 @@ function fields(value, required2, optional2 = []) {
77164
77513
  requireValue(required2.every((key2) => Object.hasOwn(value, key2)));
77165
77514
  requireValue(Object.keys(value).every((key2) => required2.includes(key2) || optional2.includes(key2)));
77166
77515
  }
77167
- function envelope(value, schema) {
77516
+ function envelope2(value, schema) {
77168
77517
  const data = record3(value);
77169
77518
  requireValue(typeof data.schemaVersion === "string");
77170
77519
  requireValue(data.schemaVersion === schema, "unsupported_version");
@@ -77182,7 +77531,7 @@ function nullableVersion(value) {
77182
77531
  return value === null ? null : version2(value);
77183
77532
  }
77184
77533
  function target2(value) {
77185
- const data = envelope(value, "superbee.document-target.v1");
77534
+ const data = envelope2(value, "superbee.document-target.v1");
77186
77535
  fields(data, ["schemaVersion", "authority", "bundleKey", "documentId"]);
77187
77536
  const authority = record3(data.authority);
77188
77537
  let parsedAuthority;
@@ -77221,12 +77570,12 @@ function provenance(value) {
77221
77570
  return data.state === "local-pending" ? { state: "local-pending", ...common } : { state: "local-conflict", ...common, remote: nullableVersion(data.remote) };
77222
77571
  }
77223
77572
  function observation(value) {
77224
- const data = envelope(value, "superbee.document-observation.v1");
77573
+ const data = envelope2(value, "superbee.document-observation.v1");
77225
77574
  fields(data, ["schemaVersion", "target", "provenance", "lifecycle"]);
77226
77575
  return { schemaVersion: "superbee.document-observation.v1", target: target2(data.target), provenance: provenance(data.provenance), lifecycle: lifecycle(data.lifecycle) };
77227
77576
  }
77228
77577
  function request2(value) {
77229
- const data = envelope(value, "superbee.present-document.v1");
77578
+ const data = envelope2(value, "superbee.present-document.v1");
77230
77579
  fields(data, ["schemaVersion", "operation", "invocationId", "target"], ["referenceVersion", "expectedLifecycle"]);
77231
77580
  requireValue(data.operation === "present_document");
77232
77581
  const expectedLifecycle = Object.hasOwn(data, "expectedLifecycle") ? lifecycle(data.expectedLifecycle) : void 0;
@@ -77258,7 +77607,7 @@ function presentation(value) {
77258
77607
  }
77259
77608
  }
77260
77609
  function receipt(value, expected) {
77261
- const data = envelope(value, "superbee.present-document-receipt.v1");
77610
+ const data = envelope2(value, "superbee.present-document-receipt.v1");
77262
77611
  requireValue(typeof data.ok === "boolean");
77263
77612
  fields(data, ["schemaVersion", "operation", "invocationId", "target", "ok", data.ok ? "presentation" : "error"]);
77264
77613
  requireValue(data.operation === "present_document");
@@ -83519,8 +83868,8 @@ async function pull2(argv2, deps = {}) {
83519
83868
  try {
83520
83869
  await runToTarget();
83521
83870
  } catch (err) {
83522
- const { envelope: envelope2 } = toExit(err);
83523
- stderr(renderErrorEnvelope(envelope2));
83871
+ const { envelope: envelope3 } = toExit(err);
83872
+ stderr(renderErrorEnvelope(envelope3));
83524
83873
  throw asHandled(err);
83525
83874
  }
83526
83875
  }
@@ -85425,6 +85774,9 @@ async function kinds(argv2, deps = {}) {
85425
85774
  () => parseArgs20({
85426
85775
  args: argv2,
85427
85776
  options: {
85777
+ coverage: { type: "boolean" },
85778
+ kind: { type: "string" },
85779
+ now: { type: "string" },
85428
85780
  dir: { type: "string" },
85429
85781
  remote: { type: "string" },
85430
85782
  json: { type: "boolean" },
@@ -85438,6 +85790,13 @@ async function kinds(argv2, deps = {}) {
85438
85790
  stdout(renderUsage(KINDS_USAGE));
85439
85791
  return;
85440
85792
  }
85793
+ if (!values.coverage && (values.kind !== void 0 || values.now !== void 0)) {
85794
+ throw new CliError("USAGE", "--kind and --now require --coverage");
85795
+ }
85796
+ if (values.coverage && values.remote !== void 0) throw new CliError("USAGE", "Kind coverage reads local bundles only; omit --remote");
85797
+ const nowText = values.now;
85798
+ const nowMs = nowText === void 0 ? Date.now() : parseTimestamp(/^\d{4}-\d{2}-\d{2}$/.test(nowText) ? `${nowText}T00:00:00Z` : nowText, "0.2");
85799
+ if (nowMs === null) throw new CliError("USAGE", "--now requires a valid ISO date or explicit-zone instant");
85441
85800
  const bundle = await openBundle(values.dir, await resolveRemoteFlag(values.remote, values.dir));
85442
85801
  const [registry2, okfVersion] = await Promise.all([
85443
85802
  loadKinds(bundle),
@@ -85446,7 +85805,20 @@ async function kinds(argv2, deps = {}) {
85446
85805
  const declared = [...registry2.kinds.values()];
85447
85806
  const ordered = declared.some((kind2) => kind2.order !== void 0) ? declared : declared.sort((a, b) => a.governs.localeCompare(b.governs));
85448
85807
  const rows = ordered.map((kind2) => toRow(kind2, okfVersion));
85808
+ if (values.coverage && values.kind !== void 0 && !registry2.kinds.has(values.kind)) {
85809
+ throw new CliError("USAGE", "--kind must name an exact declared Kind");
85810
+ }
85449
85811
  const out = { count: rows.length, kinds: rows };
85812
+ if (values.coverage) {
85813
+ const skipped = [];
85814
+ const documents = await query2(bundle, {}, { onSkip: ({ id }) => skipped.push(id) });
85815
+ const measurements = kindCoverage(registry2, documents, { now: new Date(nowMs), okfVersion, kind: values.kind });
85816
+ const byKind = new Map(measurements.kinds.map((row4) => [row4.governs, row4]));
85817
+ const selected2 = rows.filter((row4) => byKind.has(String(row4.governs))).map((row4) => ({ ...row4, ...byKind.get(String(row4.governs)) }));
85818
+ out.count = selected2.length;
85819
+ out.kinds = selected2;
85820
+ out.coverage = { now: measurements.now, documents: measurements.documents, complete: skipped.length === 0, skipped_documents: skipped.length, skipped_examples: skipped.sort().slice(0, 3), undeclared_kinds: measurements.undeclared_kinds };
85821
+ }
85450
85822
  if (registry2.warnings.length > 0) out.warnings = registry2.warnings;
85451
85823
  if (rows.length === 0) {
85452
85824
  out.help = [`${cliInvocation()} new "<Kind>" <id> --<field> <value> (once a kind is declared)`];
@@ -85459,6 +85831,7 @@ var init_kinds2 = __esm({
85459
85831
  "use strict";
85460
85832
  init_define_SUPERBEE_BUILD_IDENTITY();
85461
85833
  init_define_SUPERBEE_UPDATE_POLICY();
85834
+ init_errors4();
85462
85835
  init_output2();
85463
85836
  init_src();
85464
85837
  init_bundle2();
@@ -85470,6 +85843,7 @@ var init_kinds2 = __esm({
85470
85843
 
85471
85844
  Usage:
85472
85845
  superbee kinds [--dir <path>] [--remote <url>]
85846
+ superbee kinds --coverage [--kind <Kind>] [--now <ISO instant or date>] [--dir <path>] [--json]
85473
85847
 
85474
85848
  A kind convention is a plain OKF doc (type: Convention) under conventions/ declaring a document
85475
85849
  kind's purpose, required/optional fields and their descriptions, allowed enum values, typed-link vocabulary, expected body
@@ -85528,7 +85902,22 @@ A misshaped or misplaced key here is a non-fatal registry warning (visible in 'k
85528
85902
  output), never a silent no-op. See 'superbee doc read conventions/context-note' on any
85529
85903
  --init'd bundle for a full worked example with a values: enum and sections:.
85530
85904
 
85905
+ Coverage is local and read-only: group all readable concepts by actual type, using the same
85906
+ registry, logical field aliases and concept-link resolver. Filled excludes null, blank strings,
85907
+ empty lists/maps and case-insensitive unknown/n/a/na/none/tbd/null/-/? sentinels; it is a measurement,
85908
+ not required-field validation. Zero-record rates are null. Body prose excludes headings, standalone
85909
+ links and Related sections at any ATX heading level (including descendants until the next same
85910
+ or higher-level heading). This is line measurement, not Markdown rendering. Drift separates standard/envelope fields. Typed links use exact
85911
+ Kind-declared labels; other concept links are untyped citations, not undeclared relation violations.
85912
+ Freshness measures checked_on domain date metadata against the Kind's minute/hour/day horizon,
85913
+ not its meaningful-change clock. Missing/invalid dates and absent horizons remain explicit.
85914
+ Examples are capped at 3 per drift field; source domains at 15 with total/shown counts. A skipped
85915
+ malformed document makes coverage partial; no remote, sync or network access is performed.
85916
+
85531
85917
  Options:
85918
+ --coverage Add per-Kind field, drift, link, freshness and source measurements
85919
+ --kind <Kind> Select one exact declared type (requires --coverage)
85920
+ --now <ISO> Fixed UTC date or explicit-zone instant for coverage (requires --coverage)
85532
85921
  --dir <path> Bundle directory (default: discovered from the cwd)
85533
85922
  --remote <url> Talk to a wire-protocol server instead of a local bundle
85534
85923
  (mutually exclusive with --dir; remote access is always explicit)
@@ -92145,12 +92534,12 @@ function cleanRegex(source) {
92145
92534
  return source.slice(start, end);
92146
92535
  }
92147
92536
  function floatSafeRemainder2(val, step) {
92148
- const ratio = val / step;
92149
- const roundedRatio = Math.round(ratio);
92150
- const tolerance = Number.EPSILON * Math.max(Math.abs(ratio), 1);
92151
- if (Math.abs(ratio - roundedRatio) < tolerance)
92537
+ const ratio2 = val / step;
92538
+ const roundedRatio = Math.round(ratio2);
92539
+ const tolerance = Number.EPSILON * Math.max(Math.abs(ratio2), 1);
92540
+ if (Math.abs(ratio2 - roundedRatio) < tolerance)
92152
92541
  return 0;
92153
- return ratio - roundedRatio;
92542
+ return ratio2 - roundedRatio;
92154
92543
  }
92155
92544
  function defineLazy(object5, key2, getter) {
92156
92545
  let value = void 0;
@@ -119053,8 +119442,8 @@ var require_formats = __commonJS({
119053
119442
  init_define_SUPERBEE_UPDATE_POLICY();
119054
119443
  Object.defineProperty(exports, "__esModule", { value: true });
119055
119444
  exports.formatNames = exports.fastFormats = exports.fullFormats = void 0;
119056
- function fmtDef(validate, compare) {
119057
- return { validate, compare };
119445
+ function fmtDef(validate, compare2) {
119446
+ return { validate, compare: compare2 };
119058
119447
  }
119059
119448
  exports.fullFormats = {
119060
119449
  // date: http://tools.ietf.org/html/rfc3339#section-5.6
@@ -125440,8 +125829,8 @@ async function mcp(argv2, deps = {}) {
125440
125829
  try {
125441
125830
  await mcpInner(argv2, deps);
125442
125831
  } catch (error51) {
125443
- const { envelope: envelope2, handled } = toExit(error51);
125444
- if (!handled) stderr(renderErrorEnvelope(envelope2));
125832
+ const { envelope: envelope3, handled } = toExit(error51);
125833
+ if (!handled) stderr(renderErrorEnvelope(envelope3));
125445
125834
  throw handled ? error51 : asHandled(error51);
125446
125835
  }
125447
125836
  }
@@ -128894,8 +129283,8 @@ async function postRoute(context, route, body, writeRequest) {
128894
129283
  }
128895
129284
  throw hostedFailure(error52, target3, resume2);
128896
129285
  }
128897
- const envelope2 = answer2.body ?? {};
128898
- const error51 = envelope2.error;
129286
+ const envelope3 = answer2.body ?? {};
129287
+ const error51 = envelope3.error;
128899
129288
  const code3 = typeof error51 === "string" ? error51 : typeof error51?.code === "string" ? error51.code : null;
128900
129289
  const message = typeof error51?.message === "string" ? error51.message : "";
128901
129290
  if (answer2.status === 503 && code3 === "write_outcome_unknown") throw unknown3();
@@ -128905,10 +129294,10 @@ async function postRoute(context, route, body, writeRequest) {
128905
129294
  help: "a later release of the host offers it; until then do this in the Superbee app"
128906
129295
  });
128907
129296
  }
128908
- if (answer2.status === 200 && envelope2.ok === true && typeof envelope2.data === "object" && envelope2.data !== null && !Array.isArray(envelope2.data)) {
128909
- return { ok: true, data: envelope2.data };
129297
+ if (answer2.status === 200 && envelope3.ok === true && typeof envelope3.data === "object" && envelope3.data !== null && !Array.isArray(envelope3.data)) {
129298
+ return { ok: true, data: envelope3.data };
128910
129299
  }
128911
- if (answer2.status === 200 && envelope2.ok === false && code3 !== null) return { ok: false, code: code3, message };
129300
+ if (answer2.status === 200 && envelope3.ok === false && code3 !== null) return { ok: false, code: code3, message };
128912
129301
  throw hostedFailure(new RemoteError(`hosted ${route} answered ${answer2.status}`, code3 ?? "RUNTIME", answer2.status), target3, resume2);
128913
129302
  }
128914
129303
  function accessRefusal(code3, hostMessage, subject) {
@@ -129280,8 +129669,8 @@ async function catalog(argv2, deps = {}) {
129280
129669
  try {
129281
129670
  await catalogInner(argv2, deps);
129282
129671
  } catch (err) {
129283
- const { envelope: envelope2, handled } = toExit(err);
129284
- if (!handled) stderr(renderErrorEnvelope(envelope2));
129672
+ const { envelope: envelope3, handled } = toExit(err);
129673
+ if (!handled) stderr(renderErrorEnvelope(envelope3));
129285
129674
  throw handled ? err : asHandled(err);
129286
129675
  }
129287
129676
  return;
@@ -134510,7 +134899,7 @@ function packParts(content3, versions) {
134510
134899
  const parts = [];
134511
134900
  let part = null;
134512
134901
  let size = 0;
134513
- const envelope2 = 512;
134902
+ const envelope3 = 512;
134514
134903
  for (const version4 of new Set(versions)) {
134515
134904
  const object5 = content3.objects.get(version4);
134516
134905
  if (!object5) continue;
@@ -134518,7 +134907,7 @@ function packParts(content3, versions) {
134518
134907
  if (part === null || part.versions.length >= bounds.partObjects || size + bytes > bounds.partTargetBytes) {
134519
134908
  part = { documents: [], reserved: [], history: [], versions: [] };
134520
134909
  parts.push(part);
134521
- size = envelope2;
134910
+ size = envelope3;
134522
134911
  }
134523
134912
  if (object5.kind === "documents") part.documents.push(object5.value);
134524
134913
  else if (object5.kind === "reserved") part.reserved.push(object5.value);
@@ -134642,19 +135031,19 @@ async function runStagedCreate(request3) {
134642
135031
  }
134643
135032
  }
134644
135033
  function read(name, answer2) {
134645
- const envelope2 = answer2.body ?? {};
134646
- const code3 = typeof envelope2.error?.code === "string" ? envelope2.error.code : null;
134647
- const message = typeof envelope2.error?.message === "string" ? envelope2.error.message : "";
134648
- if (answer2.status === 200 && envelope2.ok === true && typeof envelope2.data === "object" && envelope2.data !== null) return envelope2.data;
134649
- if (answer2.status === 200 && envelope2.ok === false && code3 === "staged_manifest_missing") return "no_manifest";
134650
- if (answer2.status === 200 && envelope2.ok === false && code3 === "request_conflict" && envelope2.error?.retryable === true) return "busy";
134651
- if (answer2.status === 200 && envelope2.ok === false && code3 === "validation_failed" && VERSION_MISMATCH.test(message)) {
135034
+ const envelope3 = answer2.body ?? {};
135035
+ const code3 = typeof envelope3.error?.code === "string" ? envelope3.error.code : null;
135036
+ const message = typeof envelope3.error?.message === "string" ? envelope3.error.message : "";
135037
+ if (answer2.status === 200 && envelope3.ok === true && typeof envelope3.data === "object" && envelope3.data !== null) return envelope3.data;
135038
+ if (answer2.status === 200 && envelope3.ok === false && code3 === "staged_manifest_missing") return "no_manifest";
135039
+ if (answer2.status === 200 && envelope3.ok === false && code3 === "request_conflict" && envelope3.error?.retryable === true) return "busy";
135040
+ if (answer2.status === 200 && envelope3.ok === false && code3 === "validation_failed" && VERSION_MISMATCH.test(message)) {
134652
135041
  throw new CliError("RUNTIME", `${client.target.origin} stores an object differently from this CLI (client/host contract mismatch)`, {
134653
135042
  details: { reason: "staged_mismatch", route: name, host_message: message, host: client.target.origin, request_id: requestId2, retryable: false },
134654
135043
  help: `upgrade Superbee (npm install -g superbee), then re-run the same command, which resumes this creation: ${request3.resume}`
134655
135044
  });
134656
135045
  }
134657
- if (answer2.status === 200 && envelope2.ok === false && code3 !== null) throw new StagedRefusal(code3, message, reserved, name);
135046
+ if (answer2.status === 200 && envelope3.ok === false && code3 !== null) throw new StagedRefusal(code3, message, reserved, name);
134658
135047
  if (answer2.status === 429 && code3 === "bundle_create_limit") throw new StagedRefusal(code3, message, reserved, name);
134659
135048
  if (answer2.status === 400 && !reserved) throw new StagedRefusal(code3 ?? "invalid_input", message || `the host refused ${name} as malformed`, false, name);
134660
135049
  throw hostedFailure(new RemoteError(`hosted ${name} answered ${answer2.status}`, code3 ?? "RUNTIME", answer2.status), client.target, request3.resume);
@@ -135049,9 +135438,9 @@ async function sendCreation(plan, context) {
135049
135438
  }
135050
135439
  throw hostedFailure(error51, target3, yesCommand);
135051
135440
  }
135052
- const envelope2 = answer2.body ?? {};
135053
- const code3 = typeof envelope2.error?.code === "string" ? envelope2.error.code : null;
135054
- const hostMessage = typeof envelope2.error?.message === "string" ? envelope2.error.message : "";
135441
+ const envelope3 = answer2.body ?? {};
135442
+ const code3 = typeof envelope3.error?.code === "string" ? envelope3.error.code : null;
135443
+ const hostMessage = typeof envelope3.error?.message === "string" ? envelope3.error.message : "";
135055
135444
  if (answer2.status === 503 && code3 === "write_outcome_unknown") {
135056
135445
  throw new CliError("TRANSIENT", `${target3.origin} may have partly created '${bundleId}'`, {
135057
135446
  details: { reason: "write_outcome_unknown", bundle_id: bundleId, workspace, host: target3.origin, request_id: requestId2, retryable: true },
@@ -135063,16 +135452,16 @@ async function sendCreation(plan, context) {
135063
135452
  if (forgettable) await clearPendingCreate(home2, canonical2, bundleId);
135064
135453
  throw createRefusal(code3, hostMessage, refusalContext);
135065
135454
  }
135066
- if (answer2.status === 200 && envelope2.ok === false && code3 !== null) {
135455
+ if (answer2.status === 200 && envelope3.ok === false && code3 !== null) {
135067
135456
  if (code3 !== "request_conflict" && forgettable) await clearPendingCreate(home2, canonical2, bundleId);
135068
135457
  throw createRefusal(code3, hostMessage, refusalContext);
135069
135458
  }
135070
- if (answer2.status !== 200 || envelope2.ok !== true || typeof envelope2.data !== "object" || envelope2.data === null) {
135459
+ if (answer2.status !== 200 || envelope3.ok !== true || typeof envelope3.data !== "object" || envelope3.data === null) {
135071
135460
  if (answer2.status === 400 && forgettable) await clearPendingCreate(home2, canonical2, bundleId);
135072
135461
  throw hostedFailure(new RemoteError(`hosted bundle-create answered ${answer2.status}`, code3 ?? "RUNTIME", answer2.status), target3, yesCommand);
135073
135462
  }
135074
135463
  await clearPendingCreate(home2, canonical2, bundleId);
135075
- return envelope2.data;
135464
+ return envelope3.data;
135076
135465
  }
135077
135466
  async function publish(argv2, partial2 = {}) {
135078
135467
  const deps = publishDeps(partial2);
@@ -135800,7 +136189,7 @@ async function main(argv2) {
135800
136189
  await main(hoisted);
135801
136190
  return;
135802
136191
  }
135803
- const envelope2 = toEnvelope(
136192
+ const envelope3 = toEnvelope(
135804
136193
  new CliError(
135805
136194
  "USAGE",
135806
136195
  `options must follow the command (e.g. '${cliInvocation()} ${commandWords(command)} \u2026').`,
@@ -135809,7 +136198,7 @@ async function main(argv2) {
135809
136198
  }
135810
136199
  )
135811
136200
  );
135812
- process.stdout.write(renderErrorEnvelope(envelope2));
136201
+ process.stdout.write(renderErrorEnvelope(envelope3));
135813
136202
  process.exitCode = 2;
135814
136203
  return;
135815
136204
  }
@@ -135829,8 +136218,8 @@ async function main(argv2) {
135829
136218
  },
135830
136219
  renderUnknownCommand: (cmd) => renderErrorEnvelope(toEnvelope(unknownCommandError(cmd))),
135831
136220
  formatError: (err) => {
135832
- const { exitCode, envelope: envelope2, handled } = toExit(err);
135833
- return { output: handled ? "" : renderErrorEnvelope(envelope2), exitCode };
136221
+ const { exitCode, envelope: envelope3, handled } = toExit(err);
136222
+ return { output: handled ? "" : renderErrorEnvelope(envelope3), exitCode };
135834
136223
  }
135835
136224
  });
135836
136225
  }