@josfox/jos 4.0.4 → 4.0.6

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.
@@ -0,0 +1,190 @@
1
+ /**
2
+ * JOS VALIDATE Command - Validate .jos artifacts
3
+ * Checks schema, required keys, and integrity
4
+ * Format version v0.0.7 — Specification maturity v0.1.0 (Alpha)
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const crypto = require('crypto');
10
+
11
+ const C = {
12
+ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
13
+ purple: '\x1b[38;5;135m', cyan: '\x1b[38;5;51m',
14
+ green: '\x1b[38;5;78m', red: '\x1b[38;5;196m',
15
+ yellow: '\x1b[38;5;220m', gray: '\x1b[38;5;245m'
16
+ };
17
+
18
+ // Witness Logging
19
+ function logWitness(home, eventType, data) {
20
+ const runId = global.JOS_VALIDATE_ID || new Date().toISOString().replace(/[:.]/g, '-');
21
+ global.JOS_VALIDATE_ID = runId;
22
+
23
+ const runDir = path.join(home, 'runs', runId);
24
+ if (!fs.existsSync(runDir)) fs.mkdirSync(runDir, { recursive: true });
25
+
26
+ const event = {
27
+ timestamp: new Date().toISOString(),
28
+ type: `validate:${eventType}`,
29
+ ...data
30
+ };
31
+
32
+ fs.appendFileSync(path.join(runDir, 'events.jsonl'), JSON.stringify(event) + '\n');
33
+ }
34
+
35
+ // Required keys for JOSFOXAI + MAGIC compliance
36
+ const JOSFOXAI_KEYS = ['jos', 'orchestration_contract', 'security', 'files', 'orchestration', 'x_run_params', 'adaptive_ai', 'id_jos'];
37
+ const MAGIC_KEYS = ['meta', 'artifacts', 'guardrails', 'intention', 'capabilities'];
38
+ const ALL_REQUIRED_KEYS = [...JOSFOXAI_KEYS, ...MAGIC_KEYS];
39
+
40
+ exports.execute = async (args, home) => {
41
+ const target = args[0];
42
+ const insecure = args.includes('--insecure');
43
+ const verbose = args.includes('--verbose') || args.includes('-v');
44
+
45
+ if (!target || args.includes('--help')) {
46
+ console.log(`
47
+ ${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
48
+ ${C.bold}JOS VALIDATE${C.reset} // Validate .jos artifacts
49
+ ${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}
50
+
51
+ ${C.bold}Usage:${C.reset}
52
+ jos validate <file.jos> [options]
53
+
54
+ ${C.bold}Options:${C.reset}
55
+ --insecure Skip integrity verification
56
+ --verbose Show detailed validation information
57
+
58
+ ${C.bold}Validates:${C.reset}
59
+ 1. JSON syntax
60
+ 2. JOSFOXAI keys: ${JOSFOXAI_KEYS.join(', ')}
61
+ 3. MAGIC keys: ${MAGIC_KEYS.join(', ')}
62
+ 4. Integrity manifest (unless --insecure)
63
+ `);
64
+ return;
65
+ }
66
+
67
+ console.log(`\n${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
68
+ console.log(`${C.bold}JOS VALIDATE${C.reset} // ${C.gray}Format v0.0.7 — Spec v0.1.0 (Alpha)${C.reset}`);
69
+ console.log(`${C.purple}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C.reset}`);
70
+ console.log(`\n${C.cyan}📋 Artifact:${C.reset} ${target}`);
71
+
72
+ logWitness(home, 'start', { artifact: target });
73
+
74
+ let allPassed = true;
75
+ const results = [];
76
+
77
+ // 1. JSON Syntax Check
78
+ let content, artifact;
79
+ try {
80
+ content = fs.readFileSync(target, 'utf8');
81
+ artifact = JSON.parse(content);
82
+ console.log(`${C.green} ✓ JSON Syntax Valid${C.reset}`);
83
+ results.push({ check: 'json_syntax', passed: true });
84
+ logWitness(home, 'check_passed', { check: 'json_syntax' });
85
+ } catch (e) {
86
+ console.log(`${C.red} ✖ JSON Error: ${e.message}${C.reset}`);
87
+ results.push({ check: 'json_syntax', passed: false, error: e.message });
88
+ logWitness(home, 'check_failed', { check: 'json_syntax', error: e.message });
89
+ process.exit(1);
90
+ }
91
+
92
+ // 2. JOSFOXAI Keys Check
93
+ const missingJosfoxai = JOSFOXAI_KEYS.filter(k => !artifact[k]);
94
+ if (missingJosfoxai.length > 0) {
95
+ console.log(`${C.red} ✖ Missing JOSFOXAI Keys: ${missingJosfoxai.join(', ')}${C.reset}`);
96
+ results.push({ check: 'josfoxai_keys', passed: false, missing: missingJosfoxai });
97
+ logWitness(home, 'check_failed', { check: 'josfoxai_keys', missing: missingJosfoxai });
98
+ allPassed = false;
99
+ } else {
100
+ console.log(`${C.green} ✓ JOSFOXAI Keys Present (${JOSFOXAI_KEYS.length}/${JOSFOXAI_KEYS.length})${C.reset}`);
101
+ results.push({ check: 'josfoxai_keys', passed: true });
102
+ logWitness(home, 'check_passed', { check: 'josfoxai_keys' });
103
+ }
104
+
105
+ // 3. MAGIC Keys Check
106
+ const missingMagic = MAGIC_KEYS.filter(k => !artifact[k]);
107
+ if (missingMagic.length > 0) {
108
+ console.log(`${C.red} ✖ Missing MAGIC Keys: ${missingMagic.join(', ')}${C.reset}`);
109
+ results.push({ check: 'magic_keys', passed: false, missing: missingMagic });
110
+ logWitness(home, 'check_failed', { check: 'magic_keys', missing: missingMagic });
111
+ allPassed = false;
112
+ } else {
113
+ console.log(`${C.green} ✓ MAGIC Keys Present (${MAGIC_KEYS.length}/${MAGIC_KEYS.length})${C.reset}`);
114
+ results.push({ check: 'magic_keys', passed: true });
115
+ logWitness(home, 'check_passed', { check: 'magic_keys' });
116
+ }
117
+
118
+ // 4. Orchestration Structure Check
119
+ if (artifact.orchestration) {
120
+ const hasDefinitions = artifact.orchestration.definitions && Object.keys(artifact.orchestration.definitions).length > 0;
121
+ const hasFlows = artifact.orchestration.flows && Object.keys(artifact.orchestration.flows).length > 0;
122
+
123
+ if (hasDefinitions && hasFlows) {
124
+ const defCount = Object.keys(artifact.orchestration.definitions).length;
125
+ const flowCount = Object.keys(artifact.orchestration.flows).length;
126
+ console.log(`${C.green} ✓ Orchestration Structure (${defCount} definitions, ${flowCount} flows)${C.reset}`);
127
+ results.push({ check: 'orchestration_structure', passed: true, definitions: defCount, flows: flowCount });
128
+ } else {
129
+ console.log(`${C.yellow} ⚠ Orchestration may be incomplete${C.reset}`);
130
+ results.push({ check: 'orchestration_structure', passed: true, warning: 'may be incomplete' });
131
+ }
132
+ }
133
+
134
+ // 5. Integrity Check
135
+ if (!insecure) {
136
+ if (artifact.security?.integrity_ref) {
137
+ const manifestPath = path.resolve(path.dirname(target), artifact.security.integrity_ref);
138
+ if (fs.existsSync(manifestPath)) {
139
+ try {
140
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
141
+ const hash = crypto.createHash('sha256').update(content).digest('hex');
142
+ if (hash === manifest.artifact_sha256) {
143
+ console.log(`${C.green} ✓ Integrity Verified (SHA-256 match)${C.reset}`);
144
+ if (verbose) {
145
+ console.log(`${C.gray} Hash: ${hash}${C.reset}`);
146
+ }
147
+ results.push({ check: 'integrity', passed: true, hash: hash });
148
+ logWitness(home, 'integrity_verified', { hash: hash, manifest: artifact.security.integrity_ref });
149
+ } else {
150
+ console.log(`${C.red} ✖ Integrity Mismatch!${C.reset}`);
151
+ if (verbose) {
152
+ console.log(`${C.gray} Expected: ${manifest.artifact_sha256}${C.reset}`);
153
+ console.log(`${C.gray} Actual: ${hash}${C.reset}`);
154
+ }
155
+ results.push({ check: 'integrity', passed: false, expected: manifest.artifact_sha256, actual: hash });
156
+ logWitness(home, 'integrity_failed', { expected: manifest.artifact_sha256, actual: hash });
157
+ allPassed = false;
158
+ }
159
+ } catch (e) {
160
+ console.log(`${C.red} ✖ Invalid Manifest: ${e.message}${C.reset}`);
161
+ results.push({ check: 'integrity', passed: false, error: e.message });
162
+ allPassed = false;
163
+ }
164
+ } else {
165
+ console.log(`${C.red} ✖ Manifest Not Found: ${artifact.security.integrity_ref}${C.reset}`);
166
+ results.push({ check: 'integrity', passed: false, error: 'manifest not found' });
167
+ logWitness(home, 'integrity_failed', { error: 'manifest not found' });
168
+ allPassed = false;
169
+ }
170
+ } else {
171
+ console.log(`${C.yellow} ⚠ No Integrity Reference (security.integrity_ref)${C.reset}`);
172
+ results.push({ check: 'integrity', passed: true, warning: 'no integrity_ref' });
173
+ }
174
+ } else {
175
+ console.log(`${C.yellow} ⚠ Integrity Check Skipped (--insecure)${C.reset}`);
176
+ results.push({ check: 'integrity', skipped: true });
177
+ }
178
+
179
+ // Summary
180
+ console.log('');
181
+ if (allPassed) {
182
+ console.log(`${C.green}${C.bold}✓ VALIDATION PASSED${C.reset}`);
183
+ logWitness(home, 'success', { results: results });
184
+ } else {
185
+ console.log(`${C.red}${C.bold}✖ VALIDATION FAILED${C.reset}`);
186
+ logWitness(home, 'failed', { results: results });
187
+ process.exit(1);
188
+ }
189
+ console.log('');
190
+ };