@astrale-os/kernel-dsl 0.2.0-beta.37 → 0.2.0-beta.39

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 (102) hide show
  1. package/dist/v1/builder/core/authoring.d.ts +7 -2
  2. package/dist/v1/builder/lowering/schema/context.d.ts +9 -4
  3. package/dist/v1/builder/lowering/schema/context.js +20 -20
  4. package/dist/v1/builder/policy/authoring.d.ts +6 -6
  5. package/dist/v1/builder/policy/authoring.js +3 -1
  6. package/dist/v1/compiled/admission/accept.js +97 -18
  7. package/dist/v1/compiled/admission/semantics.js +77 -24
  8. package/dist/v1/compiled/compiler/compile.js +23 -7
  9. package/dist/v1/compiled/loader/load.d.ts +11 -2
  10. package/dist/v1/compiled/loader/load.js +4 -1
  11. package/dist/v1/compiled/model/schema.d.ts +5 -4
  12. package/dist/v1/domain/create.js +17 -9
  13. package/dist/v1/index.d.ts +1 -1
  14. package/dist/v1/language/callable/composition.d.ts +13 -1
  15. package/dist/v1/language/callable/composition.js +13 -3
  16. package/dist/v1/language/core/model/core.d.ts +7 -1
  17. package/dist/v1/language/core/resolved.d.ts +6 -2
  18. package/dist/v1/language/index.d.ts +1 -1
  19. package/dist/v1/language/index.js +1 -1
  20. package/dist/v1/language/policy/index.d.ts +1 -1
  21. package/dist/v1/language/policy/index.js +1 -1
  22. package/dist/v1/language/policy/model/policy.d.ts +1 -0
  23. package/dist/v1/language/policy/model/policy.js +17 -0
  24. package/dist/v1/language/value/compile/fields.d.ts +1 -1
  25. package/dist/v1/language/value/compile/load.d.ts +4 -2
  26. package/dist/v1/language/value/compile/load.js +22 -1
  27. package/dist/v1/language/value/compile/model.d.ts +16 -1
  28. package/dist/v1/language/value/evaluate/assertions.d.ts +2 -0
  29. package/dist/v1/language/value/evaluate/assertions.js +13 -0
  30. package/dist/v1/language/value/evaluate/evaluator.js +78 -17
  31. package/dist/v1/language/value/evaluate/preparation.d.ts +10 -1
  32. package/dist/v1/language/value/evaluate/preparation.js +17 -26
  33. package/dist/v1/language/value/evaluate/program.js +1 -1
  34. package/dist/v1/language/value/evaluate/validate.d.ts +6 -2
  35. package/dist/v1/language/value/evaluate/validate.js +18 -11
  36. package/dist/v1/language/value/ordering.d.ts +2 -0
  37. package/dist/v1/language/value/ordering.js +4 -8
  38. package/dist/v1/language/value/regexp/compile.d.ts +3 -3
  39. package/dist/v1/language/value/regexp/compile.js +56 -11
  40. package/dist/v1/language/value/regexp/matcher.d.ts +3 -3
  41. package/dist/v1/language/value/regexp/matcher.js +75 -3
  42. package/dist/v1/schema/analysis/class.d.ts +21 -0
  43. package/dist/v1/schema/analysis/class.js +18 -9
  44. package/dist/v1/schema/compatibility/api.d.ts +2 -0
  45. package/dist/v1/schema/compatibility/api.js +1 -0
  46. package/dist/v1/schema/compatibility/comparators/callables.d.ts +28 -0
  47. package/dist/v1/schema/compatibility/comparators/callables.js +77 -0
  48. package/dist/v1/schema/compatibility/comparators/classes.d.ts +28 -0
  49. package/dist/v1/schema/compatibility/comparators/classes.js +96 -0
  50. package/dist/v1/schema/compatibility/comparators/index.d.ts +12 -0
  51. package/dist/v1/schema/compatibility/comparators/index.js +41 -0
  52. package/dist/v1/schema/compatibility/comparators/members.d.ts +4 -0
  53. package/dist/v1/schema/compatibility/comparators/members.js +49 -0
  54. package/dist/v1/schema/compatibility/comparators/values.d.ts +5 -0
  55. package/dist/v1/schema/compatibility/comparators/values.js +37 -0
  56. package/dist/v1/schema/compatibility/compare.d.ts +5 -57
  57. package/dist/v1/schema/compatibility/compare.js +19 -162
  58. package/dist/v1/schema/compatibility/coordinate.d.ts +2 -7
  59. package/dist/v1/schema/compatibility/coordinate.js +2 -6
  60. package/dist/v1/schema/compatibility/evidence.d.ts +5 -0
  61. package/dist/v1/schema/compatibility/evidence.js +51 -0
  62. package/dist/v1/schema/compatibility/fields.d.ts +6 -0
  63. package/dist/v1/schema/compatibility/fields.js +5 -0
  64. package/dist/v1/schema/compatibility/index.d.ts +5 -4
  65. package/dist/v1/schema/compatibility/index.js +3 -2
  66. package/dist/v1/schema/compatibility/legacy/index.d.ts +58 -0
  67. package/dist/v1/schema/compatibility/legacy/index.js +145 -0
  68. package/dist/v1/schema/compatibility/meaning/footprint.d.ts +7 -0
  69. package/dist/v1/schema/compatibility/meaning/footprint.js +57 -0
  70. package/dist/v1/schema/compatibility/meaning/index.d.ts +3 -0
  71. package/dist/v1/schema/compatibility/meaning/index.js +14 -0
  72. package/dist/v1/schema/compatibility/model.d.ts +96 -0
  73. package/dist/v1/schema/compatibility/model.js +1 -0
  74. package/dist/v1/schema/compatibility/references.d.ts +30 -0
  75. package/dist/v1/schema/compatibility/references.js +122 -0
  76. package/dist/v1/schema/compatibility/report.d.ts +26 -0
  77. package/dist/v1/schema/compatibility/report.js +100 -0
  78. package/dist/v1/schema/compatibility/scope.d.ts +27 -0
  79. package/dist/v1/schema/compatibility/scope.js +78 -0
  80. package/dist/v1/schema/compatibility/structure/index.d.ts +3 -0
  81. package/dist/v1/schema/compatibility/structure/index.js +16 -0
  82. package/dist/v1/schema/compatibility/structure/inheritance.d.ts +7 -0
  83. package/dist/v1/schema/compatibility/structure/inheritance.js +68 -0
  84. package/dist/v1/schema/compatibility/structure/requirements.d.ts +7 -0
  85. package/dist/v1/schema/compatibility/structure/requirements.js +70 -0
  86. package/dist/v1/schema/compatibility/subjects.d.ts +34 -0
  87. package/dist/v1/schema/compatibility/subjects.js +86 -0
  88. package/dist/v1/schema/fingerprint.d.ts +2 -2
  89. package/dist/v1/schema/fingerprint.js +1 -1
  90. package/dist/v1/schema/index.d.ts +3 -0
  91. package/dist/v1/schema/index.js +2 -0
  92. package/dist/v1/schema/normalization/domain.js +15 -1
  93. package/dist/v1/schema/resolution/domain.js +17 -10
  94. package/dist/v1/schema/resolution/origins.d.ts +3 -0
  95. package/dist/v1/schema/resolution/origins.js +12 -4
  96. package/dist/v1/schema/validation/core.js +78 -26
  97. package/dist/v1/schema/validation/domain.structure.js +7 -2
  98. package/package.json +2 -2
  99. package/dist/v1/schema/compatibility/footprint.d.ts +0 -25
  100. package/dist/v1/schema/compatibility/footprint.js +0 -263
  101. package/dist/v1/schema/compatibility/meaning.d.ts +0 -44
  102. package/dist/v1/schema/compatibility/meaning.js +0 -234
@@ -1,7 +1,8 @@
1
- export { compareDependencyMeaning, compareMemberMeaning, describeMeaningChange, footprintOf, meaningOf, } from './compare.js';
2
- export type { DependencyMeaningChange, DependencyMeaningChangeKind, DependencyMeaningComparison, FootprintEntry, } from './compare.js';
1
+ export * from './api.js';
2
+ export { compareDependencyMeaning, compareDependencyStructure, compareMemberMeaning, describeMeaningChange, footprintOf, meaningOf, } from './legacy/index.js';
3
+ export type { DependencyMeaningChange, DependencyMeaningChangeKind, DependencyMeaningComparison, DependencyStructureComparison, FootprintEntry, } from './legacy/index.js';
3
4
  export type { MeaningDifference } from './diff.js';
4
5
  export { ANNOTATION_KEYWORDS, FIELD_ROLES } from './fields.js';
5
6
  export type { DependencyMeaningLevel, FieldRole } from './fields.js';
6
- export { callableFingerprint } from './meaning.js';
7
- export type { MeaningFingerprint } from './meaning.js';
7
+ export { callableFingerprint } from './comparators/callables.js';
8
+ export type { Fingerprint as MeaningFingerprint } from './model.js';
@@ -1,3 +1,4 @@
1
- export { compareDependencyMeaning, compareMemberMeaning, describeMeaningChange, footprintOf, meaningOf, } from './compare.js';
1
+ export * from './api.js';
2
+ export { compareDependencyMeaning, compareDependencyStructure, compareMemberMeaning, describeMeaningChange, footprintOf, meaningOf, } from './legacy/index.js';
2
3
  export { ANNOTATION_KEYWORDS, FIELD_ROLES } from './fields.js';
