@descryy/ir 0.1.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.
Files changed (94) hide show
  1. package/LICENSE +21 -0
  2. package/dist/capabilities.d.ts +83 -0
  3. package/dist/capabilities.d.ts.map +1 -0
  4. package/dist/capabilities.js +91 -0
  5. package/dist/capabilities.js.map +1 -0
  6. package/dist/conformance/bind.d.ts +82 -0
  7. package/dist/conformance/bind.d.ts.map +1 -0
  8. package/dist/conformance/bind.js +157 -0
  9. package/dist/conformance/bind.js.map +1 -0
  10. package/dist/conformance/cli.d.ts +25 -0
  11. package/dist/conformance/cli.d.ts.map +1 -0
  12. package/dist/conformance/cli.js +137 -0
  13. package/dist/conformance/cli.js.map +1 -0
  14. package/dist/conformance/compare.d.ts +74 -0
  15. package/dist/conformance/compare.d.ts.map +1 -0
  16. package/dist/conformance/compare.js +140 -0
  17. package/dist/conformance/compare.js.map +1 -0
  18. package/dist/conformance/compose.d.ts +79 -0
  19. package/dist/conformance/compose.d.ts.map +1 -0
  20. package/dist/conformance/compose.js +167 -0
  21. package/dist/conformance/compose.js.map +1 -0
  22. package/dist/conformance/golden.d.ts +110 -0
  23. package/dist/conformance/golden.d.ts.map +1 -0
  24. package/dist/conformance/golden.js +252 -0
  25. package/dist/conformance/golden.js.map +1 -0
  26. package/dist/conformance/index.d.ts +26 -0
  27. package/dist/conformance/index.d.ts.map +1 -0
  28. package/dist/conformance/index.js +18 -0
  29. package/dist/conformance/index.js.map +1 -0
  30. package/dist/conformance/manifest-check.d.ts +78 -0
  31. package/dist/conformance/manifest-check.d.ts.map +1 -0
  32. package/dist/conformance/manifest-check.js +149 -0
  33. package/dist/conformance/manifest-check.js.map +1 -0
  34. package/dist/conformance/manifest.d.ts +83 -0
  35. package/dist/conformance/manifest.d.ts.map +1 -0
  36. package/dist/conformance/manifest.js +158 -0
  37. package/dist/conformance/manifest.js.map +1 -0
  38. package/dist/conformance/report.d.ts +14 -0
  39. package/dist/conformance/report.d.ts.map +1 -0
  40. package/dist/conformance/report.js +87 -0
  41. package/dist/conformance/report.js.map +1 -0
  42. package/dist/conformance/run.d.ts +172 -0
  43. package/dist/conformance/run.d.ts.map +1 -0
  44. package/dist/conformance/run.js +626 -0
  45. package/dist/conformance/run.js.map +1 -0
  46. package/dist/contracts.d.ts +198 -0
  47. package/dist/contracts.d.ts.map +1 -0
  48. package/dist/contracts.js +10 -0
  49. package/dist/contracts.js.map +1 -0
  50. package/dist/contradiction.d.ts +112 -0
  51. package/dist/contradiction.d.ts.map +1 -0
  52. package/dist/contradiction.js +97 -0
  53. package/dist/contradiction.js.map +1 -0
  54. package/dist/finding.d.ts +567 -0
  55. package/dist/finding.d.ts.map +1 -0
  56. package/dist/finding.js +491 -0
  57. package/dist/finding.js.map +1 -0
  58. package/dist/hypothesis.d.ts +130 -0
  59. package/dist/hypothesis.d.ts.map +1 -0
  60. package/dist/hypothesis.js +116 -0
  61. package/dist/hypothesis.js.map +1 -0
  62. package/dist/identity.d.ts +295 -0
  63. package/dist/identity.d.ts.map +1 -0
  64. package/dist/identity.js +404 -0
  65. package/dist/identity.js.map +1 -0
  66. package/dist/index.d.ts +34 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +21 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/ir.d.ts +360 -0
  71. package/dist/ir.d.ts.map +1 -0
  72. package/dist/ir.js +76 -0
  73. package/dist/ir.js.map +1 -0
  74. package/dist/model-tables.d.ts +111 -0
  75. package/dist/model-tables.d.ts.map +1 -0
  76. package/dist/model-tables.js +103 -0
  77. package/dist/model-tables.js.map +1 -0
  78. package/dist/normalise.d.ts +114 -0
  79. package/dist/normalise.d.ts.map +1 -0
  80. package/dist/normalise.js +603 -0
  81. package/dist/normalise.js.map +1 -0
  82. package/dist/reliability.d.ts +89 -0
  83. package/dist/reliability.d.ts.map +1 -0
  84. package/dist/reliability.js +181 -0
  85. package/dist/reliability.js.map +1 -0
  86. package/dist/tool-surface.d.ts +131 -0
  87. package/dist/tool-surface.d.ts.map +1 -0
  88. package/dist/tool-surface.js +133 -0
  89. package/dist/tool-surface.js.map +1 -0
  90. package/dist/vocabulary.d.ts +73 -0
  91. package/dist/vocabulary.d.ts.map +1 -0
  92. package/dist/vocabulary.js +150 -0
  93. package/dist/vocabulary.js.map +1 -0
  94. package/package.json +27 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Descry
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Framework capabilities — the named things a pattern may require beyond the
3
+ * language adapter itself (§11A.8).
4
+ *
5
+ * ## Why these are named rather than counted
6
+ *
7
+ * There was one capability, `"framework-extractor"`, and the harness matched it
8
+ * against `frameworkExtractors.length === 0`. One boolean standing in for *which
9
+ * framework knowledge does this adapter have*, and it cost coverage in both
10
+ * directions at once:
11
+ *
12
+ * - **It kept a pattern out of the corpus.** A directional-migration pattern
13
+ * cannot be skipped for adapters that do not read migrations, because any
14
+ * adapter binding *any* extractor is then expected to satisfy it.
15
+ * - **It hid an extractor already in the tree.** `adapter-java` shipped a Spring
16
+ * route reader and had to keep declaring `frameworkExtractors: []`, because
17
+ * declaring it would have turned patterns 06, 07 and 08 from skipped into
18
+ * failing for extractors nobody had written. So pattern 04 reported *"requires
19
+ * a framework-extractor; none is bound"* for a capability the adapter has.
20
+ *
21
+ * Three lanes hit the same field from three sides. Naming the capabilities lets
22
+ * an adapter say yes to one of them.
23
+ *
24
+ * ## The set is closed, and it is closed on BOTH sides
25
+ *
26
+ * A pattern names what it needs; an adapter names what it supplies; the harness
27
+ * compares two strings and knows nothing about any framework. That is the IR
28
+ * boundary doing its job — `"spring"` and `"rails"` never appear above the
29
+ * adapter, only `"route-extractor"`.
30
+ *
31
+ * An unrecognised value is a **loud failure on either side** — a parse error in
32
+ * the golden, an adapter failure in a run — never a skip. That asymmetry is the
33
+ * whole safety property: a typo that skipped would be a gate that silently
34
+ * stopped running, and a suite which has stopped checking looks exactly like a
35
+ * suite with nothing to report.
36
+ *
37
+ * Adding a value changes what "skipped" means in every report that mentions it,
38
+ * so it is added deliberately, with the pattern that needs it, or not at all.
39
+ */
40
+ /**
41
+ * Routes: `API_ROUTE` with a method and a path template, and the `SERVES_API`
42
+ * edge to the endpoint it serves. Pattern 04.
43
+ */
44
+ export declare const ROUTE_EXTRACTOR = "route-extractor";
45
+ /**
46
+ * Persisted entities: `MODEL`, its fields, and their nullability — evidence
47
+ * being an ORM mapping rather than a name. Patterns 06 and 07.
48
+ *
49
+ * 07 is here rather than under routes despite being described as *"a route
50
+ * handler reads a field of the model"*: its assertion is `FUNCTION --READS-->
51
+ * MODEL`, with no `API_ROUTE` role and no `SERVES_API` edge. The only framework
52
+ * claim in it is `MODEL`. Reading the assertions settles this; reading the
53
+ * description does not.
54
+ */
55
+ export declare const ORM_EXTRACTOR = "orm-extractor";
56
+ /**
57
+ * The calling side of an HTTP boundary: `USES_API` from a caller to an
58
+ * `API_ENDPOINT`. Pattern 08.
59
+ *
60
+ * Separate from `ROUTE_EXTRACTOR` because the two are genuinely independent —
61
+ * `adapter-go` reads routes and no client calls, and a frontend-only adapter
62
+ * would be the reverse. Nobody declares an endpoint; it is minted by whoever
63
+ * reads a route *or* a call, which is exactly why either side can exist alone.
64
+ */
65
+ export declare const CLIENT_CALL_EXTRACTOR = "client-call-extractor";
66
+ /**
67
+ * The strict client-base resolution contract (DEC-164): `attrs.clientBase` on
68
+ * every caller a `USES_API` edge might come from, and `unresolved` refuses the
69
+ * edge. Patterns 08a/08b/08c.
70
+ *
71
+ * Separate from `CLIENT_CALL_EXTRACTOR` on purpose — an adapter can read a call
72
+ * site (08's plain case) without ever reading what base it composes against.
73
+ * DEC-164 §2 is explicit that this is opt-in: an adapter declaring it accepts
74
+ * the stricter refusal rule, and one that does not keeps emitting `USES_API`
75
+ * unqualified, which is why the two capabilities are not the same string.
76
+ */
77
+ export declare const CLIENT_BASE_EXTRACTOR = "client-base-extractor";
78
+ export declare const FRAMEWORK_CAPABILITIES: readonly ["route-extractor", "orm-extractor", "client-call-extractor", "client-base-extractor"];
79
+ export type FrameworkCapability = (typeof FRAMEWORK_CAPABILITIES)[number];
80
+ export declare function isFrameworkCapability(value: string): value is FrameworkCapability;
81
+ /** For error messages, so every rejection prints the same closed set. */
82
+ export declare function capabilityList(): string;
83
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH;;;GAGG;AACH,eAAO,MAAM,eAAe,oBAAoB,CAAC;AAEjD;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAE7D,eAAO,MAAM,sBAAsB,iGAKzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,mBAAmB,CAEjF;AAED,yEAAyE;AACzE,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Framework capabilities — the named things a pattern may require beyond the
3
+ * language adapter itself (§11A.8).
4
+ *
5
+ * ## Why these are named rather than counted
6
+ *
7
+ * There was one capability, `"framework-extractor"`, and the harness matched it
8
+ * against `frameworkExtractors.length === 0`. One boolean standing in for *which
9
+ * framework knowledge does this adapter have*, and it cost coverage in both
10
+ * directions at once:
11
+ *
12
+ * - **It kept a pattern out of the corpus.** A directional-migration pattern
13
+ * cannot be skipped for adapters that do not read migrations, because any
14
+ * adapter binding *any* extractor is then expected to satisfy it.
15
+ * - **It hid an extractor already in the tree.** `adapter-java` shipped a Spring
16
+ * route reader and had to keep declaring `frameworkExtractors: []`, because
17
+ * declaring it would have turned patterns 06, 07 and 08 from skipped into
18
+ * failing for extractors nobody had written. So pattern 04 reported *"requires
19
+ * a framework-extractor; none is bound"* for a capability the adapter has.
20
+ *
21
+ * Three lanes hit the same field from three sides. Naming the capabilities lets
22
+ * an adapter say yes to one of them.
23
+ *
24
+ * ## The set is closed, and it is closed on BOTH sides
25
+ *
26
+ * A pattern names what it needs; an adapter names what it supplies; the harness
27
+ * compares two strings and knows nothing about any framework. That is the IR
28
+ * boundary doing its job — `"spring"` and `"rails"` never appear above the
29
+ * adapter, only `"route-extractor"`.
30
+ *
31
+ * An unrecognised value is a **loud failure on either side** — a parse error in
32
+ * the golden, an adapter failure in a run — never a skip. That asymmetry is the
33
+ * whole safety property: a typo that skipped would be a gate that silently
34
+ * stopped running, and a suite which has stopped checking looks exactly like a
35
+ * suite with nothing to report.
36
+ *
37
+ * Adding a value changes what "skipped" means in every report that mentions it,
38
+ * so it is added deliberately, with the pattern that needs it, or not at all.
39
+ */
40
+ /**
41
+ * Routes: `API_ROUTE` with a method and a path template, and the `SERVES_API`
42
+ * edge to the endpoint it serves. Pattern 04.
43
+ */
44
+ export const ROUTE_EXTRACTOR = "route-extractor";
45
+ /**
46
+ * Persisted entities: `MODEL`, its fields, and their nullability — evidence
47
+ * being an ORM mapping rather than a name. Patterns 06 and 07.
48
+ *
49
+ * 07 is here rather than under routes despite being described as *"a route
50
+ * handler reads a field of the model"*: its assertion is `FUNCTION --READS-->
51
+ * MODEL`, with no `API_ROUTE` role and no `SERVES_API` edge. The only framework
52
+ * claim in it is `MODEL`. Reading the assertions settles this; reading the
53
+ * description does not.
54
+ */
55
+ export const ORM_EXTRACTOR = "orm-extractor";
56
+ /**
57
+ * The calling side of an HTTP boundary: `USES_API` from a caller to an
58
+ * `API_ENDPOINT`. Pattern 08.
59
+ *
60
+ * Separate from `ROUTE_EXTRACTOR` because the two are genuinely independent —
61
+ * `adapter-go` reads routes and no client calls, and a frontend-only adapter
62
+ * would be the reverse. Nobody declares an endpoint; it is minted by whoever
63
+ * reads a route *or* a call, which is exactly why either side can exist alone.
64
+ */
65
+ export const CLIENT_CALL_EXTRACTOR = "client-call-extractor";
66
+ /**
67
+ * The strict client-base resolution contract (DEC-164): `attrs.clientBase` on
68
+ * every caller a `USES_API` edge might come from, and `unresolved` refuses the
69
+ * edge. Patterns 08a/08b/08c.
70
+ *
71
+ * Separate from `CLIENT_CALL_EXTRACTOR` on purpose — an adapter can read a call
72
+ * site (08's plain case) without ever reading what base it composes against.
73
+ * DEC-164 §2 is explicit that this is opt-in: an adapter declaring it accepts
74
+ * the stricter refusal rule, and one that does not keeps emitting `USES_API`
75
+ * unqualified, which is why the two capabilities are not the same string.
76
+ */
77
+ export const CLIENT_BASE_EXTRACTOR = "client-base-extractor";
78
+ export const FRAMEWORK_CAPABILITIES = [
79
+ ROUTE_EXTRACTOR,
80
+ ORM_EXTRACTOR,
81
+ CLIENT_CALL_EXTRACTOR,
82
+ CLIENT_BASE_EXTRACTOR,
83
+ ];
84
+ export function isFrameworkCapability(value) {
85
+ return FRAMEWORK_CAPABILITIES.includes(value);
86
+ }
87
+ /** For error messages, so every rejection prints the same closed set. */
88
+ export function capabilityList() {
89
+ return FRAMEWORK_CAPABILITIES.map((c) => `"${c}"`).join(", ");
90
+ }
91
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEjD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAE7D,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,eAAe;IACf,aAAa;IACb,qBAAqB;IACrB,qBAAqB;CACb,CAAC;AAIX,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,OAAQ,sBAA4C,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,cAAc;IAC5B,OAAO,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Role binding — turning `"calc_method"` into the actual node an adapter emitted.
3
+ *
4
+ * ## Why binding is on `(file, name)` and not on node id
5
+ *
6
+ * A node id is `hash(repo, kind, qualifiedSymbolPath)` (DEC-011), and the
7
+ * qualified symbol path is built from a package root the adapter chooses. The
8
+ * harness cannot recompute it without knowing how that adapter names packages —
9
+ * which is adapter-private knowledge, and asking for it would make the harness
10
+ * language-aware. `file` and `name` are the two fields a human can point at in
11
+ * the source, and a manifest is written by a human pointing at source.
12
+ *
13
+ * ## Binding does not filter by expected type, on purpose
14
+ *
15
+ * A node bound on `(file, name)` and then found to have the wrong type reports
16
+ * *wrong type*. A node filtered out by type before binding reports *role
17
+ * unbound* — the same defect, described so vaguely the adapter author cannot act
18
+ * on it. Bind first, judge after.
19
+ *
20
+ * The one place the expected type is consulted is a **tie**, and only a tie: two
21
+ * nodes matching one `(file, name)`, which `OrderPage.tsx` produces the moment a
22
+ * frontend extractor exists, because the module and the component share a name.
23
+ * A single match is never filtered, so the good error above is never traded for
24
+ * a worse one.
25
+ *
26
+ * ## Ambiguity is a failure, never a guess
27
+ *
28
+ * The symbol fallback below (matching `dispatch` against
29
+ * `OrderService.dispatch`) exists because no rule pins how much qualification an
30
+ * adapter puts in `IRNode.name`. It is safe only because two candidates are a
31
+ * loud failure rather than a coin flip — precision over recall applies to the
32
+ * harness itself, not only to the adapters it grades.
33
+ */
34
+ import type { IRNode } from "../ir.ts";
35
+ import type { NodeType } from "../vocabulary.ts";
36
+ import type { CorpusManifest } from "./manifest.ts";
37
+ export type BindFailureReason = "unbound" | "ambiguous";
38
+ export interface BindFailure {
39
+ readonly role: string;
40
+ readonly reason: BindFailureReason;
41
+ readonly detail: string;
42
+ }
43
+ export interface BindResult {
44
+ readonly bound: ReadonlyMap<string, IRNode>;
45
+ readonly failures: readonly BindFailure[];
46
+ }
47
+ /**
48
+ * Compare two repo-relative paths.
49
+ *
50
+ * Deliberately shallow: the Normaliser has already rejected absolute paths, so
51
+ * anything reaching here is repo-relative and the only remaining variation is a
52
+ * leading `./` or a platform separator. `file` is **not** normalised away —
53
+ * golden pattern 01's `sameFileAs` compares it between two nodes, so it has to
54
+ * survive intact.
55
+ */
56
+ export declare function samePath(left: string | null, right: string | null): boolean;
57
+ /**
58
+ * Bind the given roles against a batch's nodes.
59
+ *
60
+ * Only the roles asked for are bound. A pattern that is skipped or not required
61
+ * at this resolution never asks, which is what stops "this adapter has no
62
+ * framework extractor" from being reported as eighteen unbound roles.
63
+ */
64
+ export declare function bindRoles(nodes: readonly IRNode[], manifest: CorpusManifest, roles: readonly string[],
65
+ /**
66
+ * The type the golden expects for each role, used **only to break a tie**.
67
+ *
68
+ * A `.tsx` file called `OrderPage.tsx` declares a component called `OrderPage`
69
+ * and a module called `OrderPage`, and that is not a naming accident — it is
70
+ * how React projects are laid out. Before this, no manifest could name that
71
+ * role at all: `(symbol, file)` matched two nodes and the binder rightly
72
+ * refused to choose.
73
+ *
74
+ * It is a tie-break and deliberately not a filter. Filtering by expected type
75
+ * would turn "the adapter emitted this as a MODULE, and the golden wants a
76
+ * COMPONENT" into "no node named OrderPage" — the same failure reported as a
77
+ * worse sentence, and one that points at the manifest instead of at the
78
+ * adapter. A single match is still bound whatever its type, and still fails
79
+ * the golden's own type assertion afterwards.
80
+ */
81
+ expectedTypes?: ReadonlyMap<string, NodeType>): BindResult;
82
+ //# sourceMappingURL=bind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../../src/conformance/bind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,eAAe,CAAC;AAEjE,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAI3E;AAiBD;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,SAAS,MAAM,EAAE;AACxB;;;;;;;;;;;;;;;GAeG;AACH,aAAa,GAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAa,GACvD,UAAU,CAyEZ"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Role binding — turning `"calc_method"` into the actual node an adapter emitted.
3
+ *
4
+ * ## Why binding is on `(file, name)` and not on node id
5
+ *
6
+ * A node id is `hash(repo, kind, qualifiedSymbolPath)` (DEC-011), and the
7
+ * qualified symbol path is built from a package root the adapter chooses. The
8
+ * harness cannot recompute it without knowing how that adapter names packages —
9
+ * which is adapter-private knowledge, and asking for it would make the harness
10
+ * language-aware. `file` and `name` are the two fields a human can point at in
11
+ * the source, and a manifest is written by a human pointing at source.
12
+ *
13
+ * ## Binding does not filter by expected type, on purpose
14
+ *
15
+ * A node bound on `(file, name)` and then found to have the wrong type reports
16
+ * *wrong type*. A node filtered out by type before binding reports *role
17
+ * unbound* — the same defect, described so vaguely the adapter author cannot act
18
+ * on it. Bind first, judge after.
19
+ *
20
+ * The one place the expected type is consulted is a **tie**, and only a tie: two
21
+ * nodes matching one `(file, name)`, which `OrderPage.tsx` produces the moment a
22
+ * frontend extractor exists, because the module and the component share a name.
23
+ * A single match is never filtered, so the good error above is never traded for
24
+ * a worse one.
25
+ *
26
+ * ## Ambiguity is a failure, never a guess
27
+ *
28
+ * The symbol fallback below (matching `dispatch` against
29
+ * `OrderService.dispatch`) exists because no rule pins how much qualification an
30
+ * adapter puts in `IRNode.name`. It is safe only because two candidates are a
31
+ * loud failure rather than a coin flip — precision over recall applies to the
32
+ * harness itself, not only to the adapters it grades.
33
+ */
34
+ /**
35
+ * Compare two repo-relative paths.
36
+ *
37
+ * Deliberately shallow: the Normaliser has already rejected absolute paths, so
38
+ * anything reaching here is repo-relative and the only remaining variation is a
39
+ * leading `./` or a platform separator. `file` is **not** normalised away —
40
+ * golden pattern 01's `sameFileAs` compares it between two nodes, so it has to
41
+ * survive intact.
42
+ */
43
+ export function samePath(left, right) {
44
+ if (left === null || right === null)
45
+ return left === right;
46
+ const clean = (p) => p.replace(/\\/g, "/").replace(/^\.\//, "");
47
+ return clean(left) === clean(right);
48
+ }
49
+ /** The last segment of a dotted symbol: `OrderService.dispatch` -> `dispatch`. */
50
+ function lastSegment(symbol) {
51
+ const index = symbol.lastIndexOf(".");
52
+ return index === -1 ? symbol : symbol.slice(index + 1);
53
+ }
54
+ function bindOne(nodes, binding) {
55
+ const inFile = nodes.filter((node) => samePath(node.file, binding.file));
56
+ const exact = inFile.filter((node) => node.name === binding.symbol);
57
+ if (exact.length > 0)
58
+ return exact;
59
+ const tail = lastSegment(binding.symbol);
60
+ if (tail === binding.symbol)
61
+ return [];
62
+ return inFile.filter((node) => node.name === tail);
63
+ }
64
+ /**
65
+ * Bind the given roles against a batch's nodes.
66
+ *
67
+ * Only the roles asked for are bound. A pattern that is skipped or not required
68
+ * at this resolution never asks, which is what stops "this adapter has no
69
+ * framework extractor" from being reported as eighteen unbound roles.
70
+ */
71
+ export function bindRoles(nodes, manifest, roles,
72
+ /**
73
+ * The type the golden expects for each role, used **only to break a tie**.
74
+ *
75
+ * A `.tsx` file called `OrderPage.tsx` declares a component called `OrderPage`
76
+ * and a module called `OrderPage`, and that is not a naming accident — it is
77
+ * how React projects are laid out. Before this, no manifest could name that
78
+ * role at all: `(symbol, file)` matched two nodes and the binder rightly
79
+ * refused to choose.
80
+ *
81
+ * It is a tie-break and deliberately not a filter. Filtering by expected type
82
+ * would turn "the adapter emitted this as a MODULE, and the golden wants a
83
+ * COMPONENT" into "no node named OrderPage" — the same failure reported as a
84
+ * worse sentence, and one that points at the manifest instead of at the
85
+ * adapter. A single match is still bound whatever its type, and still fails
86
+ * the golden's own type assertion afterwards.
87
+ */
88
+ expectedTypes = new Map()) {
89
+ const bound = new Map();
90
+ const failures = [];
91
+ for (const role of roles) {
92
+ const binding = manifest.roles[role];
93
+ if (binding === undefined) {
94
+ // THE ONE EXCEPTION, RECORDED HERE BECAUSE THIS IS WHERE SOMEONE WOULD
95
+ // "FIX" IT. A `mustNotBind` role's absence IS its assertion — the corpus
96
+ // names an over-admission trap and the adapter must produce no node for
97
+ // it, so unbound is the pass condition. The inversion is applied in
98
+ // `run.ts`, which filters these roles out of `failures`, deliberately
99
+ // rather than by loosening the rule here. This rule is not wrong for
100
+ // them; it is not applied to them. See DEC-160.
101
+ failures.push({
102
+ role,
103
+ reason: "unbound",
104
+ detail: `the manifest binds no symbol for this role. Every role in the golden must be bound ` +
105
+ `(fixtures/README.md, "Adding a language" step 2); an unbound role is a loud failure ` +
106
+ `and never a silent skip, because a corpus that quietly stops covering a pattern still ` +
107
+ `reports green.`,
108
+ });
109
+ continue;
110
+ }
111
+ // The primary first, then each alternate in order. More than one producer
112
+ // may legitimately declare a role — a route is `GET /orders/{id}` in a
113
+ // published contract and `GET /orders/:id` in the service source — and the
114
+ // corpus should accept whichever producer is running rather than demanding
115
+ // the one it happened to be written against.
116
+ const attempts = [binding, ...(binding.alternates ?? [])];
117
+ let matches = [];
118
+ let matched = attempts[0];
119
+ for (const attempt of attempts) {
120
+ const found = bindOne(nodes, attempt);
121
+ if (found.length > 0) {
122
+ matches = found;
123
+ matched = attempt;
124
+ break;
125
+ }
126
+ }
127
+ if (matches.length > 1) {
128
+ const wanted = expectedTypes.get(role);
129
+ const ofType = wanted === undefined ? [] : matches.filter((node) => node.type === wanted);
130
+ if (ofType.length === 1)
131
+ matches = ofType;
132
+ }
133
+ if (matches.length === 1) {
134
+ bound.set(role, matches[0]);
135
+ continue;
136
+ }
137
+ if (matches.length === 0) {
138
+ failures.push({
139
+ role,
140
+ reason: "unbound",
141
+ detail: `no node matched ` +
142
+ attempts.map((a) => `"${a.symbol}" in ${a.file ?? "(no file)"}`).join(" or ") +
143
+ `. The adapter either did not emit it or named it something the manifest does not expect.`,
144
+ });
145
+ continue;
146
+ }
147
+ failures.push({
148
+ role,
149
+ reason: "ambiguous",
150
+ detail: `${matches.length} nodes in ${matched.file ?? "(no file)"} match "${matched.symbol}" ` +
151
+ `(types: ${matches.map((m) => m.type).join(", ")}). The harness will not guess which one ` +
152
+ `the manifest meant; qualify the symbol in the manifest until exactly one matches.`,
153
+ });
154
+ }
155
+ return { bound, failures };
156
+ }
157
+ //# sourceMappingURL=bind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bind.js","sourceRoot":"","sources":["../../src/conformance/bind.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The conformance CLI.
3
+ *
4
+ * Deliberately thin, and deliberately here rather than in the engine: an adapter
5
+ * lives in its own repo (DEC-001) and depends on `@descryy/ir` alone, so the
6
+ * command that gates its release cannot live in a package it does not have. When
7
+ * the engine's own CLI exists this becomes `descry conformance` and calls the
8
+ * same `main()`.
9
+ *
10
+ * The adapter is loaded by module specifier and named export. That is the only
11
+ * way the harness can stay ignorant of every adapter — it imports what it is
12
+ * told to import and asks it for a batch.
13
+ */
14
+ interface Args {
15
+ readonly source: string;
16
+ readonly corpus: string;
17
+ readonly golden: string | undefined;
18
+ readonly patterns: readonly string[];
19
+ readonly sweep: boolean;
20
+ readonly json: boolean;
21
+ }
22
+ export declare function parseArgs(argv: readonly string[]): Args;
23
+ export declare function main(argv: readonly string[], log?: (...data: any[]) => void): Promise<number>;
24
+ export {};
25
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/conformance/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA2BH,UAAU,IAAI;IACZ,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAyCvD;AAoBD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,2BAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BtF"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * The conformance CLI.
3
+ *
4
+ * Deliberately thin, and deliberately here rather than in the engine: an adapter
5
+ * lives in its own repo (DEC-001) and depends on `@descryy/ir` alone, so the
6
+ * command that gates its release cannot live in a package it does not have. When
7
+ * the engine's own CLI exists this becomes `descry conformance` and calls the
8
+ * same `main()`.
9
+ *
10
+ * The adapter is loaded by module specifier and named export. That is the only
11
+ * way the harness can stay ignorant of every adapter — it imports what it is
12
+ * told to import and asks it for a batch.
13
+ */
14
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
15
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
16
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
17
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
18
+ });
19
+ }
20
+ return path;
21
+ };
22
+ import { resolve } from "node:path";
23
+ import { fileURLToPath, pathToFileURL } from "node:url";
24
+ import { loadGolden } from "./golden.js";
25
+ import { loadManifest } from "./manifest.js";
26
+ import { formatReport, formatSweepReport } from "./report.js";
27
+ import { runConformance, runConformanceSweep } from "./run.js";
28
+ const USAGE = `
29
+ descry conformance --source <module>#<export> --corpus <dir> [options]
30
+
31
+ --source Module specifier and named export of the source to grade. The
32
+ export is either an IRSource or a factory taking the resolution
33
+ level to cap at.
34
+ --corpus Directory holding manifest.json and the fixture sources.
35
+ --golden Path to patterns.json. Defaults to <corpus>/../../golden/patterns.json.
36
+ --pattern Run one pattern. Repeatable. Defaults to the whole corpus.
37
+ --sweep Run every level up to the corpus maximum and check monotonicity.
38
+ --json Emit the raw result instead of the report.
39
+
40
+ Exit code 0 only when every pattern passes and the boundary rejected nothing.
41
+ `.trim();
42
+ export function parseArgs(argv) {
43
+ let source = "";
44
+ let corpus = "";
45
+ let golden;
46
+ const patterns = [];
47
+ let sweep = false;
48
+ let json = false;
49
+ for (let i = 0; i < argv.length; i += 1) {
50
+ const flag = argv[i];
51
+ const value = argv[i + 1];
52
+ switch (flag) {
53
+ case "--source":
54
+ source = value ?? "";
55
+ i += 1;
56
+ break;
57
+ case "--corpus":
58
+ corpus = value ?? "";
59
+ i += 1;
60
+ break;
61
+ case "--golden":
62
+ golden = value;
63
+ i += 1;
64
+ break;
65
+ case "--pattern":
66
+ if (value !== undefined)
67
+ patterns.push(value);
68
+ i += 1;
69
+ break;
70
+ case "--sweep":
71
+ sweep = true;
72
+ break;
73
+ case "--json":
74
+ json = true;
75
+ break;
76
+ default:
77
+ throw new Error(`unknown argument "${String(flag)}"\n\n${USAGE}`);
78
+ }
79
+ }
80
+ if (source === "" || corpus === "")
81
+ throw new Error(`--source and --corpus are required\n\n${USAGE}`);
82
+ return { source, corpus, golden, patterns, sweep, json };
83
+ }
84
+ async function loadSource(specifier) {
85
+ const hash = specifier.lastIndexOf("#");
86
+ if (hash === -1)
87
+ throw new Error(`--source must be "<module>#<export>", got "${specifier}"`);
88
+ const modulePath = specifier.slice(0, hash);
89
+ const exportName = specifier.slice(hash + 1);
90
+ const url = modulePath.startsWith(".") || modulePath.startsWith("/")
91
+ ? pathToFileURL(resolve(modulePath)).href
92
+ : modulePath;
93
+ const loaded = (await import(__rewriteRelativeImportExtension(url)));
94
+ const entry = loaded[exportName];
95
+ if (entry === undefined)
96
+ throw new Error(`"${modulePath}" has no export "${exportName}"`);
97
+ if (typeof entry === "function")
98
+ return entry;
99
+ return () => entry;
100
+ }
101
+ export async function main(argv, log = console.log) {
102
+ const args = parseArgs(argv);
103
+ const corpus = resolve(args.corpus);
104
+ const manifest = loadManifest(resolve(corpus, "manifest.json"));
105
+ const golden = loadGolden(args.golden ?? resolve(corpus, "..", "..", "golden", "patterns.json"));
106
+ const factory = await loadSource(args.source);
107
+ const shared = {
108
+ manifest,
109
+ golden,
110
+ root: corpus,
111
+ ...(args.patterns.length === 0 ? {} : { patterns: args.patterns }),
112
+ };
113
+ if (args.sweep) {
114
+ const sweep = await runConformanceSweep({ ...shared, createSource: factory });
115
+ log(args.json ? JSON.stringify(sweep, null, 2) : formatSweepReport(sweep));
116
+ return sweep.passed ? 0 : 1;
117
+ }
118
+ const result = await runConformance({
119
+ ...shared,
120
+ source: await factory(manifest.expectedMaxResolution),
121
+ });
122
+ log(args.json ? JSON.stringify(result, null, 2) : formatReport(result));
123
+ return result.passed ? 0 : 1;
124
+ }
125
+ /* node:coverage disable */
126
+ if (process.argv[1] !== undefined && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
127
+ main(process.argv.slice(2))
128
+ .then((code) => {
129
+ process.exitCode = code;
130
+ })
131
+ .catch((error) => {
132
+ console.error(error instanceof Error ? error.message : String(error));
133
+ process.exitCode = 2;
134
+ });
135
+ }
136
+ /* node:coverage enable */
137
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/conformance/cli.ts"],"names":[],"mappings":"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"}