@aikdna/studio-core 1.1.0 → 1.2.0

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/studio-core",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "KDNA Studio Core — pure logic library for authoring, validating, and compiling KDNA domain judgment packages.",
5
5
  "type": "commonjs",
6
6
  "main": "src/index.js",
@@ -13,6 +13,7 @@
13
13
  const contradiction = require('./contradiction');
14
14
  const { validateAllCards } = require('./validate-cards');
15
15
  const { validateGovernance } = require('../governance');
16
+ const { computeI18nCoverage } = require('../i18n');
16
17
 
17
18
  function computeReadiness(project) {
18
19
  const cards = project.cards || [];
@@ -28,6 +29,15 @@ function computeReadiness(project) {
28
29
 
29
30
  // ── Governance check (v0.6.1) ───────────────────────────────────
30
31
  const govResult = validateGovernance(project);
32
+
33
+ // ── I18N check (v1.2.0) ─────────────────────────────────────────
34
+ const isOfficial = project.name?.startsWith('@aikdna/') || project.release?.official === true;
35
+ const i18nCoverage = computeI18nCoverage(project);
36
+ if (isOfficial && i18nCoverage.level === 'L0') {
37
+ blocking.push('I18N: official domains require at least L1 (KDNA_CARD.json + README in locales/zh-CN/)');
38
+ } else if (isOfficial && i18nCoverage.level === 'L1') {
39
+ warnings.push('I18N: L1 achieved (card + readme). Recommended: L2 overlay for publishable grade.');
40
+ }
31
41
  for (const issue of govResult.issues) {
32
42
  (issue.severity === 'blocking' ? blocking : warnings).push(`Governance: ${issue.message}`);
33
43
  }
@@ -114,7 +124,7 @@ function computeReadiness(project) {
114
124
  warnings.push('Governance checks not passed — publishable downgraded to tested');
115
125
  }
116
126
 
117
- return buildResult(grade, blocking, warnings, project, { feynmanRatio, allFeynman, governance: govResult });
127
+ return buildResult(grade, blocking, warnings, project, { feynmanRatio, allFeynman, governance: govResult, i18n: i18nCoverage });
118
128
  }
119
129
 
120
130
  function buildResult(grade, blocking, warnings, project, detail = {}) {
@@ -128,6 +138,7 @@ function buildResult(grade, blocking, warnings, project, detail = {}) {
128
138
  warnings,
129
139
  score: Math.max(0, 100 - blocking.length * 15 - warnings.length * 3),
130
140
  governance: detail.governance || null,
141
+ i18n: detail.i18n || null,
131
142
  stats: {
132
143
  total_cards: (project.cards || []).length,
133
144
  locked_cards: lockedCount,
@@ -136,6 +147,7 @@ function buildResult(grade, blocking, warnings, project, detail = {}) {
136
147
  total_tests: (project.tests || []).length,
137
148
  rated_tests: ratedTests,
138
149
  feynman_ratio: detail.feynmanRatio !== undefined ? Math.round(detail.feynmanRatio * 100) + '%' : 'N/A',
150
+ i18n_level: detail.i18n?.level || 'L0',
139
151
  },
140
152
  next_step: grade === 'draft_grade' ? 'Lock at least 3 axioms with boundaries and 50% Feynman.' :
141
153
  grade === 'human_controlled' ? 'Add 5+ rated evals and 3+ self-checks.' :