aisp-validator 0.1.0 → 0.2.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 (3) hide show
  1. package/bin/cli.js +49 -10
  2. package/package.json +1 -1
  3. package/src/index.js +98 -7
package/bin/cli.js CHANGED
@@ -9,7 +9,7 @@ import { readFile } from 'fs/promises';
9
9
  import { existsSync } from 'fs';
10
10
 
11
11
  const HELP = `
12
- AISP Validator - Validate AISP 5.1 documents
12
+ AISP Validator v0.2.0 - Validate AISP 5.1 documents
13
13
 
14
14
  Usage:
15
15
  aisp-validator <command> [file]
@@ -19,6 +19,7 @@ Commands:
19
19
  validate <file> Validate an AISP document
20
20
  tier <file> Get quality tier (⊘ to ◊⁺⁺)
21
21
  density <file> Get density score (δ)
22
+ debug <file> Show detailed density breakdown
22
23
  help Show this help message
23
24
 
24
25
  Quality Tiers:
@@ -28,10 +29,16 @@ Quality Tiers:
28
29
  ◊⁻ Bronze δ ≥ 0.20
29
30
  ⊘ Reject δ < 0.20
30
31
 
32
+ Density Formula:
33
+ δ = (blockScore × 0.4) + (bindingScore × 0.6)
34
+
35
+ blockScore: Required blocks present (⟦Ω⟧, ⟦Σ⟧, ⟦Γ⟧, ⟦Λ⟧, ⟦Ε⟧)
36
+ bindingScore: Semantic operators (≜, ≔, ∀, ∃, λ, ⇒, ∈, etc.)
37
+
31
38
  Examples:
32
39
  npx aisp-validator validate spec.aisp
33
40
  npx aisp-validator tier spec.aisp
34
- npx aisp-validator spec.aisp
41
+ npx aisp-validator debug spec.aisp
35
42
  `;
36
43
 
