@formigio/fazemos-cli 0.10.24 → 0.10.25
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.
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -1
- package/dist/runbook/checks.d.ts +78 -0
- package/dist/runbook/checks.js +404 -0
- package/dist/runbook/checks.js.map +1 -0
- package/dist/runbook/schema.d.ts +153 -0
- package/dist/runbook/schema.js +136 -0
- package/dist/runbook/schema.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { isProjectConnectionUnavailable, renderProjectConnectionUnavailableCopy,
|
|
|
10
10
|
import { loadYaml, summarize } from './yaml/load.js';
|
|
11
11
|
import { printFindings, printJson } from './yaml/format.js';
|
|
12
12
|
import { validateManifest } from './manifest/checks.js';
|
|
13
|
+
import { validatePath as validateRunbookPath } from './runbook/checks.js';
|
|
13
14
|
import { findLocalRegistry, resolveRole, buildInboxFile, writeInboxFile, writeInboxFileAtPath, buildRolesSyncPayload, findUnprocessedInboxFiles, computeFileHash, gitCommitInboxFile, } from './dispatch.js';
|
|
14
15
|
import { execSync } from 'child_process';
|
|
15
16
|
import { registerPauseCommands } from './pause.js';
|
|
@@ -8238,6 +8239,87 @@ Examples:
|
|
|
8238
8239
|
if (summary.errors > 0)
|
|
8239
8240
|
process.exit(1);
|
|
8240
8241
|
});
|
|
8242
|
+
// ── `fazemos runbook validate` — Runbook substrate validator (F39 TOOL-1) ──
|
|
8243
|
+
//
|
|
8244
|
+
// Validates Runbook step-doc frontmatter against the FROZEN schema
|
|
8245
|
+
// (projects/fazemos/runbooks/runbook.schema.json) + the per-template
|
|
8246
|
+
// flip-state ledger (projects/fazemos/runbooks/flip-state.json). Offline; no
|
|
8247
|
+
// API calls. A NEW command group (sibling to `yaml` / `manifest`) — a Runbook
|
|
8248
|
+
// doc is a different artifact (markdown-with-frontmatter, not a YAML manifest),
|
|
8249
|
+
// so it does not belong under `manifest validate`'s ADM contract. See the F39
|
|
8250
|
+
// tech spec §9. Scope: frontmatter shape + flip-state invariant ONLY — NOT
|
|
8251
|
+
// id→file resolution (F40), NOT contract-conformance-against-binding (F41).
|
|
8252
|
+
const runbookGroup = program.command('runbook').description('Runbook substrate validation (F39). A Runbook is the one reusable unit of ' +
|
|
8253
|
+
'work: a declared I/O contract + a role hint + a procedure body, authored ' +
|
|
8254
|
+
'as frontmatter on a step doc (steps/<Template>/<Step>.md). Offline; no API ' +
|
|
8255
|
+
'calls. Run at author time, in Ollie\'s stewardship audit, or in CI on PRs ' +
|
|
8256
|
+
'touching steps/** or runbooks/**.');
|
|
8257
|
+
runbookGroup
|
|
8258
|
+
.command('validate')
|
|
8259
|
+
.description('Validate Runbook step-doc frontmatter: frozen-schema shape + frozen enums + runbook_schema_version + F18 description contract + id shape/uniqueness + no-binding-leak + per-template flip-state invariant.')
|
|
8260
|
+
.argument('<path>', 'Path to a Runbook step-doc (.md) or a directory of them (e.g. "steps/Hello Fazemos/"). Absolute or relative to CWD.')
|
|
8261
|
+
.option('--json', 'Emit structured JSON output instead of human-readable text. See --help for shape.')
|
|
8262
|
+
.addHelpText('after', `
|
|
8263
|
+
What runs (in order, per file):
|
|
8264
|
+
1. frontmatter split + js-yaml parse (rule slugs: runbook.no_frontmatter / runbook.frontmatter_parse_error / runbook.shape)
|
|
8265
|
+
2. frozen schema (ajv, draft-07) (rule slugs: schema.* — required/enum/type/pattern/additionalProperties)
|
|
8266
|
+
3. runbook_schema_version present/known (runbook.version_missing = ERROR; runbook.version_unknown = warning)
|
|
8267
|
+
4. description (F18 contract) (runbook.description_invalid: MISSING/EMPTY/MULTILINE)
|
|
8268
|
+
5. runbook id kebab shape + uniqueness (runbook.id_shape; runbook.id_duplicate across a directory run)
|
|
8269
|
+
6. no binding/DAG leak (runbook.binding_leak — depends_on/source_*/step_type/template/cadence/… + top-level reviewer/eval_max_turns)
|
|
8270
|
+
7. per-template flip-state invariant (runbook.flip_state_unreadable / runbook.flip_state_mismatch)
|
|
8271
|
+
|
|
8272
|
+
Schema source of truth: projects/fazemos/runbooks/runbook.schema.json (canonical;
|
|
8273
|
+
loaded from the workspace clone). The CLI vendors a copy as the absent-canonical
|
|
8274
|
+
fallback; a unit test diffs the two and fails on drift (F39 §9.2).
|
|
8275
|
+
|
|
8276
|
+
Flip-state: projects/fazemos/runbooks/flip-state.json. flipped:true => the doc is
|
|
8277
|
+
authoritative (empty inline sections are correct — no false EMPTY_STEP_BODY alarm);
|
|
8278
|
+
flipped:false/absent => inline sections are authoritative (frontmatter accepted if
|
|
8279
|
+
present, transitional). An unreadable ledger is a hard error.
|
|
8280
|
+
|
|
8281
|
+
Frozen enums (F39 §5.2; append-only within a major version):
|
|
8282
|
+
type text | number | boolean | url | filepath | json
|
|
8283
|
+
format text | filepath | url | commit_sha | integer | markdown | json
|
|
8284
|
+
source_hint upstream | pipeline_param | dispatch_param | workspace_path
|
|
8285
|
+
|
|
8286
|
+
Exit codes:
|
|
8287
|
+
0 no error-severity findings (warnings + infos OK)
|
|
8288
|
+
1 any error-severity finding present
|
|
8289
|
+
|
|
8290
|
+
JSON output shape (--json) — same as \`manifest validate --json\`, one object per file:
|
|
8291
|
+
{ "source", "ok", "summary": { "errors", "warnings", "infos" }, "findings": [ … ] }
|
|
8292
|
+
|
|
8293
|
+
When to invoke:
|
|
8294
|
+
- Author time, before commit (catches STEP_UNRESOLVED-class defects before a render)
|
|
8295
|
+
- Inside Ollie's stewardship / flip audit
|
|
8296
|
+
- In CI on any PR touching steps/** or runbooks/**
|
|
8297
|
+
|
|
8298
|
+
Examples:
|
|
8299
|
+
fazemos runbook validate "projects/fazemos/steps/Hello Fazemos/Write a random fact.md"
|
|
8300
|
+
fazemos runbook validate "projects/fazemos/steps/Hello Fazemos/" --json | jq '.[].findings[] | select(.severity=="error")'`)
|
|
8301
|
+
.action((path, opts) => {
|
|
8302
|
+
const results = validateRunbookPath(path);
|
|
8303
|
+
let totalErrors = 0;
|
|
8304
|
+
if (opts.json) {
|
|
8305
|
+
const payload = results.map((r) => {
|
|
8306
|
+
const summary = summarize(r.findings);
|
|
8307
|
+
totalErrors += summary.errors;
|
|
8308
|
+
return { source: r.source, ok: summary.errors === 0, summary, findings: r.findings };
|
|
8309
|
+
});
|
|
8310
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
8311
|
+
}
|
|
8312
|
+
else {
|
|
8313
|
+
for (const r of results) {
|
|
8314
|
+
const summary = summarize(r.findings);
|
|
8315
|
+
totalErrors += summary.errors;
|
|
8316
|
+
printFindings(r.source, r.findings, summary);
|
|
8317
|
+
console.log('');
|
|
8318
|
+
}
|
|
8319
|
+
}
|
|
8320
|
+
if (totalErrors > 0)
|
|
8321
|
+
process.exit(1);
|
|
8322
|
+
});
|
|
8241
8323
|
// ── `fazemos dispatch` — role-to-role dispatch ─────────────────────
|
|
8242
8324
|
//
|
|
8243
8325
|
// F26 data flow (API write-through, Dex S-B):
|