feat(ultraplan-local): add autonomy-gate state machine + manifest schema extensions for skip_commit_check + memory_write
Step 4 of plan-v2 (ultra-pipeline-speedup).
lib/util/autonomy-gate.mjs (NEW)
5-state machine {idle, gates_on, auto_running, paused_for_gate, completed}
honoring the --gates flag intent. Re-entry to completed is idempotent.
Includes CLI shim:
node lib/util/autonomy-gate.mjs --state X --event Y [--gates true|false]
→ JSON: { ok, next_state | error }, exit 0 on success / 1 on invalid.
lib/parsers/manifest-yaml.mjs (EXTENDED)
OPTIONAL_KEYS list adds skip_commit_check and memory_write — both boolean,
default false when absent, MANIFEST_OPTIONAL_TYPE when non-boolean.
Existing REQUIRED_KEYS contract untouched; existing 9 manifest tests
still pass.
Tests: 19 (autonomy-gate) + 8 (manifest-schema-extensions) = 27 new.
[skip-docs]
This commit is contained in:
parent
b1e161116a
commit
645f01625b
6 changed files with 602 additions and 2 deletions
|
|
@ -20,6 +20,19 @@ const REQUIRED_KEYS = [
|
|||
'must_contain',
|
||||
];
|
||||
|
||||
// Optional manifest keys (plan-v2 Step 4). Absence == false.
|
||||
// `skip_commit_check`: opt out of the per-step commit assertion (e.g. memory-only steps).
|
||||
// `memory_write` : marks a step that writes to ~/.claude/projects/.../memory/
|
||||
// so the executor can route it through the memory truth gate.
|
||||
const OPTIONAL_KEYS = [
|
||||
'skip_commit_check',
|
||||
'memory_write',
|
||||
];
|
||||
|
||||
const OPTIONAL_BOOLEAN_KEYS = new Set(OPTIONAL_KEYS);
|
||||
|
||||
export { OPTIONAL_KEYS };
|
||||
|
||||
/**
|
||||
* Extract the first fenced YAML block whose first non-blank line begins with
|
||||
* `manifest:`.
|
||||
|
|
@ -84,6 +97,19 @@ export function parseManifest(stepBody) {
|
|||
errors.push(issue('MANIFEST_COUNT_TYPE', 'min_file_count must be a number'));
|
||||
}
|
||||
|
||||
for (const k of OPTIONAL_BOOLEAN_KEYS) {
|
||||
if (k in parsed) {
|
||||
if (typeof parsed[k] !== 'boolean') {
|
||||
errors.push(issue(
|
||||
'MANIFEST_OPTIONAL_TYPE',
|
||||
`${k} must be boolean if present (got ${typeof parsed[k]})`,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
parsed[k] = false; // default: absence == false
|
||||
}
|
||||
}
|
||||
|
||||
return { valid: errors.length === 0, errors, warnings, parsed };
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue