|
| 1 | +import * as fs from 'fs'; |
| 2 | +import * as os from 'os'; |
| 3 | +import * as path from 'path'; |
1 | 4 | import { KnowledgeLearningPlatform } from './KnowledgeLearningPlatform'; |
| 5 | +import { createFileBackedKnowledgeGraphStore } from './store'; |
2 | 6 |
|
3 | 7 | describe('KnowledgeLearningPlatform', () => { |
4 | 8 | let nowIso: string; |
@@ -1048,6 +1052,119 @@ describe('KnowledgeLearningPlatform', () => { |
1048 | 1052 | expect(state.sessionActionTelemetry.executionCount).toBeGreaterThanOrEqual(0); |
1049 | 1053 | }); |
1050 | 1054 |
|
| 1055 | + test('foundation readiness resolves explicit repo roots without overclaiming missing adapters', async () => { |
| 1056 | + const tempRoot = fs.mkdtempSync( |
| 1057 | + path.join(fs.realpathSync(os.tmpdir()), 'noteconnection-foundation-platform-') |
| 1058 | + ); |
| 1059 | + |
| 1060 | + try { |
| 1061 | + const fakeRepoRoot = path.join(tempRoot, 'repo'); |
| 1062 | + fs.mkdirSync(path.join(fakeRepoRoot, 'src', 'learning'), { recursive: true }); |
| 1063 | + fs.mkdirSync(path.join(fakeRepoRoot, 'docs', 'diataxis', 'en', 'explanation'), { recursive: true }); |
| 1064 | + fs.mkdirSync(path.join(fakeRepoRoot, 'docs', 'diataxis', 'zh', 'explanation'), { recursive: true }); |
| 1065 | + |
| 1066 | + fs.writeFileSync( |
| 1067 | + path.join(fakeRepoRoot, 'package.json'), |
| 1068 | + JSON.stringify( |
| 1069 | + { |
| 1070 | + scripts: { |
| 1071 | + 'verify:foundation:readiness': 'node scripts/verify-foundation-readiness.js', |
| 1072 | + }, |
| 1073 | + }, |
| 1074 | + null, |
| 1075 | + 2 |
| 1076 | + ), |
| 1077 | + 'utf8' |
| 1078 | + ); |
| 1079 | + fs.writeFileSync( |
| 1080 | + path.join(fakeRepoRoot, 'src', 'learning', 'store.ts'), |
| 1081 | + "export async function loadSnapshot() {}\nexport function createFileBackedKnowledgeGraphStore() {}\nexport const diagnostics = { storeType: 'file' };\n", |
| 1082 | + 'utf8' |
| 1083 | + ); |
| 1084 | + fs.writeFileSync( |
| 1085 | + path.join( |
| 1086 | + fakeRepoRoot, |
| 1087 | + 'docs', |
| 1088 | + 'diataxis', |
| 1089 | + 'en', |
| 1090 | + 'explanation', |
| 1091 | + 'foundation-reentry-readiness-checklist.md' |
| 1092 | + ), |
| 1093 | + 'foundation checklist\n', |
| 1094 | + 'utf8' |
| 1095 | + ); |
| 1096 | + fs.writeFileSync( |
| 1097 | + path.join( |
| 1098 | + fakeRepoRoot, |
| 1099 | + 'docs', |
| 1100 | + 'diataxis', |
| 1101 | + 'zh', |
| 1102 | + 'explanation', |
| 1103 | + 'foundation-reentry-readiness-checklist.md' |
| 1104 | + ), |
| 1105 | + 'foundation checklist\n', |
| 1106 | + 'utf8' |
| 1107 | + ); |
| 1108 | + fs.writeFileSync( |
| 1109 | + path.join( |
| 1110 | + fakeRepoRoot, |
| 1111 | + 'docs', |
| 1112 | + 'diataxis', |
| 1113 | + 'en', |
| 1114 | + 'explanation', |
| 1115 | + 'development-progress-dashboard.md' |
| 1116 | + ), |
| 1117 | + 'foundation-reentry-readiness-checklist\n', |
| 1118 | + 'utf8' |
| 1119 | + ); |
| 1120 | + fs.writeFileSync( |
| 1121 | + path.join( |
| 1122 | + fakeRepoRoot, |
| 1123 | + 'docs', |
| 1124 | + 'diataxis', |
| 1125 | + 'zh', |
| 1126 | + 'explanation', |
| 1127 | + 'development-progress-dashboard.md' |
| 1128 | + ), |
| 1129 | + 'foundation-reentry-readiness-checklist\n', |
| 1130 | + 'utf8' |
| 1131 | + ); |
| 1132 | + |
| 1133 | + const readinessPlatform = new KnowledgeLearningPlatform({ |
| 1134 | + nowProvider: () => new Date(nowIso), |
| 1135 | + projectRoot: fakeRepoRoot, |
| 1136 | + store: createFileBackedKnowledgeGraphStore({ |
| 1137 | + filePath: path.join(tempRoot, 'runtime_data', 'knowledge_graph_store.v1.json'), |
| 1138 | + }), |
| 1139 | + }); |
| 1140 | + |
| 1141 | + const readiness = await readinessPlatform.getFoundationReadiness(); |
| 1142 | + |
| 1143 | + expect(readiness.status).toBe('in_progress'); |
| 1144 | + expect(readiness.decision).toBe('no-go'); |
| 1145 | + expect(readiness.baseline.storeType).toBe('file'); |
| 1146 | + expect(readiness.baseline.exists).toBe(false); |
| 1147 | + expect(readiness.baseline.loaded).toBe(false); |
| 1148 | + expect(readiness.baseline.fileBackedStore).toBe(true); |
| 1149 | + expect(readiness.baseline.graphAdapterModulePresent).toBe(false); |
| 1150 | + expect(readiness.baseline.vectorAdapterModulePresent).toBe(false); |
| 1151 | + expect(readiness.documents.checklistPagesPresent).toBe(true); |
| 1152 | + expect(readiness.documents.dashboardReferencesPresent).toBe(true); |
| 1153 | + expect(readiness.packageScripts.readinessVerifierPresent).toBe(true); |
| 1154 | + expect(readiness.mandatoryChecks.map((entry) => entry.gateId)).toEqual( |
| 1155 | + expect.arrayContaining([ |
| 1156 | + 'contract', |
| 1157 | + 'core_behavior', |
| 1158 | + 'persistence_safety', |
| 1159 | + 'interaction_non_regression', |
| 1160 | + 'documentation', |
| 1161 | + ]) |
| 1162 | + ); |
| 1163 | + } finally { |
| 1164 | + fs.rmSync(tempRoot, { recursive: true, force: true }); |
| 1165 | + } |
| 1166 | + }); |
| 1167 | + |
1051 | 1168 | test('tutor action uses misconception context for targeted guidance', async () => { |
1052 | 1169 | const ingest = await platform.ingestKnowledge({ |
1053 | 1170 | incremental: true, |
|
0 commit comments