37
44
  async function main() {
@@ -42,11 +49,16 @@ async function main() {
42
49
  process.exit(0);
43
50
  }
44
51
 
52
+ if (args[0] === '--version' || args[0] === '-v') {
53
+ console.log('aisp-validator v0.2.0');
54
+ process.exit(0);
55
+ }
56
+
45
57
  let command = args[0];
46
58
  let file = args[1];
47
59
 
48
60
  // If first arg is a file (no command), default to validate
49
- if (command && !['validate', 'tier', 'density'].includes(command)) {
61
+ if (command && !['validate', 'tier', 'density', 'debug'].includes(command)) {
50
62
  file = command;
51
63
  command = 'validate';
52
64
  }
@@ -65,13 +77,13 @@ async function main() {
65
77
  try {
66
78
  await AISP.init();
67
79
  const content = await readFile(file, 'utf-8');
68
- const result = AISP.validate(content);
69
80
 
70
81
  switch (command) {
71
- case 'validate':
82
+ case 'validate': {
83
+ const result = AISP.validate(content);
72
84
  if (result.valid) {
73
85
  console.log(`✓ VALID`);
74
- console.log(` Tier: ${result.tier}`);
86
+ console.log(` Tier: ${result.tier} ${result.tierName}`);
75
87
  console.log(` Density (δ): ${result.delta.toFixed(3)}`);
76
88
  console.log(` Ambiguity: ${result.ambiguity.toFixed(3)}`);
77
89
  process.exit(0);
@@ -79,20 +91,47 @@ async function main() {
79
91
  console.log(`✗ INVALID`);
80
92
  console.log(` Error: ${result.error || `Error code ${result.errorCode}`}`);
81
93
  if (result.tier) {
82
- console.log(` Tier: ${result.tier}`);
94
+ console.log(` Tier: ${result.tier} ${result.tierName}`);
83
95
  console.log(` Density (δ): ${result.delta.toFixed(3)}`);
84
96
  }
85
97
  process.exit(1);
86
98
  }
87
99
  break;
100
+ }
88
101
 
89
- case 'tier':
90
- console.log(result.tier);
102
+ case 'tier': {
103
+ const result = AISP.validate(content);
104
+ console.log(`${result.tier} ${result.tierName}`);
91
105
  break;
106
+ }
92
107
 
93
- case 'density':
108
+ case 'density': {
109
+ const result = AISP.validate(content);
94
110
  console.log(result.delta.toFixed(4));
95
111
  break;
112
+ }
113
+
114
+ case 'debug': {
115
+ const debug = AISP.debug(content);
116
+ console.log(`\nAISP Density Debug`);
117
+ console.log(`==================`);
118
+ console.log(`\nTier: ${debug.tier} ${debug.tierName}`);
119
+ console.log(`Density (δ): ${debug.delta.toFixed(3)}`);
120
+ console.log(`\nScore Breakdown:`);
121
+ console.log(` Block Score: ${(debug.blockScore * 100).toFixed(1)}% (weight: 40%)`);
122
+ console.log(` Binding Score: ${(debug.bindingScore * 100).toFixed(1)}% (weight: 60%)`);
123
+ console.log(`\nBlocks Found: ${debug.breakdown.blocksFound}/${debug.breakdown.blocksRequired}`);
124
+ console.log(` Required: ⟦Ω⟧, ⟦Σ⟧, ⟦Γ⟧, ⟦Λ⟧, ⟦Ε⟧`);
125
+ console.log(`\nSemantic Operators: ${debug.breakdown.totalBindings}`);
126
+ console.log(` ≜ definitions: ${debug.breakdown.definitions}`);
127
+ console.log(` ≔ assignments: ${debug.breakdown.assignments}`);
128
+ console.log(` ∀∃ quantifiers: ${debug.breakdown.quantifiers}`);
129
+ console.log(` λ lambdas: ${debug.breakdown.lambdas}`);
130
+ console.log(` ⇒⇔ implications: ${debug.breakdown.implications}`);
131
+ console.log(` ∈⊆∩∪ set ops: ${debug.breakdown.setOps}`);
132
+ console.log(`\nFormula: δ = (${debug.blockScore.toFixed(2)} × 0.4) + (${debug.bindingScore.toFixed(2)} × 0.6) = ${debug.delta.toFixed(3)}`);
133
+ break;
134
+ }
96
135
  }
97
136
  } catch (err) {
98
137
  console.error(`Error: ${err.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aisp-validator",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "AISP 5.1 document validator - validates AI Symbolic Protocol specifications with <2% ambiguity",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/index.js CHANGED
@@ -10,6 +10,63 @@ import { dirname, join } from 'path';
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = dirname(__filename);
12
12
 
13
+ /**
14
+ * Calculate semantic density using Block Coverage + Binding Density
15
+ * δ = (blockScore × 0.4) + (bindingScore × 0.6)
16
+ * @param {string} text - AISP source
17
+ * @returns {object} { delta, blockScore, bindingScore, breakdown }
18
+ */
19
+ function calculateSemanticDensity(text) {
20
+ // Required blocks present?
21
+ const blocks = ['⟦Ω', '⟦Σ', '⟦Γ', '⟦Λ', '⟦Ε'];
22
+ const blocksFound = blocks.filter(b => text.includes(b));
23
+ const blockScore = blocksFound.length / blocks.length;
24
+
25
+ // Binding density (semantic operators)
26
+ const definitions = (text.match(/≜/g) || []).length;
27
+ const assignments = (text.match(/≔/g) || []).length;
28
+ const quantifiers = (text.match(/[∀∃]/g) || []).length;
29
+ const lambdas = (text.match(/λ/g) || []).length;
30
+ const implications = (text.match(/[⇒⇔→↔]/g) || []).length;
31
+ const setOps = (text.match(/[∈⊆∩∪∅]/g) || []).length;
32
+
33
+ const totalBindings = definitions + assignments + quantifiers + lambdas + implications + setOps;
34
+ const bindingScore = Math.min(1, totalBindings / 20);
35
+
36
+ // Combined score
37
+ const delta = (blockScore * 0.4) + (bindingScore * 0.6);
38
+
39
+ return {
40
+ delta,
41
+ blockScore,
42
+ bindingScore,
43
+ breakdown: {
44
+ blocksFound: blocksFound.length,
45
+ blocksRequired: blocks.length,
46
+ definitions,
47
+ assignments,
48
+ quantifiers,
49
+ lambdas,
50
+ implications,
51
+ setOps,
52
+ totalBindings
53
+ }
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Get tier from delta value
59
+ * @param {number} delta
60
+ * @returns {object} { tier, tierValue, tierName }
61
+ */
62
+ function getTierFromDelta(delta) {
63
+ if (delta >= 0.75) return { tier: '◊⁺⁺', tierValue: 4, tierName: 'Platinum' };
64
+ if (delta >= 0.60) return { tier: '◊⁺', tierValue: 3, tierName: 'Gold' };
65
+ if (delta >= 0.40) return { tier: '◊', tierValue: 2, tierName: 'Silver' };
66
+ if (delta >= 0.20) return { tier: '◊⁻', tierValue: 1, tierName: 'Bronze' };
67
+ return { tier: '⊘', tierValue: 0, tierName: 'Reject' };
68
+ }
69
+
13
70
  const AISP = {
14
71
  _instance: null,
15
72
  _memory: null,
@@ -74,15 +131,38 @@ const AISP = {
74
131
  };
75
132
  }
76
133
 
77
- const result = this._instance.aisp_validate(docId);
134
+ const parseResult = this._instance.aisp_validate(docId);
135
+
136
+ // Use semantic density calculation instead of WASM density
137
+ const densityResult = calculateSemanticDensity(source);
138
+ const tierResult = getTierFromDelta(densityResult.delta);
78
139
 
79
140
  return {
80
- valid: result === 0,
81
- tier: this._getTierSymbol(this._instance.aisp_tier(docId)),
82
- tierValue: this._instance.aisp_tier(docId),
83
- delta: this._instance.aisp_density(docId),
141
+ valid: parseResult === 0,
142
+ tier: tierResult.tier,
143
+ tierValue: tierResult.tierValue,
144
+ tierName: tierResult.tierName,
145
+ delta: densityResult.delta,
84
146
  ambiguity: this._instance.aisp_ambig(docId),
85
- errorCode: result
147
+ errorCode: parseResult
148
+ };
149
+ },
150
+
151
+ /**
152
+ * Get detailed density breakdown for debugging
153
+ * @param {string} source - AISP source
154
+ * @returns {object} Detailed breakdown
155
+ */
156
+ debug(source) {
157
+ const densityResult = calculateSemanticDensity(source);
158
+ const tierResult = getTierFromDelta(densityResult.delta);
159
+
160
+ return {
161
+ ...tierResult,
162
+ delta: densityResult.delta,
163
+ blockScore: densityResult.blockScore,
164
+ bindingScore: densityResult.bindingScore,
165
+ breakdown: densityResult.breakdown
86
166
  };
87
167
  },
88
168
 
@@ -130,8 +210,19 @@ const AISP = {
130
210
  async validateFile(filePath) {
131
211
  const content = await readFile(filePath, 'utf-8');
132
212
  return this.validate(content);
213
+ },
214
+
215
+ /**
216
+ * Debug file - show density breakdown
217
+ * @param {string} filePath - Path to AISP file
218
+ * @returns {Promise<object>} Debug breakdown
219
+ */
220
+ async debugFile(filePath) {
221
+ const content = await readFile(filePath, 'utf-8');
222
+ return this.debug(content);
133
223
  }
134
224
  };
135
225
 
136
226
  export default AISP;
137
- export const { init, validate, isValid, getDensity, getTier, validateFile } = AISP;
227
+ export const { init, validate, isValid, getDensity, getTier, validateFile, debug, debugFile } = AISP;
228
+ export { calculateSemanticDensity, getTierFromDelta };