@ogygie/core 0.2.0 → 0.3.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 +1 -1
- package/src/vocabulary-audit.test.ts +18 -2
- package/src/vocabulary-audit.ts +18 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ogygie/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Ogygie framework core: manifest/spec/error schemas, generic tenancy and gate tooling. Ships TypeScript sources — Ogygie products run tsx/vitest by construction (D1).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -121,9 +121,25 @@ describe("auditProductVocabulary — B4 : la pureté des fichiers gouvernés", (
|
|
|
121
121
|
const violations = auditProductVocabulary({
|
|
122
122
|
vocabulary: VOCABULARY,
|
|
123
123
|
sourceFiles: [],
|
|
124
|
-
governedFiles: [{ path: "tsconfig.base.json", content: "// tuned for the
|
|
124
|
+
governedFiles: [{ path: "tsconfig.base.json", content: "// tuned for the gadget pipeline" }],
|
|
125
125
|
});
|
|
126
|
-
expect(violations.map((violation) => violation.match.root)).toEqual(["
|
|
126
|
+
expect(violations.map((violation) => violation.match.root)).toEqual(["gadget"]);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("un ALIAS interdit dans un fichier gouverné ne déclenche RIEN (v2)", () => {
|
|
130
|
+
// An alias is by definition a word the product does NOT use, so finding it
|
|
131
|
+
// in a generic file proves no contamination — while the framework's own
|
|
132
|
+
// neutral domain and plain computing English produce such collisions in
|
|
133
|
+
// bulk (eight false positives out of eighteen on the first real migration).
|
|
134
|
+
expect(
|
|
135
|
+
auditProductVocabulary({
|
|
136
|
+
vocabulary: VOCABULARY,
|
|
137
|
+
sourceFiles: [],
|
|
138
|
+
governedFiles: [
|
|
139
|
+
{ path: "AGENTS.md", content: "const widgetId = 1; // gizmo everywhere" },
|
|
140
|
+
],
|
|
141
|
+
}),
|
|
142
|
+
).toEqual([]);
|
|
127
143
|
});
|
|
128
144
|
|
|
129
145
|
it("un fichier gouverné strictement générique passe", () => {
|
package/src/vocabulary-audit.ts
CHANGED
|
@@ -8,10 +8,17 @@
|
|
|
8
8
|
* - PRODUCT SOURCE (B3): only forbidden ALIASES are hunted, and only in the
|
|
9
9
|
* machine identifiers — comments are blanked out first. The business prose
|
|
10
10
|
* of the project keeps its own words; the code has one term per concept.
|
|
11
|
-
* - GOVERNED FILES (B4):
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* - GOVERNED FILES (B4): the CANONICAL terms are hunted in the RAW text,
|
|
12
|
+
* comments and all. A governed file is identical in every Ogygie project, so
|
|
13
|
+
* it may know no product's domain at all, not even in a comment. That is the
|
|
14
|
+
* framework/product boundary made mechanical.
|
|
15
|
+
* Forbidden aliases are deliberately NOT hunted there (spec v2): an alias is
|
|
16
|
+
* by definition a word the product does NOT use, so finding one in a generic
|
|
17
|
+
* file proves no contamination — while the framework's own neutral domain
|
|
18
|
+
* (`orders`, `customerId`) and plain computing English (`level`, `register`)
|
|
19
|
+
* collide with it in bulk. Eight false positives out of eighteen on the first
|
|
20
|
+
* real migration, and a gate whose verdicts one learns to ignore protects
|
|
21
|
+
* nothing.
|
|
15
22
|
*
|
|
16
23
|
* The filesystem is injected (files come in as text), so the whole judgement
|
|
17
24
|
* is a pure function proven in memory with its mutations.
|
|
@@ -49,7 +56,11 @@ export interface VocabularyAuditInput {
|
|
|
49
56
|
readonly governedFiles: readonly ScannedFile[];
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Every root the vocabulary declares: canonical terms AND forbidden aliases.
|
|
61
|
+
* Kept for callers that need the full list; the governed-file rule uses the
|
|
62
|
+
* canonical terms alone (see above).
|
|
63
|
+
*/
|
|
53
64
|
export function vocabularyRootsOf(vocabulary: ProductVocabulary): readonly string[] {
|
|
54
65
|
return vocabulary.entries.flatMap((entry) => [entry.canonical, ...entry.forbiddenAliases]);
|
|
55
66
|
}
|
|
@@ -71,7 +82,7 @@ export function auditProductVocabulary(
|
|
|
71
82
|
|
|
72
83
|
const canonicalOfAlias = canonicalByAlias(vocabulary);
|
|
73
84
|
const forbiddenAliases = [...canonicalOfAlias.keys()];
|
|
74
|
-
const
|
|
85
|
+
const canonicalTerms = vocabulary.entries.map((entry) => entry.canonical);
|
|
75
86
|
const violations: VocabularyViolation[] = [];
|
|
76
87
|
|
|
77
88
|
for (const file of input.sourceFiles) {
|
|
@@ -86,7 +97,7 @@ export function auditProductVocabulary(
|
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
for (const file of input.governedFiles) {
|
|
89
|
-
for (const match of findProductVocabulary(file.content,
|
|
100
|
+
for (const match of findProductVocabulary(file.content, canonicalTerms)) {
|
|
90
101
|
violations.push({
|
|
91
102
|
kind: "GOVERNED_FILE",
|
|
92
103
|
filePath: file.path,
|