You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Completes the ADR-0051 P1 publish lint. `collectAndLintDocs` (run by
`os compile` / `os lint`, which already pass the assembled stack) now
also validates every ```metadata fence:
- body shape: `type` ∈ {state_machine, flow, permission} (did-you-mean
on a typo'd type), `name` required, `object` required for
state_machine.
- reference liveness against the package's OWN metadata: the object +
named state_machine rule, the flow, or the permission set must exist
in this stack. A dead same-package reference is a build error (same
posture as docs/broken-link), with did-you-mean hints. Cross-package
embeds are out of v1 scope.
Note: scans share `stripCode()` which DELETES fenced blocks, so the
embed scan walks raw lines instead. The body parser mirrors the
objectui-side one so build-time and render-time agree.
Tests: 8 cases (valid trio, unknown type, missing name/object, dead
object/rule/flow/permission refs, non-metadata fences ignored, locale
variants). Verified the real app-showcase doc lints clean (no false
positives) with a typo'd-ref negative control.
No CLI build fix was needed: a clean dependency-ordered build
(`turbo run build --filter=@objectstack/cli`, 52/52) passes; the
previously-seen `validate-expressions.ts` / adr-0048-test errors were
stale/unbuilt local `dist`, not a code defect.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
err('docs/metadata-embed',`metadata embed in "${docName}" has unknown type "${type}"${s ? ` — did you mean \`${s}\`?` : ` (expected ${METADATA_EMBED_TYPES.join(', ')})`}.`);
434
+
continue;
435
+
}
436
+
if(!f.name){
437
+
err('docs/metadata-embed',`metadata embed (${type}) in "${docName}" is missing \`name\`.`);
438
+
continue;
439
+
}
440
+
441
+
// ── reference liveness (same-package) ──
442
+
if(type==='state_machine'){
443
+
if(!f.object){
444
+
err('docs/metadata-embed',`state_machine embed "${f.name}" in "${docName}" is missing \`object\` (a state machine is a rule on an object).`);
445
+
continue;
446
+
}
447
+
constobj=objByName.get(f.object);
448
+
if(!obj){
449
+
consts=nearest(f.object,[...objByName.keys()]);
450
+
err('docs/metadata-embed-ref',`state_machine embed in "${docName}" references object "${f.object}", which does not exist in this package${s ? ` — did you mean \`${s}\`?` : ''}.`);
err('docs/metadata-embed-ref',`state_machine embed in "${docName}" references "${f.name}", but object "${f.object}" has no state_machine rule with that name${s ? ` — did you mean \`${s}\`?` : ''}.`);
460
+
}
461
+
}elseif(type==='flow'){
462
+
if(!flowNames.includes(f.name)){
463
+
consts=nearest(f.name,flowNames);
464
+
err('docs/metadata-embed-ref',`flow embed in "${docName}" references flow "${f.name}", which does not exist in this package${s ? ` — did you mean \`${s}\`?` : ''}.`);
465
+
}
466
+
}elseif(type==='permission'){
467
+
if(!permNames.includes(f.name)){
468
+
consts=nearest(f.name,permNames);
469
+
err('docs/metadata-embed-ref',`permission embed in "${docName}" references permission set "${f.name}", which does not exist in this package${s ? ` — did you mean \`${s}\`?` : ''}.`);
0 commit comments