@aikdna/kdna-cli 0.16.5 → 0.16.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikdna/kdna-cli",
3
- "version": "0.16.5",
3
+ "version": "0.16.6",
4
4
  "description": "KDNA CLI — create, validate, install, and manage domain cognition packages for AI agents.",
5
5
  "type": "commonjs",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -107,7 +107,8 @@ Agent Runtime:
107
107
 
108
108
  Testing & Verification:
109
109
  verify <name> 3-layer: structure + trust + judgment
110
- verify <name> --i18n I18N verification: locale dirs, overlays, card completeness
110
+ verify <name> --i18n I18N verification: locales, overlays, card completeness
111
+ verify <name> --governance Governance verification: risk_level, KDNA_CARD, provenance
111
112
  verify <name> --judgment --run-tests Judgment validation with eval cases
112
113
  compare <name> --input "..." With/without KDNA reasoning diff
113
114
  compare <name> --input "..." --report-md Markdown report format
package/src/verify.js CHANGED
@@ -467,6 +467,87 @@ function checkI18n(destDir) {
467
467
  };
468
468
  }
469
469
 
470
+ // ─── Governance layer ───────────────────────────────────────────────
471
+
472
+ function checkGovernance(destDir) {
473
+ const issues = [];
474
+ const passed = [];
475
+ const card = readJson(path.join(destDir, 'KDNA_CARD.json')) || {};
476
+
477
+ if (!readJson(path.join(destDir, 'KDNA_CARD.json'))) {
478
+ issues.push({ severity: 'error', msg: 'governance: KDNA_CARD.json missing — required' });
479
+ return { layer: 'governance', passed: false, issues, results: issues.map((i) => i.msg) };
480
+ }
481
+ passed.push('KDNA_CARD.json present');
482
+
483
+ if (!card.risk_level) {
484
+ issues.push({ severity: 'error', msg: 'governance: risk_level not declared (R0/R1/R2/R3)' });
485
+ } else if (!['R0', 'R1', 'R2', 'R3'].includes(card.risk_level)) {
486
+ issues.push({ severity: 'error', msg: `governance: invalid risk_level "${card.risk_level}"` });
487
+ } else {
488
+ passed.push(`risk_level: ${card.risk_level}`);
489
+ }
490
+
491
+ if (!card.intended_use?.length) {
492
+ issues.push({ severity: 'error', msg: 'governance: intended_use empty' });
493
+ } else {
494
+ passed.push(`intended_use: ${card.intended_use.length} entries`);
495
+ }
496
+
497
+ if (!card.out_of_scope?.length) {
498
+ issues.push({ severity: 'error', msg: 'governance: out_of_scope empty' });
499
+ } else {
500
+ passed.push(`out_of_scope: ${card.out_of_scope.length} entries`);
501
+ }
502
+
503
+ if (!card.known_limitations?.length) {
504
+ issues.push({ severity: 'warn', msg: 'governance: known_limitations empty' });
505
+ } else {
506
+ passed.push(`known_limitations: ${card.known_limitations.length} entries`);
507
+ }
508
+
509
+ if (['R1', 'R2', 'R3'].includes(card.risk_level) && !card.author_responsibility) {
510
+ issues.push({
511
+ severity: 'warn',
512
+ msg: `governance: risk ${card.risk_level} should declare author_responsibility`,
513
+ });
514
+ }
515
+
516
+ if (['R2', 'R3'].includes(card.risk_level)) {
517
+ if (!card.reviewed_by && !card.requires_expert_review) {
518
+ issues.push({
519
+ severity: 'error',
520
+ msg: `governance: risk ${card.risk_level} requires expert_review`,
521
+ });
522
+ }
523
+ if (!card.risk_warnings?.length) {
524
+ issues.push({
525
+ severity: 'error',
526
+ msg: `governance: risk ${card.risk_level} requires risk_warnings`,
527
+ });
528
+ }
529
+ }
530
+
531
+ if (!card.human_lock_summary)
532
+ issues.push({ severity: 'warn', msg: 'governance: human_lock_summary missing' });
533
+ else passed.push('human_lock_summary present');
534
+
535
+ if (!card.provenance) issues.push({ severity: 'warn', msg: 'governance: provenance missing' });
536
+ else passed.push('provenance present');
537
+
538
+ if (!card.quality_badge)
539
+ issues.push({ severity: 'warn', msg: 'governance: quality_badge missing' });
540
+ else passed.push(`quality_badge: ${card.quality_badge}`);
541
+
542
+ return {
543
+ layer: 'governance',
544
+ passed: issues.filter((i) => i.severity === 'error').length === 0,
545
+ issues,
546
+ results: passed.concat(issues.map((i) => i.msg)),
547
+ score: { total: passed.length, max: passed.length + issues.length },
548
+ };
549
+ }
550
+
470
551
  // ─── Main ──────────────────────────────────────────────────────────────
471
552
 
472
553
  function cmdVerify(input, args = []) {
@@ -477,8 +558,9 @@ function cmdVerify(input, args = []) {
477
558
  trust: args.includes('--trust'),
478
559
  judgment: args.includes('--judgment'),
479
560
  i18n: args.includes('--i18n'),
561
+ governance: args.includes('--governance'),
480
562
  };
481
- const all = !want.structure && !want.trust && !want.judgment && !want.i18n;
563
+ const all = !want.structure && !want.trust && !want.judgment && !want.i18n && !want.governance;
482
564
  if (all) want.structure = want.trust = want.judgment = true;
483
565
 
484
566
  // Resolve name → installed path + scope/entry
@@ -532,6 +614,7 @@ function cmdVerify(input, args = []) {
532
614
  if (want.trust) results.push(checkTrust(destDir, scope, entry));
533
615
  if (want.judgment) results.push(checkJudgment(destDir));
534
616
  if (want.i18n) results.push(checkI18n(destDir));
617
+ if (want.governance) results.push(checkGovernance(destDir));
535
618
 
536
619
  // ── JSON output ──────────────────────────────────────────────────────
537
620
  if (jsonMode) {
@@ -548,6 +631,8 @@ function cmdVerify(input, args = []) {
548
631
  const structureResult = results.find((r) => r.layer === 'structure');
549
632
  const trustResult = results.find((r) => r.layer === 'trust');
550
633
  const judgmentResult = results.find((r) => r.layer === 'judgment');
634
+ const i18nResult = results.find((r) => r.layer === 'i18n');
635
+ const governanceResult = results.find((r) => r.layer === 'governance');
551
636
 
552
637
  let exitCode = EXIT.OK;
553
638
  if (structureResult && structureResult.issues.some((i) => i.severity === 'error')) {