@ultimat3/manifest 10.0.0 → 11.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/manifest",
3
- "version": "10.0.0",
3
+ "version": "11.0.0",
4
4
  "description": "x.manifest.json: deterministic generated facts, contract diff, AGENTS.md budget",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,10 +31,10 @@
31
31
  "test": "bun test"
32
32
  },
33
33
  "dependencies": {
34
- "@ultimat3/action": "10.0.0",
35
- "@ultimat3/core": "10.0.0",
36
- "@ultimat3/entity": "10.0.0",
37
- "@ultimat3/jobs": "10.0.0",
38
- "@ultimat3/query": "10.0.0"
34
+ "@ultimat3/action": "11.0.0",
35
+ "@ultimat3/core": "11.0.0",
36
+ "@ultimat3/entity": "11.0.0",
37
+ "@ultimat3/jobs": "11.0.0",
38
+ "@ultimat3/query": "11.0.0"
39
39
  }
40
40
  }
package/src/docs-scan.ts CHANGED
@@ -242,9 +242,12 @@ export async function scanPackageDocs(dir: string): Promise<readonly DocEntry[]>
242
242
  // alphabetically would reorder an argument its author sequenced on purpose, and prose read out
243
243
  // of order is prose an agent has to reassemble. Both halves are deterministic, which is what
244
244
  // "two scans of one tree agree" actually requires.
245
+ // Code units, never `localeCompare`, which answers from the runtime's ICU default and collation
246
+ // version: `jobs.Cache` sorted before `jobs.cache` on one machine and after it on the next, for
247
+ // one installed tree. `@ultimat3/jobs`' `job.ts` states the same rule.
245
248
  const moduleEntries = scanned
246
249
  .filter((entry) => entry !== undefined)
247
- .sort((a, b) => a.topic.localeCompare(b.topic));
250
+ .sort((a, b) => (a.topic < b.topic ? -1 : a.topic > b.topic ? 1 : 0));
248
251
  return [...moduleEntries, ...(await guideEntries(dir, name, version))];
249
252
  }
250
253
 
@@ -3,6 +3,15 @@
3
3
 
4
4
  import type { DocEntry } from './docs-scan';
5
5
 
6
+ /**
7
+ * The tie-break, in CODE UNITS. Never `localeCompare`: with no locale argument it answers from the
8
+ * runtime's ICU default and collation version, so one corpus ranks two ways on two machines and
9
+ * this file's header — "the order it produces is a function of its input alone" — stops being
10
+ * true. `@ultimat3/jobs`' `job.ts` states the same rule for the manifest it emits; the comparator
11
+ * is restated rather than imported because that package is not below this one on the tier table.
12
+ */
13
+ const byTopic = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);
14
+
6
15
  /**
7
16
  * Words that carry no signal in a question about an API. Deliberately tiny: every word removed
8
17
  * here is a word an agent cannot search for, and `get`, `set`, `run` and `new` are all real
@@ -194,7 +203,7 @@ export function searchDocs(
194
203
  const hit = scoreEntry(entry, tokens, rationale);
195
204
  if (hit !== undefined && hit.covered >= required) hits.push(hit);
196
205
  }
197
- hits.sort((a, b) => b.score - a.score || a.entry.topic.localeCompare(b.entry.topic));
206
+ hits.sort((a, b) => b.score - a.score || byTopic(a.entry.topic, b.entry.topic));
198
207
  return hits.slice(0, limit);
199
208
  }
200
209
 
@@ -220,6 +229,6 @@ export function nearestTopics(
220
229
  }
221
230
  if (score > 0) scored.push({ topic: entry.topic, score });
222
231
  }
223
- scored.sort((a, b) => b.score - a.score || a.topic.localeCompare(b.topic));
232
+ scored.sort((a, b) => b.score - a.score || byTopic(a.topic, b.topic));
224
233
  return [...new Set(scored.map((item) => item.topic))].slice(0, limit);
225
234
  }