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:
2026-09-05 11:38:48 -07:00
parent ca2830174f
commit e02d49a739
25 changed files with 2473 additions and 66 deletions
+29
View File
@@ -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
View File
@@ -0,0 +1,7 @@
{
"xzbt": "0.1",
"meta": {
"id": "Valid-Id-Upper",
"name": "Invalid ID Syntax Study"
}
}
+31
View File
@@ -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
View File
@@ -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
}
}
}
+19
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
}
}
+7
View File
@@ -0,0 +1,7 @@
{
"xzbt": "0.99-unsupported",
"meta": {
"id": "unsupported-version-study",
"name": "Invalid Version Study"
}
}
+63
View File
@@ -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"
}
]
}
+7
View File
@@ -0,0 +1,7 @@
{
"xzbt": "0.1",
"meta": {
"id": "minimal-study",
"name": "Minimal Valid Study"
}
}
+120
View File
@@ -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);
}