@lmzhen/dsh-evolution-merge 0.30.24 → 0.30.25

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 (82) hide show
  1. package/lib/index.js +518 -182
  2. package/lib/types/approve-command.js +2 -1
  3. package/lib/types/authoring-flow.d.ts +5 -0
  4. package/lib/types/authoring-flow.js +8 -5
  5. package/lib/types/commands.d.ts +7 -0
  6. package/lib/types/commands.js +8 -1
  7. package/lib/types/commit-execute.d.ts +4 -0
  8. package/lib/types/commit-execute.js +8 -5
  9. package/lib/types/commit-receipt.js +3 -1
  10. package/lib/types/contracts.d.ts +20 -1
  11. package/lib/types/doctor.js +1 -1
  12. package/lib/types/domain/errors.js +5 -1
  13. package/lib/types/domain/merge-snapshot.d.ts +12 -3
  14. package/lib/types/domain/merge-snapshot.js +9 -4
  15. package/lib/types/domain/reconcile.js +1 -1
  16. package/lib/types/domain/row-v4.d.ts +4 -0
  17. package/lib/types/domain/row-v4.js +9 -9
  18. package/lib/types/domain/run-coordinator.d.ts +9 -0
  19. package/lib/types/domain/stage-aggregate.d.ts +6 -1
  20. package/lib/types/domain/stage-aggregate.js +16 -9
  21. package/lib/types/domain/validation-plan.js +5 -1
  22. package/lib/types/index.js +14 -2
  23. package/lib/types/kernel/adapter-v4.d.ts +12 -0
  24. package/lib/types/kernel/adapter-v4.js +54 -0
  25. package/lib/types/kernel/failure.d.ts +8 -0
  26. package/lib/types/kernel/failure.js +33 -0
  27. package/lib/types/kernel/index.d.ts +9 -0
  28. package/lib/types/kernel/index.js +9 -0
  29. package/lib/types/kernel/invariants.d.ts +4 -0
  30. package/lib/types/kernel/invariants.js +47 -0
  31. package/lib/types/kernel/ledger.d.ts +46 -0
  32. package/lib/types/kernel/ledger.js +62 -0
  33. package/lib/types/kernel/machine.d.ts +13 -0
  34. package/lib/types/kernel/machine.js +108 -0
  35. package/lib/types/kernel/model.d.ts +154 -0
  36. package/lib/types/kernel/model.js +5 -0
  37. package/lib/types/kernel/projection.d.ts +28 -0
  38. package/lib/types/kernel/projection.js +44 -0
  39. package/lib/types/kernel/recovery.d.ts +31 -0
  40. package/lib/types/kernel/recovery.js +19 -0
  41. package/lib/types/kernel/unit.d.ts +43 -0
  42. package/lib/types/kernel/unit.js +63 -0
  43. package/lib/types/merge-routes.js +9 -0
  44. package/lib/types/new-child-authoring.d.ts +1 -0
  45. package/lib/types/new-child-authoring.js +15 -7
  46. package/lib/types/pending-actions.d.ts +1 -1
  47. package/lib/types/pending-actions.js +4 -0
  48. package/lib/types/recovery-coordinator.d.ts +2 -0
  49. package/lib/types/recovery-coordinator.js +14 -4
  50. package/lib/types/recovery-projection.d.ts +4 -2
  51. package/lib/types/recovery-projection.js +3 -3
  52. package/lib/types/resume-command.js +2 -1
  53. package/lib/types/round2-outcome.js +26 -9
  54. package/lib/types/run-shell.d.ts +1 -0
  55. package/lib/types/run-shell.js +57 -15
  56. package/lib/types/runtime.d.ts +4 -1
  57. package/lib/types/runtime.js +34 -22
  58. package/lib/types/scan-command.d.ts +1 -0
  59. package/lib/types/scan-command.js +1 -0
  60. package/lib/types/scan-ports.js +3 -0
  61. package/lib/types/scan-run.d.ts +6 -1
  62. package/lib/types/scan-run.js +34 -18
  63. package/lib/types/surface/merge-view.js +12 -4
  64. package/lib/types/undo-operation.d.ts +2 -1
  65. package/lib/types/undo-operation.js +10 -4
  66. package/lib/types/wire-projection.js +7 -2
  67. package/lib/types/wire.d.ts +1 -0
  68. package/package.json +4 -4
  69. package/lib/types/adapters/model.d.ts +0 -31
  70. package/lib/types/adapters/model.js +0 -47
  71. package/lib/types/gate-cache.d.ts +0 -12
  72. package/lib/types/gate-cache.js +0 -36
  73. package/lib/types/gate-filter.d.ts +0 -31
  74. package/lib/types/gate-filter.js +0 -64
  75. package/lib/types/ladder.d.ts +0 -65
  76. package/lib/types/ladder.js +0 -162
  77. package/lib/types/propose.d.ts +0 -26
  78. package/lib/types/propose.js +0 -69
  79. package/lib/types/screening-port.d.ts +0 -47
  80. package/lib/types/screening-port.js +0 -93
  81. package/lib/types/screening.d.ts +0 -30
  82. package/lib/types/screening.js +0 -75
