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.
Files changed (4) hide show
  1. package/README.md +91 -0
  2. package/bin/cli.js +105 -0
  3. package/index.js +162 -0
  4. 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
+ [![npm version](https://badge.fury.io/js/cgd-validator.svg)](https://www.npmjs.com/package/cgd-validator)
6
+ [![License: CC BY 4.0](https://img.shields.io/badge/License-CC_BY_4.0-lightgrey.svg)](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
+ }