3
- export { callableFingerprint } from './meaning.js';
4
+ export { callableFingerprint } from './comparators/callables.js';
@@ -0,0 +1,58 @@
1
+ /** Historical positional APIs and version-3 wire evidence. New analyses never depend on this adapter. */
2
+ import type { Value as JsonValue } from '@astrale-os/kernel-dsl/value';
3
+ import type { Definition, Key as SemanticKey, Revision } from '../../../addressing/index.js';
4
+ import type { DomainSchema } from '../../model/schema.js';
5
+ import type { MeaningDifference } from '../diff.js';
6
+ import type { DependencyMeaningLevel } from '../fields.js';
7
+ import type { Fingerprint as MeaningFingerprint } from '../model.js';
8
+ export type DependencyMeaningChangeKind = 'missing' | 'changed' | 'added';
9
+ export type DependencyMeaningChange = {
10
+ readonly key: SemanticKey;
11
+ readonly kind: 'missing';
12
+ readonly sourceFingerprint: MeaningFingerprint;
13
+ } | {
14
+ readonly key: SemanticKey;
15
+ readonly kind: 'changed';
16
+ readonly sourceFingerprint: MeaningFingerprint;
17
+ readonly targetFingerprint: MeaningFingerprint;
18
+ /** Every exact path of the meaning that differs, in JSON Pointer order. */
19
+ readonly differences: readonly MeaningDifference[];
20
+ } | {
21
+ /** A required, non-automatic Property the target adds to an inherited Class. */
22
+ readonly key: SemanticKey;
23
+ readonly kind: 'added';
24
+ readonly targetFingerprint: MeaningFingerprint;
25
+ readonly meaning: JsonValue;
26
+ };
27
+ export interface DependencyMeaningComparison {
28
+ readonly version: 3;
29
+ readonly dependency: SemanticKey.Origin;
30
+ readonly source: Revision;
31
+ readonly target: Revision;
32
+ readonly footprint: readonly SemanticKey[];
33
+ readonly changes: readonly DependencyMeaningChange[];
34
+ readonly fingerprint: MeaningFingerprint;
35
+ }
36
+ /** One footprint entry: the Key, what it is, and for a Class how strongly it is used. */
37
+ export interface FootprintEntry {
38
+ readonly key: SemanticKey;
39
+ readonly kind: Definition.Kind | 'property' | 'method';
40
+ readonly level?: DependencyMeaningLevel;
41
+ }
42
+ export interface DependencyStructureComparison {
43
+ readonly kind: 'structure';
44
+ readonly version: 1;
45
+ readonly dependency: SemanticKey.Origin;
46
+ readonly source: Revision;
47
+ readonly target: Revision;
48
+ readonly footprint: readonly SemanticKey[];
49
+ readonly changes: readonly DependencyMeaningChange[];
50
+ readonly fingerprint: MeaningFingerprint;
51
+ }
52
+ export declare function compareDependencyMeaning(dependent: DomainSchema, target: DomainSchema): DependencyMeaningComparison;
53
+ export declare function compareMemberMeaning(source: DomainSchema, target: DomainSchema, roots: readonly [SemanticKey, ...SemanticKey[]]): DependencyMeaningComparison;
54
+ export declare function compareDependencyStructure(dependent: DomainSchema, target: DomainSchema): DependencyStructureComparison;
55
+ export declare function footprintOf(dependent: DomainSchema, origin: SemanticKey.Origin): readonly FootprintEntry[];
56
+ export declare function meaningOf(schema: DomainSchema, key: SemanticKey, level?: DependencyMeaningLevel): JsonValue;
57
+ /** One line an operator can act on, naming the exact paths of a changed meaning. */
58
+ export declare function describeMeaningChange(change: DependencyMeaningChange): string;
@@ -0,0 +1,145 @@
1
+ import { Key } from '../../../addressing/index.js';
2
+ import { compareUnicode } from '../../../addressing/ordering.js';
3
+ import { compareFacet } from '../comparators/index.js';
4
+ import { fingerprintMeaning } from '../comparators/values.js';
5
+ import { compareMeaning, compareStructure } from '../compare.js';
6
+ import { prepare, retainedContext } from '../scope.js';
7
+ export function compareDependencyMeaning(dependent, target) {
8
+ return legacyMeaning(compareMeaning({ scope: { kind: 'dependency', dependent }, target }));
9
+ }
10
+ export function compareMemberMeaning(source, target, roots) {
11
+ return legacyMeaning(compareMeaning({ scope: { kind: 'members', source, roots }, target }));
12
+ }
13
+ export function compareDependencyStructure(dependent, target) {
14
+ const report = compareStructure({ scope: { kind: 'dependency', dependent }, target });
15
+ const failed = new Set(report.assessments.filter((item) => !item.satisfied).map((item) => item.observation.id));
16
+ const changes = report.entries.flatMap((entry) => entry.observations.filter((item) => failed.has(item.id)).map((item) => changeOf(entry, item)));
17
+ return Object.freeze({
18
+ kind: 'structure',
19
+ version: 1,
20
+ dependency: report.scope.source.origin,
21
+ source: report.scope.source.revision,
22
+ target: report.scope.target.revision,
23
+ footprint: Object.freeze(report.entries
24
+ .filter((entry) => Key.origin(entry.subject.key) === report.scope.source.origin &&
25
+ entry.observations.some((item) => item.before !== undefined))
26
+ .map((entry) => entry.subject.key)),
27
+ changes: Object.freeze(changes),
28
+ fingerprint: report.evidence.fingerprint,
29
+ });
30
+ }
31
+ export function footprintOf(dependent, origin) {
32
+ const { source } = retainedContext(dependent, origin, '/origin');
33
+ const report = compareMeaning({ scope: { kind: 'dependency', dependent }, target: source });
34
+ return Object.freeze(report.entries.map((entry) => Object.freeze({
35
+ ...entry.subject,
36
+ ...(entry.subject.kind === 'class'
37
+ ? {
38
+ level: strongest(entry).facet === 'class.inherit'
39
+ ? 'inherit'
40
+ : 'reference',
41
+ }
42
+ : {}),
43
+ })));
44
+ }
45
+ export function meaningOf(schema, key, level = 'reference') {
46
+ const context = prepare({
47
+ scope: { kind: 'members', source: schema, roots: [key] },
48
+ target: schema,
49
+ });
50
+ const coordinate = context.roots[0].coordinate;
51
+ const facet = coordinate.kind === 'class'
52
+ ? level === 'inherit'
53
+ ? 'class.inherit'
54
+ : 'class.reference'
55
+ : coordinate.kind === 'method'
56
+ ? 'method.signature'
57
+ : coordinate.kind === 'property'
58
+ ? 'property'
59
+ : coordinate.ref.kind === 'function'
60
+ ? 'function.signature'
61
+ : coordinate.ref.kind;
62
+ return compareFacet({ context, pair: context.pair(coordinate), facet }).before;
63
+ }
64
+ function strongest(entry) {
65
+ return (entry.observations.find((item) => item.facet === 'class.inherit') ??
66
+ entry.observations.find((item) => item.facet !== 'property.required') ??
67
+ entry.observations[0]);
68
+ }
69
+ function legacyMeaning(report) {
70
+ const coordinates = [];
71
+ const footprint = [];
72
+ const changes = [];
73
+ const additions = [];
74
+ for (const entry of report.entries) {
75
+ const added = entry.observations.find((item) => item.facet === 'property.required');
76
+ if (added !== undefined)
77
+ additions.push(changeOf(entry, added));
78
+ const observation = strongest(entry);
79
+ const change = changeOf(entry, observation);
80
+ if (observation.before === undefined) {
81
+ continue;
82
+ }
83
+ footprint.push(entry.subject.key);
84
+ coordinates.push([
85
+ entry.subject.key,
86
+ fingerprintMeaning(observation.before),
87
+ observation.after === undefined ? null : fingerprintMeaning(observation.after),
88
+ ]);
89
+ if (change !== undefined)
90
+ changes.push(change);
91
+ }
92
+ additions.sort((a, b) => compareUnicode(a.key, b.key));
93
+ const identity = {
94
+ version: 3,
95
+ dependency: report.scope.source.origin,
96
+ source: report.scope.source.revision,
97
+ target: report.scope.target.revision,
98
+ };
99
+ return Object.freeze({
100
+ ...identity,
101
+ footprint: Object.freeze(footprint),
102
+ changes: Object.freeze([...changes, ...additions]),
103
+ fingerprint: fingerprintMeaning({
104
+ ...identity,
105
+ coordinates,
106
+ additions: additions.map(({ key, targetFingerprint }) => [key, targetFingerprint]),
107
+ }),
108
+ });
109
+ }
110
+ function changeOf(entry, observation) {
111
+ const key = entry.subject.key;
112
+ if (observation.state === 'equal')
113
+ return undefined;
114
+ if (observation.before === undefined)
115
+ return Object.freeze({
116
+ key,
117
+ kind: 'added',
118
+ targetFingerprint: fingerprintMeaning(observation.after),
119
+ meaning: observation.after,
120
+ });
121
+ const sourceFingerprint = fingerprintMeaning(observation.before);
122
+ if (observation.after === undefined)
123
+ return Object.freeze({ key, kind: 'missing', sourceFingerprint });
124
+ return Object.freeze({
125
+ key,
126
+ kind: 'changed',
127
+ sourceFingerprint,
128
+ targetFingerprint: fingerprintMeaning(observation.after),
129
+ differences: observation.differences,
130
+ });
131
+ }
132
+ /** One line an operator can act on, naming the exact paths of a changed meaning. */
133
+ export function describeMeaningChange(change) {
134
+ switch (change.kind) {
135
+ case 'missing':
136
+ return `${change.key} missing`;
137
+ case 'added':
138
+ return `${change.key} added as an obligation`;
139
+ case 'changed': {
140
+ const paths = change.differences.map(({ path }) => path);
141
+ const shown = paths.slice(0, 3).join(', ');
142
+ return `${change.key} changed at ${paths.length > 3 ? `${shown} and ${paths.length - 3} more` : shown}`;
143
+ }
144
+ }
145
+ }
@@ -0,0 +1,7 @@
1
+ import type { Report } from '../report.js';
2
+ import type { ComparisonContext } from '../scope.js';
3
+ /** Meaning follows complete callable contracts through the exact authored reference closure. */
4
+ export declare function compareFootprint({ context, report, }: {
5
+ readonly context: ComparisonContext;
6
+ readonly report: Report;
7
+ }): void;
@@ -0,0 +1,57 @@
1
+ import { Key } from '../../../addressing/index.js';
2
+ import { compareAddedProperties } from '../comparators/classes.js';
3
+ import { compareFacet } from '../comparators/index.js';
4
+ import { contextInvalid } from '../context.js';
5
+ import { callableReferences, classReferences, inherits, memberReferences, valueReferences, } from '../references.js';
6
+ /** Meaning follows complete callable contracts through the exact authored reference closure. */
7
+ export function compareFootprint({ context, report, }) {
8
+ const queue = [...context.roots];
9
+ const visited = new Set();
10
+ for (const reference of queue) {
11
+ report.note(reference);
12
+ const { coordinate, usage } = reference;
13
+ const visit = `${coordinate.key}:${usage.relation}`;
14
+ if (visited.has(visit))
15
+ continue;
16
+ visited.add(visit);
17
+ const pair = context.pair(coordinate);
18
+ const subject = pair.source;
19
+ if (subject === undefined)
20
+ throw contextInvalid(`Retained acceptance context has no meaning for ${coordinate.key}.`, coordinate.key);
21
+ let facet;
22
+ switch (subject.kind) {
23
+ case 'class': {
24
+ facet = inherits(usage) ? 'class.inherit' : 'class.reference';
25
+ queue.push(...classReferences(subject, false));
26
+ if (inherits(usage))
27
+ queue.push(...classReferences(subject, true));
28
+ break;
29
+ }
30
+ case 'property':
31
+ facet = 'property';
32
+ queue.push(...valueReferences(subject));
33
+ break;
34
+ case 'method':
35
+ facet = 'method.signature';
36
+ queue.push(...callableReferences(subject));
37
+ break;
38
+ case 'member': {
39
+ facet =
40
+ subject.coordinate.ref.kind === 'function'
41
+ ? 'function.signature'
42
+ : subject.coordinate.ref.kind;
43
+ queue.push(...memberReferences(subject));
44
+ }
45
+ }
46
+ if (Key.origin(coordinate.key) !== context.source.origin)
47
+ continue;
48
+ report.record({
49
+ pair,
50
+ facet,
51
+ ...compareFacet({ context, pair, facet }),
52
+ requirement: { kind: facet },
53
+ });
54
+ if (facet === 'class.inherit')
55
+ compareAddedProperties({ context, pair, report });
56
+ }
57
+ }
@@ -0,0 +1,3 @@
1
+ import type { MeaningComparison } from '../model.js';
2
+ import type { ComparisonContext } from '../scope.js';
3
+ export declare function analyzeMeaning(context: ComparisonContext): MeaningComparison;
@@ -0,0 +1,14 @@
1
+ import { evidenceOf } from '../evidence.js';
2
+ import { createReport } from '../report.js';
3
+ import { compareFootprint } from './footprint.js';
4
+ export function analyzeMeaning(context) {
5
+ const report = createReport();
6
+ compareFootprint({ context, report });
7
+ const result = { scope: context.scope, ...report.finish() };
8
+ return Object.freeze({
9
+ kind: 'meaning',
10
+ ...result,
11
+ equivalent: result.assessments.every(({ satisfied }) => satisfied),
12
+ evidence: evidenceOf({ kind: 'meaning', ...result }),
13
+ });
14
+ }
@@ -0,0 +1,96 @@
1
+ import type { Value } from '@astrale-os/kernel-dsl/value';
2
+ import type { Definition, Key, Revision } from '../../addressing/index.js';
3
+ import type { DomainSchema } from '../model/schema.js';
4
+ import type { ReferenceSite } from '../resolution/origins.js';
5
+ import type { MeaningDifference } from './diff.js';
6
+ export type Fingerprint = `sha256:${string}`;
7
+ /** Inputs carry accepted schemas; a dependency's source is always its retained exact context. */
8
+ export interface ComparisonRequest {
9
+ readonly scope: {
10
+ readonly kind: 'dependency';
11
+ readonly dependent: DomainSchema;
12
+ } | {
13
+ readonly kind: 'members';
14
+ readonly source: DomainSchema;
15
+ readonly roots: readonly [Key, ...Key[]];
16
+ };
17
+ readonly target: DomainSchema;
18
+ }
19
+ export interface SchemaIdentity {
20
+ readonly origin: Key.Origin;
21
+ readonly revision: Revision;
22
+ }
23
+ export interface ComparisonScope {
24
+ readonly kind: ComparisonRequest['scope']['kind'];
25
+ readonly source: SchemaIdentity;
26
+ readonly target: SchemaIdentity;
27
+ readonly dependent?: SchemaIdentity;
28
+ readonly roots: readonly Key[];
29
+ }
30
+ /** Identity contains no requirement or usage level. */
31
+ export interface Subject {
32
+ readonly key: Key;
33
+ readonly kind: Definition.Kind | 'property' | 'method';
34
+ }
35
+ /** Immediate provenance, retained even when several paths impose the same requirement. */
36
+ export interface Usage {
37
+ readonly source: SchemaIdentity;
38
+ readonly key?: Key;
39
+ readonly relation: ReferenceSite | 'member' | 'abstract' | 'selection';
40
+ }
41
+ export type Facet = 'class.reference' | 'class.inherit' | 'class.composition' | 'property' | 'property.required' | 'method.existence' | 'method.inheritance' | 'method.signature' | 'function.existence' | 'function.signature' | 'policy' | 'view' | 'core';
42
+ /** A fact about a compared facet, including unchanged facets. No admission decision is implied. */
43
+ export interface Observation {
44
+ readonly id: string;
45
+ readonly facet: Facet;
46
+ readonly state: 'equal' | 'changed' | 'missing' | 'added';
47
+ readonly before?: Value;
48
+ readonly after?: Value;
49
+ readonly differences: readonly MeaningDifference[];
50
+ }
51
+ export interface ComparisonEntry {
52
+ readonly subject: Subject;
53
+ readonly source?: SchemaIdentity;
54
+ readonly target?: SchemaIdentity;
55
+ readonly usages: readonly Usage[];
56
+ readonly observations: readonly Observation[];
57
+ }
58
+ /** An established requirement; observations without one remain visible but do not affect the conclusion. */
59
+ export interface Assessment {
60
+ readonly subject: Subject;
61
+ readonly observation: Observation;
62
+ readonly requirement: {
63
+ readonly kind: Facet;
64
+ };
65
+ readonly satisfied: boolean;
66
+ }
67
+ /** Evidence is a semantic projection; presentation/provenance never enters its digest. */
68
+ export interface ComparisonEvidence {
69
+ readonly kind: 'structure' | 'meaning';
70
+ readonly version: 1 | 2;
71
+ readonly fingerprint: Fingerprint;
72
+ }
73
+ export interface Analysis {
74
+ readonly scope: ComparisonScope;
75
+ readonly entries: readonly ComparisonEntry[];
76
+ readonly assessments: readonly Assessment[];
77
+ readonly evidence: ComparisonEvidence;
78
+ }
79
+ export interface StructureComparison extends Analysis {
80
+ readonly kind: 'structure';
81
+ readonly compatible: boolean;
82
+ }
83
+ export interface MeaningComparison extends Analysis {
84
+ readonly kind: 'meaning';
85
+ readonly equivalent: boolean;
86
+ }
87
+ export interface Comparison {
88
+ readonly scope: ComparisonScope;
89
+ readonly entries: readonly ComparisonEntry[];
90
+ readonly structure: StructureComparison;
91
+ readonly meaning: MeaningComparison;
92
+ readonly evidence: {
93
+ readonly structure: ComparisonEvidence;
94
+ readonly meaning: ComparisonEvidence;
95
+ };
96
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import type { Key } from '../../addressing/index.js';
2
+ import type { DomainSchema } from '../model/schema.js';
3
+ import type { Coordinate } from './coordinate.js';
4
+ import type { Usage } from './model.js';
5
+ import type { ResolvedSubject } from './subjects.js';
6
+ export interface Reference {
7
+ readonly coordinate: Coordinate;
8
+ readonly usage: Usage;
9
+ }
10
+ export declare function schemaIdentity(schema: DomainSchema): Readonly<{
11
+ origin: string;
12
+ revision: import("../../addressing/revision.js").Revision;
13
+ }>;
14
+ export declare function usageOf(schema: DomainSchema, relation: Usage['relation'], key?: Key): Usage;
15
+ /** References keep their declaring member and relation; no strongest-usage collapse happens here. */
16
+ export declare function rootReferences(schema: DomainSchema): readonly Reference[];
17
+ /** Existing DSL collectors own reference syntax. These functions attach comparison provenance. */
18
+ export declare function valueReferences(subject: Extract<ResolvedSubject, {
19
+ kind: 'property';
20
+ }>): readonly Reference[];
21
+ export declare function callableReferences(subject: Extract<ResolvedSubject, {
22
+ kind: 'method';
23
+ }>): readonly Reference[];
24
+ export declare function classReferences(subject: Extract<ResolvedSubject, {
25
+ kind: 'class';
26
+ }>, inherit: boolean): readonly Reference[];
27
+ export declare function memberReferences(subject: Extract<ResolvedSubject, {
28
+ kind: 'member';
29
+ }>): readonly Reference[];
30
+ export declare function inherits(usage: Usage): boolean;
@@ -0,0 +1,122 @@
1
+ import { revisionOfDomainSchema } from '../canonical/revision.js';
2
+ import { collectCallableContractRefs, collectCallableRefs, collectClassPolicyRefs, collectCoreRefs, collectEndpointRefs, collectPolicyDefinitionRefs, collectValueDefinitionRefs, coreEndpointDefinitionRef, } from '../resolution/origins.js';
3
+ import { classCoordinate, keyForDefinitionRef, memberCoordinate, methodCoordinate, propertyCoordinate, } from './coordinate.js';
4
+ export function schemaIdentity(schema) {
5
+ return Object.freeze({ origin: schema.origin, revision: revisionOfDomainSchema(schema) });
6
+ }
7
+ export function usageOf(schema, relation, key) {
8
+ return Object.freeze({
9
+ source: schemaIdentity(schema),
10
+ relation,
11
+ ...(key === undefined ? {} : { key }),
12
+ });
13
+ }
14
+ function collector(schema, result, key) {
15
+ return (ref, relation) => result.push({
16
+ coordinate: ref.kind === 'class'
17
+ ? classCoordinate(ref)
18
+ : memberCoordinate(ref),
19
+ usage: usageOf(schema, relation, key),
20
+ });
21
+ }
22
+ /** References keep their declaring member and relation; no strongest-usage collapse happens here. */
23
+ export function rootReferences(schema) {
24
+ const result = [];
25
+ for (const declaration of Object.values(schema.classes)) {
26
+ const key = keyForDefinitionRef(declaration.ref);
27
+ const add = collector(schema, result, key);
28
+ declaration.extends.forEach((ref) => add(ref, 'extends'));
29
+ for (const [name, field] of Object.entries(declaration.properties)) {
30
+ collectValueDefinitionRefs(field.schema, collector(schema, result, propertyCoordinate(declaration.ref, name).key));
31
+ }
32
+ collectClassPolicyRefs(declaration, add);
33
+ if (declaration.kind === 'edge')
34
+ collectEndpointRefs(declaration, add);
35
+ else
36
+ for (const [name, method] of Object.entries(declaration.methods)) {
37
+ collectCallableRefs(method, collector(schema, result, methodCoordinate(declaration.ref, name).key));
38
+ }
39
+ }
40
+ for (const declaration of Object.values(schema.functions))
41
+ collectCallableRefs(declaration, collector(schema, result, keyForDefinitionRef(declaration.ref)));
42
+ for (const declaration of Object.values(schema.policies))
43
+ collectPolicyDefinitionRefs(declaration, collector(schema, result, keyForDefinitionRef(declaration.ref)));
44
+ for (const declaration of Object.values(schema.views))
45
+ if (declaration.target.kind === 'definition') {
46
+ const add = collector(schema, result, keyForDefinitionRef(declaration.ref));
47
+ declaration.target.definitions.forEach((ref) => add(ref, 'view'));
48
+ }
49
+ collectCoreRefs(schema, collector(schema, result));
50
+ return result;
51
+ }
52
+ /** Existing DSL collectors own reference syntax. These functions attach comparison provenance. */
53
+ export function valueReferences(subject) {
54
+ const result = [];
55
+ collectValueDefinitionRefs(subject.field.schema, collector(subject.schema, result, subject.coordinate.key));
56
+ return result;
57
+ }
58
+ export function callableReferences(subject) {
59
+ const result = [];
60
+ collectCallableContractRefs(subject.method.declaration, collector(subject.schema, result, subject.coordinate.key));
61
+ return result;
62
+ }
63
+ export function classReferences(subject, inherit) {
64
+ const result = [];
65
+ const add = collector(subject.schema, result, subject.coordinate.key);
66
+ if (inherit) {
67
+ subject.analysis.declaration.extends.forEach((ref) => add(ref, 'extends'));
68
+ if (subject.analysis.declaration.kind === 'edge')
69
+ collectEndpointRefs(subject.analysis.declaration, add);
70
+ }
71
+ else {
72
+ for (const field of subject.analysis.properties.values())
73
+ result.push({
74
+ coordinate: propertyCoordinate(field.owner, field.name),
75
+ usage: usageOf(subject.schema, 'member', subject.coordinate.key),
76
+ });
77
+ for (const method of subject.analysis.methods.values())
78
+ result.push({
79
+ coordinate: methodCoordinate(method.owner, method.name),
80
+ usage: usageOf(subject.schema, 'member', subject.coordinate.key),
81
+ });
82
+ collectClassPolicyRefs(subject.analysis.declaration, add);
83
+ }
84
+ return result;
85
+ }
86
+ export function memberReferences(subject) {
87
+ const result = [];
88
+ const { schema, coordinate: { ref, key }, } = subject;
89
+ const add = collector(schema, result, key);
90
+ switch (ref.kind) {
91
+ case 'function':
92
+ collectCallableRefs(schema.functions[ref.name], add);
93
+ break;
94
+ case 'policy':
95
+ collectPolicyDefinitionRefs(schema.policies[ref.name], add);
96
+ break;
97
+ case 'view': {
98
+ const view = schema.views[ref.name];
99
+ if (view.target.kind === 'definition')
100
+ view.target.definitions.forEach((ref) => add(ref, 'view'));
101
+ break;
102
+ }
103
+ case 'core': {
104
+ add(schema.core.nodes[ref.name].class, 'endpoint');
105
+ for (const edge of schema.core.edges) {
106
+ if (!((edge.source.kind === 'core' && edge.source.name === ref.name) ||
107
+ (edge.target.kind === 'core' && edge.target.name === ref.name)))
108
+ continue;
109
+ add(edge.class, 'endpoint');
110
+ for (const endpoint of [edge.source, edge.target]) {
111
+ const ref = coreEndpointDefinitionRef(endpoint);
112
+ if (ref !== undefined)
113
+ add(ref, 'endpoint');
114
+ }
115
+ }
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+ export function inherits(usage) {
121
+ return usage.relation === 'extends' || usage.relation === 'core';
122
+ }
@@ -0,0 +1,26 @@
1
+ import type { Value } from '@astrale-os/kernel-dsl/value';
2
+ import type { Assessment, ComparisonEntry, Facet } from './model.js';
3
+ import type { Reference } from './references.js';
4
+ import type { SubjectPair } from './scope.js';
5
+ export interface ComparisonFact {
6
+ readonly pair: SubjectPair;
7
+ readonly facet: Facet;
8
+ readonly before?: Value;
9
+ readonly after?: Value;
10
+ readonly requirement?: {
11
+ readonly kind: Assessment['requirement']['kind'];
12
+ readonly satisfied?: boolean;
13
+ };
14
+ }
15
+ /** Mutable collection is local to one analysis; callers only receive frozen completed reports. */
16
+ export declare function createReport(): {
17
+ note({ coordinate, usage }: Reference): void;
18
+ record(fact: ComparisonFact): void;
19
+ finish(): Readonly<{
20
+ entries: readonly ComparisonEntry[];
21
+ assessments: readonly Assessment[];
22
+ }>;
23
+ };
24
+ export type Report = ReturnType<typeof createReport>;
25
+ /** Full comparison merges facts; it never reclassifies the two analyses' conclusions. */
26
+ export declare function mergeEntries(...groups: readonly (readonly ComparisonEntry[])[]): readonly ComparisonEntry[];