cgd-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/README.md +91 -0
- package/bin/cli.js +105 -0
- package/index.js +162 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# cgd-validator
|
|
2
|
+
|
|
3
|
+
Validator for Clarity-Gated Document (`.cgd`) files — documents verified and annotated for safe LLM ingestion.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/cgd-validator)
|
|
6
|
+
[](https://creativecommons.org/licenses/by/4.0/)
|
|
7
|
+
|
|
8
|
+
## What is a .cgd file?
|
|
9
|
+
|
|
10
|
+
A **Clarity-Gated Document** (`.cgd`) file is a markdown document that has passed epistemic verification and contains inline annotations ensuring safe interpretation by LLMs.
|
|
11
|
+
|
|
12
|
+
Part of the [Clarity Gate](https://github.com/frmoretto/clarity-gate) ecosystem for epistemic quality verification.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g cgd-validator
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## CLI Usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Validate a single file
|
|
24
|
+
cgd-validator document.cgd
|
|
25
|
+
|
|
26
|
+
# Validate multiple files
|
|
27
|
+
cgd-validator docs/*.cgd
|
|
28
|
+
|
|
29
|
+
# Output as JSON
|
|
30
|
+
cgd-validator document.cgd --json
|
|
31
|
+
|
|
32
|
+
# Quiet mode (errors only)
|
|
33
|
+
cgd-validator document.cgd -q
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API Usage
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
const { validate, isValid, detect } = require('cgd-validator');
|
|
40
|
+
|
|
41
|
+
// Full validation with errors and warnings
|
|
42
|
+
const result = validate(fileContent);
|
|
43
|
+
console.log(result.valid); // boolean
|
|
44
|
+
console.log(result.errors); // array of error objects
|
|
45
|
+
console.log(result.warnings); // array of warning objects
|
|
46
|
+
console.log(result.frontmatter); // parsed YAML frontmatter
|
|
47
|
+
|
|
48
|
+
// Quick check
|
|
49
|
+
if (isValid(fileContent)) {
|
|
50
|
+
console.log('Document passes validation');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Detect if content is .cgd format
|
|
54
|
+
if (detect(fileContent)) {
|
|
55
|
+
console.log('This appears to be a .cgd file');
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Validation Rules
|
|
60
|
+
|
|
61
|
+
### Required Elements
|
|
62
|
+
- YAML frontmatter with:
|
|
63
|
+
- `clarity-gate-version`
|
|
64
|
+
- `verified-date`
|
|
65
|
+
- `verified-by`
|
|
66
|
+
- `hitl-status`
|
|
67
|
+
- `## Clarity Gate Verification` section
|
|
68
|
+
|
|
69
|
+
### Warnings
|
|
70
|
+
- HITL status not "CONFIRMED"
|
|
71
|
+
- Projections ("will be") without `*(projected)*` marker
|
|
72
|
+
- Vague quantifiers without annotation
|
|
73
|
+
|
|
74
|
+
## Related
|
|
75
|
+
|
|
76
|
+
- [Clarity Gate](https://github.com/frmoretto/clarity-gate) - Pre-ingestion verification for RAG systems
|
|
77
|
+
- [Source of Truth Creator](https://github.com/frmoretto/source-of-truth-creator) - Create .sot files
|
|
78
|
+
- [sot-validator](https://www.npmjs.com/package/sot-validator) - Validate .sot files
|
|
79
|
+
|
|
80
|
+
## File Format Specification
|
|
81
|
+
|
|
82
|
+
See the [SOT and CGD File Format Specification](https://github.com/frmoretto/clarity-gate/blob/main/docs/FILE_FORMAT_SPEC.md).
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
CC BY 4.0 — Use freely with attribution.
|
|
87
|
+
|
|
88
|
+
## Author
|
|
89
|
+
|
|
90
|
+
Francesco Marinoni Moretto
|
|
91
|
+
GitHub: [@frmoretto](https://github.com/frmoretto)
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* cgd-validator CLI
|
|
5
|
+
* Validate Clarity-Gated Document (.cgd) files from the command line
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { validate, VERSION } = require('../index.js');
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
15
|
+
console.log(`cgd-validator v${VERSION}`);
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (args.includes('--help') || args.includes('-h') || args.length === 0) {
|
|
20
|
+
console.log(`
|
|
21
|
+
cgd-validator v${VERSION}
|
|
22
|
+
Validate Clarity-Gated Document (.cgd) files for LLM-safe ingestion
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
cgd-validator <file.cgd> [options]
|
|
26
|
+
cgd-validator <file.cgd> <file2.cgd> ...
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
-h, --help Show this help message
|
|
30
|
+
-v, --version Show version number
|
|
31
|
+
-q, --quiet Only output errors (no warnings)
|
|
32
|
+
--json Output results as JSON
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
cgd-validator document.cgd
|
|
36
|
+
cgd-validator docs/*.cgd --json
|
|
37
|
+
|
|
38
|
+
Part of the Clarity Gate ecosystem:
|
|
39
|
+
https://github.com/frmoretto/clarity-gate
|
|
40
|
+
|
|
41
|
+
File Format Specification:
|
|
42
|
+
https://github.com/frmoretto/clarity-gate/docs/FILE_FORMAT_SPEC.md
|
|
43
|
+
`);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const quiet = args.includes('-q') || args.includes('--quiet');
|
|
48
|
+
const json = args.includes('--json');
|
|
49
|
+
const files = args.filter(a => !a.startsWith('-'));
|
|
50
|
+
|
|
51
|
+
if (files.length === 0) {
|
|
52
|
+
console.error('Error: No files specified');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let hasErrors = false;
|
|
57
|
+
const results = [];
|
|
58
|
+
|
|
59
|
+
for (const file of files) {
|
|
60
|
+
const filePath = path.resolve(file);
|
|
61
|
+
|
|
62
|
+
if (!fs.existsSync(filePath)) {
|
|
63
|
+
console.error(`Error: File not found: ${file}`);
|
|
64
|
+
hasErrors = true;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
69
|
+
const result = validate(content);
|
|
70
|
+
result.file = file;
|
|
71
|
+
results.push(result);
|
|
72
|
+
|
|
73
|
+
if (!result.valid) {
|
|
74
|
+
hasErrors = true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!json) {
|
|
78
|
+
if (result.valid && result.warnings.length === 0) {
|
|
79
|
+
console.log(`✓ ${file}: PASS`);
|
|
80
|
+
} else if (result.valid) {
|
|
81
|
+
console.log(`⚠ ${file}: PASS with warnings`);
|
|
82
|
+
if (!quiet) {
|
|
83
|
+
result.warnings.forEach(w => {
|
|
84
|
+
console.log(` Warning: ${w.message}`);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
console.log(`✗ ${file}: FAIL`);
|
|
89
|
+
result.errors.forEach(e => {
|
|
90
|
+
console.log(` Error: ${e.message}`);
|
|
91
|
+
});
|
|
92
|
+
if (!quiet) {
|
|
93
|
+
result.warnings.forEach(w => {
|
|
94
|
+
console.log(` Warning: ${w.message}`);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (json) {
|
|
102
|
+
console.log(JSON.stringify(results, null, 2));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
process.exit(hasErrors ? 1 : 0);
|
package/index.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cgd-validator
|
|
3
|
+
*
|
|
4
|
+
* Validator for Clarity-Gated Document (.cgd) files
|
|
5
|
+
* Documents verified and annotated for safe LLM ingestion
|
|
6
|
+
*
|
|
7
|
+
* Part of the Clarity Gate ecosystem:
|
|
8
|
+
* - .sot (Source of Truth) - Authoritative reference documents
|
|
9
|
+
* - .cgd (Clarity-Gated Document) - Verified for LLM ingestion
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/frmoretto/clarity-gate
|
|
12
|
+
* @license CC-BY-4.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const VERSION = '0.1.0';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Parse YAML frontmatter from CGD file
|
|
19
|
+
* @param {string} content - The file content
|
|
20
|
+
* @returns {Object|null} Parsed frontmatter or null
|
|
21
|
+
*/
|
|
22
|
+
function parseFrontmatter(content) {
|
|
23
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
24
|
+
if (!match) return null;
|
|
25
|
+
|
|
26
|
+
const frontmatter = {};
|
|
27
|
+
const lines = match[1].split('\n');
|
|
28
|
+
|
|
29
|
+
for (const line of lines) {
|
|
30
|
+
const [key, ...valueParts] = line.split(':');
|
|
31
|
+
if (key && valueParts.length) {
|
|
32
|
+
frontmatter[key.trim()] = valueParts.join(':').trim();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return frontmatter;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validate a Clarity-Gated Document (.cgd) file
|
|
41
|
+
* @param {string} content - The file content to validate
|
|
42
|
+
* @returns {ValidationResult} Validation result with errors and warnings
|
|
43
|
+
*/
|
|
44
|
+
function validate(content) {
|
|
45
|
+
const errors = [];
|
|
46
|
+
const warnings = [];
|
|
47
|
+
|
|
48
|
+
// Required: YAML frontmatter
|
|
49
|
+
const frontmatter = parseFrontmatter(content);
|
|
50
|
+
if (!frontmatter) {
|
|
51
|
+
errors.push({
|
|
52
|
+
code: 'MISSING_FRONTMATTER',
|
|
53
|
+
message: 'Document must contain YAML frontmatter (--- block)',
|
|
54
|
+
line: 1
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
// Required frontmatter fields
|
|
58
|
+
if (!frontmatter['clarity-gate-version']) {
|
|
59
|
+
errors.push({
|
|
60
|
+
code: 'MISSING_VERSION',
|
|
61
|
+
message: 'Frontmatter must contain "clarity-gate-version"',
|
|
62
|
+
line: 1
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!frontmatter['verified-date']) {
|
|
67
|
+
errors.push({
|
|
68
|
+
code: 'MISSING_VERIFIED_DATE',
|
|
69
|
+
message: 'Frontmatter must contain "verified-date"',
|
|
70
|
+
line: 1
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!frontmatter['verified-by']) {
|
|
75
|
+
errors.push({
|
|
76
|
+
code: 'MISSING_VERIFIED_BY',
|
|
77
|
+
message: 'Frontmatter must contain "verified-by"',
|
|
78
|
+
line: 1
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!frontmatter['hitl-status']) {
|
|
83
|
+
errors.push({
|
|
84
|
+
code: 'MISSING_HITL_STATUS',
|
|
85
|
+
message: 'Frontmatter must contain "hitl-status"',
|
|
86
|
+
line: 1
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Warning: HITL not confirmed
|
|
91
|
+
if (frontmatter['hitl-status'] && frontmatter['hitl-status'] !== 'CONFIRMED') {
|
|
92
|
+
warnings.push({
|
|
93
|
+
code: 'HITL_NOT_CONFIRMED',
|
|
94
|
+
message: `HITL status is "${frontmatter['hitl-status']}" - should be "CONFIRMED" for full validation`,
|
|
95
|
+
line: 1
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Required: Verification summary at end
|
|
101
|
+
if (!content.includes('## Clarity Gate Verification')) {
|
|
102
|
+
errors.push({
|
|
103
|
+
code: 'MISSING_VERIFICATION_SUMMARY',
|
|
104
|
+
message: 'Document must contain "## Clarity Gate Verification" section',
|
|
105
|
+
line: null
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Warning: Projections without markers
|
|
110
|
+
if (content.match(/will be|will reach|will reduce/i) && !content.match(/\*\(projected/i)) {
|
|
111
|
+
warnings.push({
|
|
112
|
+
code: 'UNMARKED_PROJECTION',
|
|
113
|
+
message: 'Document contains "will be/reach/reduce" without *(projected)* marker',
|
|
114
|
+
line: null
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Warning: Vague quantifiers without annotation
|
|
119
|
+
const vagueQuantifiers = content.match(/\b(several|many|most|some)\b(?!\s*\*\()/gi);
|
|
120
|
+
if (vagueQuantifiers && vagueQuantifiers.length > 0) {
|
|
121
|
+
warnings.push({
|
|
122
|
+
code: 'UNMARKED_VAGUE_QUANTIFIER',
|
|
123
|
+
message: `Found ${vagueQuantifiers.length} vague quantifier(s) without annotation (several, many, most, some)`,
|
|
124
|
+
line: null
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
valid: errors.length === 0,
|
|
130
|
+
errors,
|
|
131
|
+
warnings,
|
|
132
|
+
frontmatter,
|
|
133
|
+
version: VERSION
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Check if content is a valid .cgd file
|
|
139
|
+
* @param {string} content - The file content to check
|
|
140
|
+
* @returns {boolean} True if valid
|
|
141
|
+
*/
|
|
142
|
+
function isValid(content) {
|
|
143
|
+
return validate(content).valid;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Detect if a file is a .cgd file based on content
|
|
148
|
+
* @param {string} content - The file content
|
|
149
|
+
* @returns {boolean} True if appears to be .cgd format
|
|
150
|
+
*/
|
|
151
|
+
function detect(content) {
|
|
152
|
+
const frontmatter = parseFrontmatter(content);
|
|
153
|
+
return frontmatter && frontmatter['clarity-gate-version'];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
module.exports = {
|
|
157
|
+
validate,
|
|
158
|
+
isValid,
|
|
159
|
+
detect,
|
|
160
|
+
parseFrontmatter,
|
|
161
|
+
VERSION
|
|
162
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cgd-validator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Validator for Clarity-Gated Document (.cgd) files - verified documents for safe LLM ingestion",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cgd-validator": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Tests coming soon\" && exit 0"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"cgd",
|
|
15
|
+
"clarity-gate",
|
|
16
|
+
"validator",
|
|
17
|
+
"epistemic",
|
|
18
|
+
"ai-safety",
|
|
19
|
+
"rag",
|
|
20
|
+
"documentation",
|
|
21
|
+
"llm",
|
|
22
|
+
"verification"
|
|
23
|
+
],
|
|
24
|
+
"author": "Francesco Marinoni Moretto",
|
|
25
|
+
"license": "CC-BY-4.0",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/frmoretto/cgd-validator"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/frmoretto/clarity-gate",
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/frmoretto/clarity-gate/issues"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=16.0.0"
|
|
36
|
+
}
|
|
37
|
+
}
|