feat(phase0): complete GC1 feasibility and GC2 shared format contracts
- Record user evidence for directory fallback to complete GC1 (10/10 checks passed) - Expand Format Specification 0.1 to Revision 0.2 with normative shared contracts - Author JSON Schema Draft-07 at schema/xzbt-0.1.schema.json - Implement zero-dependency semantic validator at tools/validate-exhibit.mjs - Create 12-case conformance fixture suite and automated test runner (12/12 passing) - Update implementation status, verification gates, and gap closure decisions - Add devlog entry covering stall recovery and Phase 0 current state
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "cyclic-bindings-study",
|
||||
"name": "Invalid Cyclic Bindings Study"
|
||||
},
|
||||
"parameters": {
|
||||
"activity": {
|
||||
"type": "number",
|
||||
"default": 0.5
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"energy": {
|
||||
"type": "number",
|
||||
"initial": 0.5
|
||||
}
|
||||
},
|
||||
"bindings": [
|
||||
{
|
||||
"from": "parameters.activity",
|
||||
"to": "state.energy"
|
||||
},
|
||||
{
|
||||
"from": "state.energy",
|
||||
"to": "parameters.activity"
|
||||
}
|
||||
]
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "Valid-Id-Upper",
|
||||
"name": "Invalid ID Syntax Study"
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "operator-arity-study",
|
||||
"name": "Invalid Operator Arity Study"
|
||||
},
|
||||
"parameters": {
|
||||
"activity": {
|
||||
"type": "number",
|
||||
"default": 0.5
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"energy": {
|
||||
"type": "number",
|
||||
"initial": 0.5
|
||||
}
|
||||
},
|
||||
"bindings": [
|
||||
{
|
||||
"from": "parameters.activity",
|
||||
"to": "state.energy",
|
||||
"transform": {
|
||||
"op": "add",
|
||||
"args": [
|
||||
1.0
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "out-of-bounds-study",
|
||||
"name": "Invalid Out of Bounds Study"
|
||||
},
|
||||
"parameters": {
|
||||
"activity": {
|
||||
"type": "number",
|
||||
"default": 1.5,
|
||||
"min": 0.0,
|
||||
"max": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "missing-ref-study",
|
||||
"name": "Invalid Reference Missing Study"
|
||||
},
|
||||
"parameters": {
|
||||
"activity": {
|
||||
"type": "number",
|
||||
"default": 0.5
|
||||
}
|
||||
},
|
||||
"bindings": [
|
||||
{
|
||||
"from": "parameters.non_existent_param",
|
||||
"to": "parameters.activity"
|
||||
}
|
||||
]
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "type-mismatch-study",
|
||||
"name": "Invalid Type Mismatch Study"
|
||||
},
|
||||
"parameters": {
|
||||
"activity": {
|
||||
"type": "number",
|
||||
"default": "0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "unknown-field-study",
|
||||
"name": "Invalid Unknown Field Study"
|
||||
},
|
||||
"parameters": {
|
||||
"speed": {
|
||||
"type": "number",
|
||||
"default": 1.0,
|
||||
"unrecognized_property": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"xzbt": "0.99-unsupported",
|
||||
"meta": {
|
||||
"id": "unsupported-version-study",
|
||||
"name": "Invalid Version Study"
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "full-study",
|
||||
"name": "Full Feature Conformance Study",
|
||||
"version": "1.0.0",
|
||||
"author": "Antigravity",
|
||||
"description": "Valid exhibit exercising parameters, state, expressions, and bindings.",
|
||||
"tags": ["test", "conformance", "gc2"]
|
||||
},
|
||||
"runtime": {
|
||||
"seed": 42
|
||||
},
|
||||
"parameters": {
|
||||
"activity": {
|
||||
"type": "number",
|
||||
"default": 0.5,
|
||||
"min": 0.0,
|
||||
"max": 1.0,
|
||||
"step": 0.01,
|
||||
"label": "Activity Level"
|
||||
},
|
||||
"high-contrast": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"wave-shape": {
|
||||
"type": "enum",
|
||||
"values": ["sine", "triangle", "square"],
|
||||
"default": "sine"
|
||||
},
|
||||
"accent-color": {
|
||||
"type": "color",
|
||||
"default": "#e8ad57"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"energy": {
|
||||
"type": "number",
|
||||
"initial": 0.2,
|
||||
"min": 0.0,
|
||||
"max": 1.0
|
||||
},
|
||||
"alert-active": {
|
||||
"type": "boolean",
|
||||
"initial": false
|
||||
}
|
||||
},
|
||||
"bindings": [
|
||||
{
|
||||
"from": "parameters.activity",
|
||||
"to": "state.energy",
|
||||
"transform": {
|
||||
"op": "multiply",
|
||||
"args": [
|
||||
{ "ref": "parameters.activity" },
|
||||
1.5
|
||||
]
|
||||
},
|
||||
"smoothing": "250ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"xzbt": "0.1",
|
||||
"meta": {
|
||||
"id": "minimal-study",
|
||||
"name": "Minimal Valid Study"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* GC2 Automated Conformance Test Suite
|
||||
* Tests valid and invalid fixtures against the XZBT 0.1 Semantic Validator.
|
||||
*/
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { ExhibitValidator } from '../tools/validate-exhibit.mjs';
|
||||
|
||||
const testMatrix = [
|
||||
// Valid Fixtures
|
||||
{
|
||||
file: 'test/fixtures/gc2/valid-minimal.xzbt',
|
||||
expectedValid: true,
|
||||
expectedError: null
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/valid-full-feature.xzbt',
|
||||
expectedValid: true,
|
||||
expectedError: null
|
||||
},
|
||||
{
|
||||
file: 'prototypes/phase0/fixtures/amber-study.xzbt',
|
||||
expectedValid: true,
|
||||
expectedError: null
|
||||
},
|
||||
{
|
||||
file: 'prototypes/phase0/fixtures/blue-study.xzbt',
|
||||
expectedValid: true,
|
||||
expectedError: null
|
||||
},
|
||||
|
||||
// Invalid Fixtures with Expected Diagnostic Codes
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-unknown-field.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_UNKNOWN_FIELD'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-unsupported-version.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_UNSUPPORTED_VERSION'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-id-syntax.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_INVALID_ID'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-reference-missing.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_INVALID_REFERENCE'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-type-mismatch.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_TYPE_MISMATCH'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-cyclic-bindings.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_CYCLIC_DEPENDENCY'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-out-of-bounds.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_OUT_OF_BOUNDS'
|
||||
},
|
||||
{
|
||||
file: 'test/fixtures/gc2/invalid-operator-arity.xzbt',
|
||||
expectedValid: false,
|
||||
expectedError: 'ERR_INVALID_ARITY'
|
||||
}
|
||||
];
|
||||
|
||||
console.log('--- Running GC2 Format Contract Conformance Suite ---\n');
|
||||
|
||||
let passedTests = 0;
|
||||
let failedTests = 0;
|
||||
|
||||
for (const testCase of testMatrix) {
|
||||
const fullPath = resolve(testCase.file);
|
||||
const content = readFileSync(fullPath, 'utf-8');
|
||||
const doc = JSON.parse(content);
|
||||
const validator = new ExhibitValidator(doc, testCase.file);
|
||||
const result = validator.validate();
|
||||
|
||||
if (testCase.expectedValid) {
|
||||
if (result.valid) {
|
||||
console.log(`PASS: ${testCase.file} (valid as expected)`);
|
||||
passedTests++;
|
||||
} else {
|
||||
console.error(`FAIL: ${testCase.file} expected valid, but got errors:`);
|
||||
for (const err of result.errors) {
|
||||
console.error(` - [${err.code}] ${err.path}: ${err.message}`);
|
||||
}
|
||||
failedTests++;
|
||||
}
|
||||
} else {
|
||||
if (!result.valid && result.errors.some((e) => e.code === testCase.expectedError)) {
|
||||
console.log(`PASS: ${testCase.file} (correctly rejected with ${testCase.expectedError})`);
|
||||
passedTests++;
|
||||
} else {
|
||||
console.error(
|
||||
`FAIL: ${testCase.file} expected rejection with ${testCase.expectedError}, but got valid=${result.valid} errors:`,
|
||||
result.errors
|
||||
);
|
||||
failedTests++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\nResults: ${passedTests} passed, ${failedTests} failed out of ${testMatrix.length} total tests.`);
|
||||
|
||||
if (failedTests > 0) {
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log('GC2 Contract Completeness Conformance: ALL TESTS PASSED.\n');
|
||||
process.exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user