aisp-validator 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.
- package/LICENSE +21 -0
- package/README.md +136 -0
- package/bin/cli.js +103 -0
- package/browser/loader.js +127 -0
- package/package.json +50 -0
- package/src/index.js +137 -0
- package/wasm/aisp.h +112 -0
- package/wasm/aisp.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bradley Ross
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# AISP Validator
|
|
2
|
+
|
|
3
|
+
Validate [AISP 5.1](../AI_GUIDE.md) documents with <2% ambiguity using a <10KB WASM kernel.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### CLI
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Validate a file
|
|
11
|
+
npx aisp-validator validate spec.aisp
|
|
12
|
+
|
|
13
|
+
# Get quality tier
|
|
14
|
+
npx aisp-validator tier spec.aisp
|
|
15
|
+
|
|
16
|
+
# Get density score
|
|
17
|
+
npx aisp-validator density spec.aisp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Node.js
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import AISP from 'aisp-validator';
|
|
24
|
+
|
|
25
|
+
await AISP.init();
|
|
26
|
+
|
|
27
|
+
const result = AISP.validate(`
|
|
28
|
+
𝔸1.0.example@2026-01-14
|
|
29
|
+
γ≔test
|
|
30
|
+
|
|
31
|
+
⟦Ω:Meta⟧{ ∀D:Ambig(D)<0.02 }
|
|
32
|
+
⟦Σ:Types⟧{ T≜ℕ }
|
|
33
|
+
⟦Γ:Rules⟧{ ∀x:T:x≥0 }
|
|
34
|
+
⟦Λ:Funcs⟧{ f≜λx.x }
|
|
35
|
+
⟦Ε⟧⟨δ≜0.75;φ≜100;τ≜◊⁺⁺⟩
|
|
36
|
+
`);
|
|
37
|
+
|
|
38
|
+
console.log(result);
|
|
39
|
+
// { valid: true, tier: '◊⁺⁺', delta: 0.78, ambiguity: 0.01 }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Browser
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<script type="module">
|
|
46
|
+
import AISP from './browser/loader.js';
|
|
47
|
+
|
|
48
|
+
await AISP.init('/wasm/aisp.wasm');
|
|
49
|
+
|
|
50
|
+
const result = AISP.validate(document);
|
|
51
|
+
console.log(result.tier); // '◊⁺⁺'
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## API
|
|
56
|
+
|
|
57
|
+
### `AISP.init(wasmPath?)`
|
|
58
|
+
Initialize the WASM kernel. Call once before validation.
|
|
59
|
+
|
|
60
|
+
### `AISP.validate(source)`
|
|
61
|
+
Validate an AISP document. Returns:
|
|
62
|
+
```javascript
|
|
63
|
+
{
|
|
64
|
+
valid: boolean, // true if valid
|
|
65
|
+
tier: string, // '⊘' | '◊⁻' | '◊' | '◊⁺' | '◊⁺⁺'
|
|
66
|
+
tierValue: number, // 0-4
|
|
67
|
+
delta: number, // density δ [0, 1]
|
|
68
|
+
ambiguity: number, // [0, 1], must be <0.02
|
|
69
|
+
errorCode: number // 0 = success
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### `AISP.isValid(source)`
|
|
74
|
+
Quick check: returns `true` if valid.
|
|
75
|
+
|
|
76
|
+
### `AISP.getTier(source)`
|
|
77
|
+
Returns tier symbol: `'◊⁺⁺'`, `'◊⁺'`, `'◊'`, `'◊⁻'`, or `'⊘'`
|
|
78
|
+
|
|
79
|
+
### `AISP.getDensity(source)`
|
|
80
|
+
Returns density score (δ) between 0 and 1.
|
|
81
|
+
|
|
82
|
+
### `AISP.validateFile(path)` (Node.js only)
|
|
83
|
+
Validate a file by path.
|
|
84
|
+
|
|
85
|
+
## Quality Tiers
|
|
86
|
+
|
|
87
|
+
| Tier | Symbol | Threshold | Meaning |
|
|
88
|
+
|------|--------|-----------|---------|
|
|
89
|
+
| Platinum | ◊⁺⁺ | δ ≥ 0.75 | Production-ready |
|
|
90
|
+
| Gold | ◊⁺ | δ ≥ 0.60 | High quality |
|
|
91
|
+
| Silver | ◊ | δ ≥ 0.40 | Acceptable |
|
|
92
|
+
| Bronze | ◊⁻ | δ ≥ 0.20 | Needs improvement |
|
|
93
|
+
| Reject | ⊘ | δ < 0.20 | Insufficient AISP |
|
|
94
|
+
|
|
95
|
+
## Required AISP Blocks
|
|
96
|
+
|
|
97
|
+
Every valid AISP document must include:
|
|
98
|
+
|
|
99
|
+
- `⟦Ω⟧` - Meta/foundation
|
|
100
|
+
- `⟦Σ⟧` - Type definitions
|
|
101
|
+
- `⟦Γ⟧` - Inference rules
|
|
102
|
+
- `⟦Λ⟧` - Functions
|
|
103
|
+
- `⟦Ε⟧` - Evidence
|
|
104
|
+
|
|
105
|
+
## Building from Source
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Prerequisites
|
|
109
|
+
rustup target add wasm32-unknown-unknown
|
|
110
|
+
npm install -g binaryen
|
|
111
|
+
|
|
112
|
+
# Build
|
|
113
|
+
cd wasm
|
|
114
|
+
./build.sh
|
|
115
|
+
|
|
116
|
+
# Output: aisp.wasm (<10KB)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Architecture
|
|
120
|
+
|
|
121
|
+
The validator uses a Rust WASM kernel based on dependent type theory:
|
|
122
|
+
|
|
123
|
+
- **Zero-allocation**: Arena-based memory, no heap
|
|
124
|
+
- **Type checking**: Based on lean-agentic
|
|
125
|
+
- **Symbol table**: AISP Σ_512 glossary
|
|
126
|
+
- **Density computation**: AISP symbol ratio
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT License - see [LICENSE](./LICENSE)
|
|
131
|
+
|
|
132
|
+
## Links
|
|
133
|
+
|
|
134
|
+
- [AISP 5.1 Specification](../AI_GUIDE.md)
|
|
135
|
+
- [Reference (Rosetta Stone)](../reference.md)
|
|
136
|
+
- [Repository](https://github.com/bar181/aisp-open-core)
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AISP Validator CLI
|
|
4
|
+
* Usage: aisp-validator <command> [file]
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import AISP from '../src/index.js';
|
|
8
|
+
import { readFile } from 'fs/promises';
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
|
|
11
|
+
const HELP = `
|
|
12
|
+
AISP Validator - Validate AISP 5.1 documents
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
aisp-validator <command> [file]
|
|
16
|
+
aisp-validator [file] Shorthand for validate
|
|
17
|
+
|
|
18
|
+
Commands:
|
|
19
|
+
validate <file> Validate an AISP document
|
|
20
|
+
tier <file> Get quality tier (⊘ to ◊⁺⁺)
|
|
21
|
+
density <file> Get density score (δ)
|
|
22
|
+
help Show this help message
|
|
23
|
+
|
|
24
|
+
Quality Tiers:
|
|
25
|
+
◊⁺⁺ Platinum δ ≥ 0.75
|
|
26
|
+
◊⁺ Gold δ ≥ 0.60
|
|
27
|
+
◊ Silver δ ≥ 0.40
|
|
28
|
+
◊⁻ Bronze δ ≥ 0.20
|
|
29
|
+
⊘ Reject δ < 0.20
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
npx aisp-validator validate spec.aisp
|
|
33
|
+
npx aisp-validator tier spec.aisp
|
|
34
|
+
npx aisp-validator spec.aisp
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
async function main() {
|
|
38
|
+
const args = process.argv.slice(2);
|
|
39
|
+
|
|
40
|
+
if (args.length === 0 || args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
|
|
41
|
+
console.log(HELP);
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let command = args[0];
|
|
46
|
+
let file = args[1];
|
|
47
|
+
|
|
48
|
+
// If first arg is a file (no command), default to validate
|
|
49
|
+
if (command && !['validate', 'tier', 'density'].includes(command)) {
|
|
50
|
+
file = command;
|
|
51
|
+
command = 'validate';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!file) {
|
|
55
|
+
console.error('Error: No file specified');
|
|
56
|
+
console.log('Usage: aisp-validator <command> <file>');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!existsSync(file)) {
|
|
61
|
+
console.error(`Error: File not found: ${file}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
await AISP.init();
|
|
67
|
+
const content = await readFile(file, 'utf-8');
|
|
68
|
+
const result = AISP.validate(content);
|
|
69
|
+
|
|
70
|
+
switch (command) {
|
|
71
|
+
case 'validate':
|
|
72
|
+
if (result.valid) {
|
|
73
|
+
console.log(`✓ VALID`);
|
|
74
|
+
console.log(` Tier: ${result.tier}`);
|
|
75
|
+
console.log(` Density (δ): ${result.delta.toFixed(3)}`);
|
|
76
|
+
console.log(` Ambiguity: ${result.ambiguity.toFixed(3)}`);
|
|
77
|
+
process.exit(0);
|
|
78
|
+
} else {
|
|
79
|
+
console.log(`✗ INVALID`);
|
|
80
|
+
console.log(` Error: ${result.error || `Error code ${result.errorCode}`}`);
|
|
81
|
+
if (result.tier) {
|
|
82
|
+
console.log(` Tier: ${result.tier}`);
|
|
83
|
+
console.log(` Density (δ): ${result.delta.toFixed(3)}`);
|
|
84
|
+
}
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case 'tier':
|
|
90
|
+
console.log(result.tier);
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
case 'density':
|
|
94
|
+
console.log(result.delta.toFixed(4));
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
} catch (err) {
|
|
98
|
+
console.error(`Error: ${err.message}`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
main();
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AISP WASM Loader
|
|
3
|
+
* Minimal JavaScript interface for browser integration (<1KB minified)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const AISP = {
|
|
7
|
+
_instance: null,
|
|
8
|
+
_memory: null,
|
|
9
|
+
_allocPtr: 0x1000,
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Initialize AISP kernel
|
|
13
|
+
* @param {string} wasmUrl - URL to aisp.wasm file
|
|
14
|
+
* @returns {Promise<number>} 0 on success
|
|
15
|
+
*/
|
|
16
|
+
async init(wasmUrl = '/aisp.wasm') {
|
|
17
|
+
const response = await fetch(wasmUrl);
|
|
18
|
+
const bytes = await response.arrayBuffer();
|
|
19
|
+
|
|
20
|
+
const { instance } = await WebAssembly.instantiate(bytes, {
|
|
21
|
+
env: {
|
|
22
|
+
// Host memory allocator (optional)
|
|
23
|
+
host_alloc: (size, align) => {
|
|
24
|
+
const aligned = (this._allocPtr + align - 1) & ~(align - 1);
|
|
25
|
+
this._allocPtr = aligned + size;
|
|
26
|
+
return aligned;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this._instance = instance.exports;
|
|
32
|
+
this._memory = new Uint8Array(instance.exports.memory.buffer);
|
|
33
|
+
|
|
34
|
+
return this._instance.aisp_init();
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Validate AISP document
|
|
39
|
+
* @param {string} source - AISP source code
|
|
40
|
+
* @returns {object} Validation result
|
|
41
|
+
*/
|
|
42
|
+
validate(source) {
|
|
43
|
+
if (!this._instance) {
|
|
44
|
+
throw new Error('AISP not initialized. Call init() first.');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const encoder = new TextEncoder();
|
|
48
|
+
const bytes = encoder.encode(source);
|
|
49
|
+
|
|
50
|
+
// Write to parse buffer at offset 0x1000
|
|
51
|
+
const ptr = 0x1000;
|
|
52
|
+
if (bytes.length > 1024) {
|
|
53
|
+
return { valid: false, error: 'Document too large (max 1KB)' };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Refresh memory view in case it grew
|
|
57
|
+
this._memory = new Uint8Array(this._instance.memory.buffer);
|
|
58
|
+
this._memory.set(bytes, ptr);
|
|
59
|
+
|
|
60
|
+
// Parse document
|
|
61
|
+
const docId = this._instance.aisp_parse(ptr, bytes.length);
|
|
62
|
+
if (docId < 0) {
|
|
63
|
+
return {
|
|
64
|
+
valid: false,
|
|
65
|
+
error: `Parse error at offset ${this._instance.aisp_error_offset()}`,
|
|
66
|
+
errorCode: this._instance.aisp_error_code()
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Validate
|
|
71
|
+
const result = this._instance.aisp_validate(docId);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
valid: result === 0,
|
|
75
|
+
tier: this._getTierSymbol(this._instance.aisp_tier(docId)),
|
|
76
|
+
tierValue: this._instance.aisp_tier(docId),
|
|
77
|
+
delta: this._instance.aisp_density(docId),
|
|
78
|
+
ambiguity: this._instance.aisp_ambig(docId),
|
|
79
|
+
errorCode: result
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get tier symbol from numeric value
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
_getTierSymbol(tier) {
|
|
88
|
+
const symbols = ['⊘', '◊⁻', '◊', '◊⁺', '◊⁺⁺'];
|
|
89
|
+
return symbols[tier] || '⊘';
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Quick validation check
|
|
94
|
+
* @param {string} source - AISP source
|
|
95
|
+
* @returns {boolean} true if valid
|
|
96
|
+
*/
|
|
97
|
+
isValid(source) {
|
|
98
|
+
return this.validate(source).valid;
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get density score
|
|
103
|
+
* @param {string} source - AISP source
|
|
104
|
+
* @returns {number} density δ [0, 1]
|
|
105
|
+
*/
|
|
106
|
+
getDensity(source) {
|
|
107
|
+
return this.validate(source).delta;
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get quality tier
|
|
112
|
+
* @param {string} source - AISP source
|
|
113
|
+
* @returns {string} tier symbol
|
|
114
|
+
*/
|
|
115
|
+
getTier(source) {
|
|
116
|
+
return this.validate(source).tier;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Export for different environments
|
|
121
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
122
|
+
module.exports = AISP;
|
|
123
|
+
} else if (typeof window !== 'undefined') {
|
|
124
|
+
window.AISP = AISP;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export default AISP;
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aisp-validator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AISP 5.1 document validator - validates AI Symbolic Protocol specifications with <2% ambiguity",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"aisp-validator": "bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./src/index.js",
|
|
13
|
+
"require": "./src/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./browser": "./browser/loader.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src/",
|
|
19
|
+
"browser/",
|
|
20
|
+
"bin/",
|
|
21
|
+
"wasm/aisp.wasm",
|
|
22
|
+
"wasm/aisp.h"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"test": "node --test test/",
|
|
26
|
+
"build:wasm": "cd wasm && ./build.sh"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"aisp",
|
|
30
|
+
"validator",
|
|
31
|
+
"ai",
|
|
32
|
+
"specification",
|
|
33
|
+
"wasm",
|
|
34
|
+
"formal-methods",
|
|
35
|
+
"type-theory"
|
|
36
|
+
],
|
|
37
|
+
"author": "Bradley Ross",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/bar181/aisp-open-core"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/bar181/aisp-open-core#readme",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/bar181/aisp-open-core/issues"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AISP Validator - Node.js Entry Point
|
|
3
|
+
* Validates AISP 5.1 documents using the WASM kernel
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFile } from 'fs/promises';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { dirname, join } from 'path';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
|
|
13
|
+
const AISP = {
|
|
14
|
+
_instance: null,
|
|
15
|
+
_memory: null,
|
|
16
|
+
_allocPtr: 0x1000,
|
|
17
|
+
_initialized: false,
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Initialize AISP kernel
|
|
21
|
+
* @param {string} [wasmPath] - Optional path to aisp.wasm
|
|
22
|
+
* @returns {Promise<number>} 0 on success
|
|
23
|
+
*/
|
|
24
|
+
async init(wasmPath) {
|
|
25
|
+
if (this._initialized) return 0;
|
|
26
|
+
|
|
27
|
+
const path = wasmPath || join(__dirname, '..', 'wasm', 'aisp.wasm');
|
|
28
|
+
const bytes = await readFile(path);
|
|
29
|
+
|
|
30
|
+
const { instance } = await WebAssembly.instantiate(bytes, {
|
|
31
|
+
env: {
|
|
32
|
+
host_alloc: (size, align) => {
|
|
33
|
+
const aligned = (this._allocPtr + align - 1) & ~(align - 1);
|
|
34
|
+
this._allocPtr = aligned + size;
|
|
35
|
+
return aligned;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
this._instance = instance.exports;
|
|
41
|
+
this._memory = new Uint8Array(instance.exports.memory.buffer);
|
|
42
|
+
this._initialized = true;
|
|
43
|
+
|
|
44
|
+
return this._instance.aisp_init();
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Validate AISP document
|
|
49
|
+
* @param {string} source - AISP source code
|
|
50
|
+
* @returns {object} Validation result
|
|
51
|
+
*/
|
|
52
|
+
validate(source) {
|
|
53
|
+
if (!this._instance) {
|
|
54
|
+
throw new Error('AISP not initialized. Call init() first.');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const encoder = new TextEncoder();
|
|
58
|
+
const bytes = encoder.encode(source);
|
|
59
|
+
|
|
60
|
+
const ptr = 0x1000;
|
|
61
|
+
if (bytes.length > 1024) {
|
|
62
|
+
return { valid: false, error: 'Document too large (max 1KB)' };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this._memory = new Uint8Array(this._instance.memory.buffer);
|
|
66
|
+
this._memory.set(bytes, ptr);
|
|
67
|
+
|
|
68
|
+
const docId = this._instance.aisp_parse(ptr, bytes.length);
|
|
69
|
+
if (docId < 0) {
|
|
70
|
+
return {
|
|
71
|
+
valid: false,
|
|
72
|
+
error: `Parse error at offset ${this._instance.aisp_error_offset()}`,
|
|
73
|
+
errorCode: this._instance.aisp_error_code()
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const result = this._instance.aisp_validate(docId);
|
|
78
|
+
|
|
79
|
+
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),
|
|
84
|
+
ambiguity: this._instance.aisp_ambig(docId),
|
|
85
|
+
errorCode: result
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get tier symbol from numeric value
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
_getTierSymbol(tier) {
|
|
94
|
+
const symbols = ['⊘', '◊⁻', '◊', '◊⁺', '◊⁺⁺'];
|
|
95
|
+
return symbols[tier] || '⊘';
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Quick validation check
|
|
100
|
+
* @param {string} source - AISP source
|
|
101
|
+
* @returns {boolean} true if valid
|
|
102
|
+
*/
|
|
103
|
+
isValid(source) {
|
|
104
|
+
return this.validate(source).valid;
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get density score
|
|
109
|
+
* @param {string} source - AISP source
|
|
110
|
+
* @returns {number} density δ [0, 1]
|
|
111
|
+
*/
|
|
112
|
+
getDensity(source) {
|
|
113
|
+
return this.validate(source).delta;
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get quality tier
|
|
118
|
+
* @param {string} source - AISP source
|
|
119
|
+
* @returns {string} tier symbol
|
|
120
|
+
*/
|
|
121
|
+
getTier(source) {
|
|
122
|
+
return this.validate(source).tier;
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Validate file
|
|
127
|
+
* @param {string} filePath - Path to AISP file
|
|
128
|
+
* @returns {Promise<object>} Validation result
|
|
129
|
+
*/
|
|
130
|
+
async validateFile(filePath) {
|
|
131
|
+
const content = await readFile(filePath, 'utf-8');
|
|
132
|
+
return this.validate(content);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export default AISP;
|
|
137
|
+
export const { init, validate, isValid, getDensity, getTier, validateFile } = AISP;
|
package/wasm/aisp.h
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AISP WASM Kernel - C/C++ Header
|
|
3
|
+
* For chip integration (ESP32, RP2040, etc.)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#ifndef AISP_H
|
|
7
|
+
#define AISP_H
|
|
8
|
+
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
|
|
11
|
+
#ifdef __cplusplus
|
|
12
|
+
extern "C" {
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
/* ============================================================================
|
|
16
|
+
* Core API
|
|
17
|
+
* ============================================================================ */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Initialize AISP kernel
|
|
21
|
+
* Must be called before any other functions.
|
|
22
|
+
* @return 0 on success, <0 on error
|
|
23
|
+
*/
|
|
24
|
+
int32_t aisp_init(void);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parse AISP document from memory
|
|
28
|
+
* @param ptr Pointer to UTF-8 encoded AISP source
|
|
29
|
+
* @param len Length of source in bytes
|
|
30
|
+
* @return Document ID (0) on success, <0 on error
|
|
31
|
+
*/
|
|
32
|
+
int32_t aisp_parse(const uint8_t* ptr, uint32_t len);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Validate parsed document
|
|
36
|
+
* @param doc_id Document ID from aisp_parse
|
|
37
|
+
* @return 0 if valid, <0 on error
|
|
38
|
+
*/
|
|
39
|
+
int32_t aisp_validate(int32_t doc_id);
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get quality tier
|
|
43
|
+
* @param doc_id Document ID
|
|
44
|
+
* @return Tier value (0-4)
|
|
45
|
+
*/
|
|
46
|
+
int32_t aisp_tier(int32_t doc_id);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get ambiguity score
|
|
50
|
+
* @param doc_id Document ID
|
|
51
|
+
* @return Ambiguity [0.0, 1.0]
|
|
52
|
+
*/
|
|
53
|
+
float aisp_ambig(int32_t doc_id);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get density score (δ)
|
|
57
|
+
* @param doc_id Document ID
|
|
58
|
+
* @return Density [0.0, 1.0]
|
|
59
|
+
*/
|
|
60
|
+
float aisp_density(int32_t doc_id);
|
|
61
|
+
|
|
62
|
+
/* ============================================================================
|
|
63
|
+
* Error Handling
|
|
64
|
+
* ============================================================================ */
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get last error code
|
|
68
|
+
* @return Error code (0 = no error)
|
|
69
|
+
*/
|
|
70
|
+
int32_t aisp_error_code(void);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get error offset in input
|
|
74
|
+
* @return Byte offset where error occurred
|
|
75
|
+
*/
|
|
76
|
+
uint32_t aisp_error_offset(void);
|
|
77
|
+
|
|
78
|
+
/* ============================================================================
|
|
79
|
+
* Constants
|
|
80
|
+
* ============================================================================ */
|
|
81
|
+
|
|
82
|
+
/* Quality Tiers */
|
|
83
|
+
#define AISP_TIER_REJECT 0 /* ⊘: δ < 0.20 */
|
|
84
|
+
#define AISP_TIER_BRONZE 1 /* ◊⁻: δ ≥ 0.20 */
|
|
85
|
+
#define AISP_TIER_SILVER 2 /* ◊: δ ≥ 0.40 */
|
|
86
|
+
#define AISP_TIER_GOLD 3 /* ◊⁺: δ ≥ 0.60 */
|
|
87
|
+
#define AISP_TIER_PLATINUM 4 /* ◊⁺⁺: δ ≥ 0.75 */
|
|
88
|
+
|
|
89
|
+
/* Error Codes */
|
|
90
|
+
#define AISP_OK 0 /* Success */
|
|
91
|
+
#define AISP_ERR_PARSE -1 /* Parse error */
|
|
92
|
+
#define AISP_ERR_TYPE -2 /* Type error */
|
|
93
|
+
#define AISP_ERR_AMBIG -3 /* Ambiguity too high */
|
|
94
|
+
#define AISP_ERR_MEMORY -4 /* Memory error */
|
|
95
|
+
#define AISP_ERR_OVERFLOW -5 /* Buffer overflow */
|
|
96
|
+
|
|
97
|
+
/* Binding States (Δ⊗λ) */
|
|
98
|
+
#define AISP_BIND_CRASH 0 /* ⊥: Logic conflict */
|
|
99
|
+
#define AISP_BIND_NULL 1 /* ∅: Socket mismatch */
|
|
100
|
+
#define AISP_BIND_ADAPT 2 /* λ: Type mismatch */
|
|
101
|
+
#define AISP_BIND_ZERO 3 /* ⊤: Full compatibility */
|
|
102
|
+
|
|
103
|
+
/* Limits */
|
|
104
|
+
#define AISP_MAX_DOC_SIZE 1024 /* Maximum document size in bytes */
|
|
105
|
+
#define AISP_MAX_TERMS 128 /* Maximum unique terms */
|
|
106
|
+
#define AISP_MAX_DEPTH 32 /* Maximum context depth */
|
|
107
|
+
|
|
108
|
+
#ifdef __cplusplus
|
|
109
|
+
}
|
|
110
|
+
#endif
|
|
111
|
+
|
|
112
|
+
#endif /* AISP_H */
|
package/wasm/aisp.wasm
ADDED
|
Binary file
|