@@ -1,93 +0,0 @@
1
- /**
2
- * The real screening port: lexical floor + optional C3 proposal + optional L0–L2 gate.
3
- * Each stage is independently testable; this file only composes their frozen contracts.
4
- */
5
- import { pairKey } from "./contracts.js";
6
- import { lexicalCandidates } from "./screening.js";
7
- import { proposePairs } from "./propose.js";
8
- import { filterCandidates } from "./gate-filter.js";
9
- export async function buildScreeningCandidates(options) {
10
- const lexical = lexicalCandidates(options.cards, options.lexical);
11
- const merged = new Map();
12
- for (const candidate of lexical.candidates)
13
- merged.set(pairKey(candidate.a, candidate.b), candidate);
14
- const degraded = [];
15
- let proposed = 0;
16
- let shards = 0;
17
- if (options.propose !== undefined) {
18
- const proposal = await proposePairs(options.cards, options.propose.model, {
19
- signal: options.signal,
20
- ...(options.propose.shardSize === undefined ? {} : { shardSize: options.propose.shardSize }),
21
- ...(options.propose.maxPairs === undefined ? {} : { maxPairs: options.propose.maxPairs }),
22
- });
23
- proposed = proposal.candidates.length;
24
- shards = proposal.shards;
25
- degraded.push(...proposal.degraded);
26
- for (const candidate of proposal.candidates) {
27
- const key = pairKey(candidate.a, candidate.b);
28
- const existing = merged.get(key);
29
- if (existing === undefined) {
30
- merged.set(key, candidate);
31
- continue;
32
- }
33
- const arms = [...new Set([...(existing.arms ?? []), ...(candidate.arms ?? [])])];
34
- merged.set(key, {
35
- ...existing,
36
- ...(candidate.reason === undefined || existing.reason !== undefined ? {} : { reason: candidate.reason }),
37
- ...(arms.length === 0 ? {} : { arms }),
38
- });
39
- }
40
- }
41
- let candidates = [...merged.values()].sort((left, right) => (right.score ?? 0) - (left.score ?? 0)
42
- || left.a.localeCompare(right.a)
43
- || left.b.localeCompare(right.b));
44
- let kept = candidates.length;
45
- let dropped = 0;
46
- let gateCalls = 0;
47
- let gateErrors = 0;
48
- if (options.gate !== undefined) {
49
- const facts = options.cards.map(card => ({ name: card.name, description: card.description, body: card.body }));
50
- const filtered = await filterCandidates(candidates, {
51
- facts,
52
- model: options.gate.model,
53
- modelName: options.gate.modelName,
54
- signal: options.signal,
55
- runSeed: options.gate.runSeed,
56
- ...(options.gate.cache === undefined ? {} : { cache: options.gate.cache }),
57
- ...(options.gate.auditRate === undefined ? {} : { auditRate: options.gate.auditRate }),
58
- });
59
- candidates = filtered.kept.map(decision => decision.candidate);
60
- kept = filtered.kept.length;
61
- dropped = filtered.dropped.length;
62
- gateCalls = filtered.calls;
63
- gateErrors = filtered.errors.length;
64
- for (const error of filtered.errors)
65
- degraded.push('gate error: ' + error.candidate.a + ' + ' + error.candidate.b + ': ' + error.message);
66
- }
67
- return {
68
- candidates,
69
- stats: {
70
- lexical: lexical.candidates.length,
71
- proposed,
72
- candidates: merged.size,
73
- kept,
74
- dropped,
75
- gateCalls,
76
- gateErrors,
77
- shards,
78
- },
79
- degraded,
80
- };
81
- }
82
- /** Build the run-scoped screening function; the run id seeds the 10% audit. */
83
- export function createScreeningForRun(options) {
84
- const gate = options.gate === undefined ? undefined : { ...options.gate, runSeed: options.runSeed };
85
- return async (signal) => (await buildScreeningCandidates({
86
- cards: options.cards,
87
- signal,
88
- ...(options.lexical === undefined ? {} : { lexical: options.lexical }),
89
- ...(options.propose === undefined ? {} : { propose: options.propose }),
90
- ...(gate === undefined ? {} : { gate }),
91
- })).candidates;
92
- }
93
- //# sourceMappingURL=screening-port.js.map
@@ -1,30 +0,0 @@
1
- import type { MergeCandidate } from './contracts.ts';
2
- export interface SkillCard {
3
- readonly name: string;
4
- readonly description: string;
5
- readonly body: string;
6
- }
7
- export interface ScreeningOptions {
8
- /** Body Jaccard at/above this is a candidate on its own. */
9
- readonly bodyGate?: number;
10
- /** Description Jaccard at/above this is a candidate when the body also clears minAffinity. */
11
- readonly summaryGate?: number;
12
- /** Minimum body affinity for a summary-led candidate. */
13
- readonly minAffinity?: number;
14
- /** Upper bound after sorting by score; absent = no cap. */
15
- readonly maxCandidates?: number;
16
- }
17
- export interface ScreeningStats {
18
- readonly skills: number;
19
- readonly filtered: number;
20
- readonly candidates: number;
21
- }
22
- export interface ScreeningResult {
23
- readonly candidates: readonly MergeCandidate[];
24
- readonly stats: ScreeningStats;
25
- }
26
- /** Shannon entropy over characters; a cheap prefilter signal, not a name-quality judge. */
27
- export declare function nameEntropy(name: string): number;
28
- export declare function prefilter(cards: readonly SkillCard[]): readonly SkillCard[];
29
- export declare function lexicalCandidates(cards: readonly SkillCard[], options?: ScreeningOptions): ScreeningResult;
30
- //# sourceMappingURL=screening.d.ts.map
@@ -1,75 +0,0 @@
1
- /**
2
- * Deterministic candidate screening: name prefilter + lexical affinity.
3
- *
4
- * The semantic proposer (C3) is a separate port; this module is the zero-cost floor that
5
- * must work without a model. It reuses core `vocabulary`/`affinity` so drift/dedup and
6
- * merge screening share one tokenizer.
7
- */
8
- import { affinity, vocabulary } from '@lmzhen/dsh-evolution-core';
9
- /** Shannon entropy over characters; a cheap prefilter signal, not a name-quality judge. */
10
- export function nameEntropy(name) {
11
- if (name === '')
12
- return 0;
13
- const counts = new Map();
14
- for (const char of name)
15
- counts.set(char, (counts.get(char) ?? 0) + 1);
16
- let entropy = 0;
17
- for (const count of counts.values()) {
18
- const p = count / name.length;
19
- entropy -= p * Math.log2(p);
20
- }
21
- return entropy;
22
- }
23
- const MIN_NAME_ENTROPY = 1.5;
24
- const MIN_NAME_LENGTH = 6;
25
- export function prefilter(cards) {
26
- return cards.filter((card) => {
27
- const name = card.name.trim();
28
- if (name.length < MIN_NAME_LENGTH)
29
- return false;
30
- if (nameEntropy(name) < MIN_NAME_ENTROPY)
31
- return false;
32
- return card.body.trim() !== '' || card.description.trim() !== '';
33
- });
34
- }
35
- function sortedPair(a, b) {
36
- return a < b ? [a, b] : [b, a];
37
- }
38
- export function lexicalCandidates(cards, options = {}) {
39
- const bodyGate = options.bodyGate ?? 0.9;
40
- const summaryGate = options.summaryGate ?? 0.5;
41
- const minAffinity = options.minAffinity ?? 0.3;
42
- const eligible = prefilter(cards);
43
- const vectors = eligible.map(card => ({
44
- card,
45
- summary: vocabulary(card.description),
46
- body: vocabulary(card.body),
47
- }));
48
- const candidates = [];
49
- for (let i = 0; i < vectors.length; i += 1) {
50
- for (let j = i + 1; j < vectors.length; j += 1) {
51
- const left = vectors[i];
52
- const right = vectors[j];
53
- if (left === undefined || right === undefined)
54
- continue;
55
- const summary = affinity(left.summary, right.summary);
56
- const body = affinity(left.body, right.body);
57
- const arms = [];
58
- if (body >= bodyGate)
59
- arms.push('body');
60
- if (summary >= summaryGate && body >= minAffinity)
61
- arms.push('summary');
62
- if (arms.length === 0)
63
- continue;
64
- const [a, b] = sortedPair(left.card.name, right.card.name);
65
- candidates.push({ a, b, score: Math.max(body, summary), arms, source: 'lexical' });
66
- }
67
- }
68
- candidates.sort((left, right) => (right.score ?? 0) - (left.score ?? 0) || left.a.localeCompare(right.a) || left.b.localeCompare(right.b));
69
- const capped = options.maxCandidates === undefined ? candidates : candidates.slice(0, options.maxCandidates);
70
- return {
71
- candidates: capped,
72
- stats: { skills: cards.length, filtered: cards.length - eligible.length, candidates: capped.length },
73
- };
74
- }
75
- //# sourceMappingURL=screening.js.map