@oscharko-dev/keiko-server 0.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/dist/.tsbuildinfo +1 -0
- package/dist/assistant-response.d.ts +6 -0
- package/dist/assistant-response.d.ts.map +1 -0
- package/dist/assistant-response.js +12 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +245 -0
- package/dist/chat-handlers.d.ts +48 -0
- package/dist/chat-handlers.d.ts.map +1 -0
- package/dist/chat-handlers.js +821 -0
- package/dist/chat-stream-handlers.d.ts +4 -0
- package/dist/chat-stream-handlers.d.ts.map +1 -0
- package/dist/chat-stream-handlers.js +136 -0
- package/dist/conversation-prompt.d.ts +8 -0
- package/dist/conversation-prompt.d.ts.map +1 -0
- package/dist/conversation-prompt.js +36 -0
- package/dist/conversation-validation.d.ts +26 -0
- package/dist/conversation-validation.d.ts.map +1 -0
- package/dist/conversation-validation.js +125 -0
- package/dist/credentialPersistence.d.ts +23 -0
- package/dist/credentialPersistence.d.ts.map +1 -0
- package/dist/credentialPersistence.js +93 -0
- package/dist/credentialVault.d.ts +30 -0
- package/dist/credentialVault.d.ts.map +1 -0
- package/dist/credentialVault.js +206 -0
- package/dist/csp.d.ts +3 -0
- package/dist/csp.d.ts.map +1 -0
- package/dist/csp.js +75 -0
- package/dist/deps.d.ts +78 -0
- package/dist/deps.d.ts.map +1 -0
- package/dist/deps.js +457 -0
- package/dist/editor/agentRoutes.d.ts +7 -0
- package/dist/editor/agentRoutes.d.ts.map +1 -0
- package/dist/editor/agentRoutes.js +197 -0
- package/dist/editor/assuredGateRunner.d.ts +36 -0
- package/dist/editor/assuredGateRunner.d.ts.map +1 -0
- package/dist/editor/assuredGateRunner.js +100 -0
- package/dist/editor/assuredPreFilter.d.ts +34 -0
- package/dist/editor/assuredPreFilter.d.ts.map +1 -0
- package/dist/editor/assuredPreFilter.js +134 -0
- package/dist/editor/assuredPreFilterRunner.d.ts +31 -0
- package/dist/editor/assuredPreFilterRunner.d.ts.map +1 -0
- package/dist/editor/assuredPreFilterRunner.js +312 -0
- package/dist/editor/builtinLanguageProviders.d.ts +6 -0
- package/dist/editor/builtinLanguageProviders.d.ts.map +1 -0
- package/dist/editor/builtinLanguageProviders.js +221 -0
- package/dist/editor/codingContext.d.ts +12 -0
- package/dist/editor/codingContext.d.ts.map +1 -0
- package/dist/editor/codingContext.js +121 -0
- package/dist/editor/codingContextEvidence.d.ts +7 -0
- package/dist/editor/codingContextEvidence.d.ts.map +1 -0
- package/dist/editor/codingContextEvidence.js +52 -0
- package/dist/editor/codingContextProviders.d.ts +36 -0
- package/dist/editor/codingContextProviders.d.ts.map +1 -0
- package/dist/editor/codingContextProviders.js +348 -0
- package/dist/editor/completionModelEvidence.d.ts +16 -0
- package/dist/editor/completionModelEvidence.d.ts.map +1 -0
- package/dist/editor/completionModelEvidence.js +50 -0
- package/dist/editor/completionRoutes.d.ts +37 -0
- package/dist/editor/completionRoutes.d.ts.map +1 -0
- package/dist/editor/completionRoutes.js +411 -0
- package/dist/editor/contextRoutes.d.ts +6 -0
- package/dist/editor/contextRoutes.d.ts.map +1 -0
- package/dist/editor/contextRoutes.js +411 -0
- package/dist/editor/disposableAssuredExecution.d.ts +22 -0
- package/dist/editor/disposableAssuredExecution.d.ts.map +1 -0
- package/dist/editor/disposableAssuredExecution.js +57 -0
- package/dist/editor/editorCompletionModel.d.ts +47 -0
- package/dist/editor/editorCompletionModel.d.ts.map +1 -0
- package/dist/editor/editorCompletionModel.js +156 -0
- package/dist/editor/editorInlineCompletionModel.d.ts +34 -0
- package/dist/editor/editorInlineCompletionModel.d.ts.map +1 -0
- package/dist/editor/editorInlineCompletionModel.js +112 -0
- package/dist/editor/editorModelTokenBudget.d.ts +46 -0
- package/dist/editor/editorModelTokenBudget.d.ts.map +1 -0
- package/dist/editor/editorModelTokenBudget.js +121 -0
- package/dist/editor/inlineCompletionRateLimiter.d.ts +19 -0
- package/dist/editor/inlineCompletionRateLimiter.d.ts.map +1 -0
- package/dist/editor/inlineCompletionRateLimiter.js +46 -0
- package/dist/editor/inlineCompletionRoutes.d.ts +26 -0
- package/dist/editor/inlineCompletionRoutes.d.ts.map +1 -0
- package/dist/editor/inlineCompletionRoutes.js +404 -0
- package/dist/editor/inlineCompletionTelemetryEvidence.d.ts +5 -0
- package/dist/editor/inlineCompletionTelemetryEvidence.d.ts.map +1 -0
- package/dist/editor/inlineCompletionTelemetryEvidence.js +42 -0
- package/dist/editor/languageCancellation.d.ts +19 -0
- package/dist/editor/languageCancellation.d.ts.map +1 -0
- package/dist/editor/languageCancellation.js +48 -0
- package/dist/editor/languageProvider.d.ts +39 -0
- package/dist/editor/languageProvider.d.ts.map +1 -0
- package/dist/editor/languageProvider.js +11 -0
- package/dist/editor/languageRoutes.d.ts +15 -0
- package/dist/editor/languageRoutes.d.ts.map +1 -0
- package/dist/editor/languageRoutes.js +106 -0
- package/dist/editor/languageSanitize.d.ts +8 -0
- package/dist/editor/languageSanitize.d.ts.map +1 -0
- package/dist/editor/languageSanitize.js +101 -0
- package/dist/editor/languageService.d.ts +36 -0
- package/dist/editor/languageService.d.ts.map +1 -0
- package/dist/editor/languageService.js +93 -0
- package/dist/editor/languageServiceHost.d.ts +14 -0
- package/dist/editor/languageServiceHost.d.ts.map +1 -0
- package/dist/editor/languageServiceHost.js +242 -0
- package/dist/editor/localKnowledgeRetrieval.d.ts +21 -0
- package/dist/editor/localKnowledgeRetrieval.d.ts.map +1 -0
- package/dist/editor/localKnowledgeRetrieval.js +44 -0
- package/dist/editor/patchApplyEvidence.d.ts +21 -0
- package/dist/editor/patchApplyEvidence.d.ts.map +1 -0
- package/dist/editor/patchApplyEvidence.js +87 -0
- package/dist/editor/patchApplyRoutes.d.ts +16 -0
- package/dist/editor/patchApplyRoutes.d.ts.map +1 -0
- package/dist/editor/patchApplyRoutes.js +307 -0
- package/dist/editor/postApplyVerification.d.ts +42 -0
- package/dist/editor/postApplyVerification.d.ts.map +1 -0
- package/dist/editor/postApplyVerification.js +177 -0
- package/dist/editor/testGenerationEvidence.d.ts +6 -0
- package/dist/editor/testGenerationEvidence.d.ts.map +1 -0
- package/dist/editor/testGenerationEvidence.js +72 -0
- package/dist/editor/testGenerationPatch.d.ts +10 -0
- package/dist/editor/testGenerationPatch.d.ts.map +1 -0
- package/dist/editor/testGenerationPatch.js +66 -0
- package/dist/editor/testGenerationRoutes.d.ts +21 -0
- package/dist/editor/testGenerationRoutes.d.ts.map +1 -0
- package/dist/editor/testGenerationRoutes.js +254 -0
- package/dist/editor/testGenerationRunner.d.ts +23 -0
- package/dist/editor/testGenerationRunner.d.ts.map +1 -0
- package/dist/editor/testGenerationRunner.js +120 -0
- package/dist/editor/textOffsets.d.ts +6 -0
- package/dist/editor/textOffsets.d.ts.map +1 -0
- package/dist/editor/textOffsets.js +82 -0
- package/dist/editor/typescriptLanguageProvider.d.ts +3 -0
- package/dist/editor/typescriptLanguageProvider.d.ts.map +1 -0
- package/dist/editor/typescriptLanguageProvider.js +217 -0
- package/dist/evidence.d.ts +28 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +145 -0
- package/dist/files-deny.d.ts +3 -0
- package/dist/files-deny.d.ts.map +1 -0
- package/dist/files-deny.js +12 -0
- package/dist/files.d.ts +97 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +733 -0
- package/dist/gateway-setup.d.ts +10 -0
- package/dist/gateway-setup.d.ts.map +1 -0
- package/dist/gateway-setup.js +896 -0
- package/dist/governed-workflow.d.ts +17 -0
- package/dist/governed-workflow.d.ts.map +1 -0
- package/dist/governed-workflow.js +147 -0
- package/dist/grounded-answer.d.ts +12 -0
- package/dist/grounded-answer.d.ts.map +1 -0
- package/dist/grounded-answer.js +69 -0
- package/dist/grounded-context-index.d.ts +25 -0
- package/dist/grounded-context-index.d.ts.map +1 -0
- package/dist/grounded-context-index.js +169 -0
- package/dist/grounded-document-evidence.d.ts +28 -0
- package/dist/grounded-document-evidence.d.ts.map +1 -0
- package/dist/grounded-document-evidence.js +430 -0
- package/dist/grounded-handoff.d.ts +4 -0
- package/dist/grounded-handoff.d.ts.map +1 -0
- package/dist/grounded-handoff.js +445 -0
- package/dist/grounded-orchestrator.d.ts +43 -0
- package/dist/grounded-orchestrator.d.ts.map +1 -0
- package/dist/grounded-orchestrator.js +1445 -0
- package/dist/grounded-prompt.d.ts +2 -0
- package/dist/grounded-prompt.d.ts.map +1 -0
- package/dist/grounded-prompt.js +17 -0
- package/dist/grounded-qa-hybrid.d.ts +36 -0
- package/dist/grounded-qa-hybrid.d.ts.map +1 -0
- package/dist/grounded-qa-hybrid.js +762 -0
- package/dist/grounded-qa-multi-source.d.ts +38 -0
- package/dist/grounded-qa-multi-source.d.ts.map +1 -0
- package/dist/grounded-qa-multi-source.js +461 -0
- package/dist/grounded-qa.d.ts +45 -0
- package/dist/grounded-qa.d.ts.map +1 -0
- package/dist/grounded-qa.js +877 -0
- package/dist/grounded-rerank.d.ts +26 -0
- package/dist/grounded-rerank.d.ts.map +1 -0
- package/dist/grounded-rerank.js +72 -0
- package/dist/grounded-turn-registry.d.ts +23 -0
- package/dist/grounded-turn-registry.d.ts.map +1 -0
- package/dist/grounded-turn-registry.js +102 -0
- package/dist/headers.d.ts +3 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +22 -0
- package/dist/host-check.d.ts +3 -0
- package/dist/host-check.d.ts.map +1 -0
- package/dist/host-check.js +58 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/load-csp.d.ts +3 -0
- package/dist/load-csp.d.ts.map +1 -0
- package/dist/load-csp.js +100 -0
- package/dist/local-knowledge-grounded-qa.d.ts +42 -0
- package/dist/local-knowledge-grounded-qa.d.ts.map +1 -0
- package/dist/local-knowledge-grounded-qa.js +678 -0
- package/dist/local-knowledge-handlers.d.ts +24 -0
- package/dist/local-knowledge-handlers.d.ts.map +1 -0
- package/dist/local-knowledge-handlers.js +1285 -0
- package/dist/local-knowledge-indexing-registry.d.ts +13 -0
- package/dist/local-knowledge-indexing-registry.d.ts.map +1 -0
- package/dist/local-knowledge-indexing-registry.js +53 -0
- package/dist/localKnowledgeKeyProvider.d.ts +11 -0
- package/dist/localKnowledgeKeyProvider.d.ts.map +1 -0
- package/dist/localKnowledgeKeyProvider.js +48 -0
- package/dist/memory-audit-event-builders.d.ts +21 -0
- package/dist/memory-audit-event-builders.d.ts.map +1 -0
- package/dist/memory-audit-event-builders.js +187 -0
- package/dist/memory-audit-handler.d.ts +23 -0
- package/dist/memory-audit-handler.d.ts.map +1 -0
- package/dist/memory-audit-handler.js +191 -0
- package/dist/memory-capture-policy.d.ts +10 -0
- package/dist/memory-capture-policy.d.ts.map +1 -0
- package/dist/memory-capture-policy.js +44 -0
- package/dist/memory-consolidation-handlers.d.ts +6 -0
- package/dist/memory-consolidation-handlers.d.ts.map +1 -0
- package/dist/memory-consolidation-handlers.js +491 -0
- package/dist/memory-consolidation-registry.d.ts +47 -0
- package/dist/memory-consolidation-registry.d.ts.map +1 -0
- package/dist/memory-consolidation-registry.js +106 -0
- package/dist/memory-conv-handlers.d.ts +8 -0
- package/dist/memory-conv-handlers.d.ts.map +1 -0
- package/dist/memory-conv-handlers.js +369 -0
- package/dist/memory-conversation-context.d.ts +13 -0
- package/dist/memory-conversation-context.d.ts.map +1 -0
- package/dist/memory-conversation-context.js +22 -0
- package/dist/memory-diagnostics.d.ts +29 -0
- package/dist/memory-diagnostics.d.ts.map +1 -0
- package/dist/memory-diagnostics.js +122 -0
- package/dist/memory-embedding.d.ts +21 -0
- package/dist/memory-embedding.d.ts.map +1 -0
- package/dist/memory-embedding.js +264 -0
- package/dist/memory-handlers.d.ts +19 -0
- package/dist/memory-handlers.d.ts.map +1 -0
- package/dist/memory-handlers.js +1204 -0
- package/dist/memory-maintenance-handlers.d.ts +35 -0
- package/dist/memory-maintenance-handlers.d.ts.map +1 -0
- package/dist/memory-maintenance-handlers.js +219 -0
- package/dist/memory-record-builders.d.ts +4 -0
- package/dist/memory-record-builders.d.ts.map +1 -0
- package/dist/memory-record-builders.js +19 -0
- package/dist/memory-retention.d.ts +31 -0
- package/dist/memory-retention.d.ts.map +1 -0
- package/dist/memory-retention.js +151 -0
- package/dist/memory-retrieval-signals.d.ts +12 -0
- package/dist/memory-retrieval-signals.d.ts.map +1 -0
- package/dist/memory-retrieval-signals.js +100 -0
- package/dist/memory-salience.d.ts +12 -0
- package/dist/memory-salience.d.ts.map +1 -0
- package/dist/memory-salience.js +154 -0
- package/dist/memory-scope-sanitizer.d.ts +6 -0
- package/dist/memory-scope-sanitizer.d.ts.map +1 -0
- package/dist/memory-scope-sanitizer.js +106 -0
- package/dist/memory-target-resolver.d.ts +4 -0
- package/dist/memory-target-resolver.d.ts.map +1 -0
- package/dist/memory-target-resolver.js +73 -0
- package/dist/memory-workflow-port.d.ts +14 -0
- package/dist/memory-workflow-port.d.ts.map +1 -0
- package/dist/memory-workflow-port.js +186 -0
- package/dist/private-json.d.ts +3 -0
- package/dist/private-json.d.ts.map +1 -0
- package/dist/private-json.js +62 -0
- package/dist/promptEnhancer/index.d.ts +3 -0
- package/dist/promptEnhancer/index.d.ts.map +1 -0
- package/dist/promptEnhancer/index.js +5 -0
- package/dist/promptEnhancer/orchestrate.d.ts +2 -0
- package/dist/promptEnhancer/orchestrate.d.ts.map +1 -0
- package/dist/promptEnhancer/orchestrate.js +5 -0
- package/dist/promptEnhancer/routes.d.ts +9 -0
- package/dist/promptEnhancer/routes.d.ts.map +1 -0
- package/dist/promptEnhancer/routes.js +205 -0
- package/dist/qualityIntelligence/capsuleAdapter.d.ts +27 -0
- package/dist/qualityIntelligence/capsuleAdapter.d.ts.map +1 -0
- package/dist/qualityIntelligence/capsuleAdapter.js +57 -0
- package/dist/qualityIntelligence/connectorAuthorization.d.ts +22 -0
- package/dist/qualityIntelligence/connectorAuthorization.d.ts.map +1 -0
- package/dist/qualityIntelligence/connectorAuthorization.js +35 -0
- package/dist/qualityIntelligence/connectorErrors.d.ts +16 -0
- package/dist/qualityIntelligence/connectorErrors.d.ts.map +1 -0
- package/dist/qualityIntelligence/connectorErrors.js +56 -0
- package/dist/qualityIntelligence/connectorRoutes.d.ts +7 -0
- package/dist/qualityIntelligence/connectorRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/connectorRoutes.js +167 -0
- package/dist/qualityIntelligence/editRoutes.d.ts +5 -0
- package/dist/qualityIntelligence/editRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/editRoutes.js +293 -0
- package/dist/qualityIntelligence/exportAssembly.d.ts +22 -0
- package/dist/qualityIntelligence/exportAssembly.d.ts.map +1 -0
- package/dist/qualityIntelligence/exportAssembly.js +352 -0
- package/dist/qualityIntelligence/exportRoutes.d.ts +5 -0
- package/dist/qualityIntelligence/exportRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/exportRoutes.js +320 -0
- package/dist/qualityIntelligence/figma/figmaConcurrency.d.ts +8 -0
- package/dist/qualityIntelligence/figma/figmaConcurrency.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaConcurrency.js +34 -0
- package/dist/qualityIntelligence/figma/figmaConnector.d.ts +65 -0
- package/dist/qualityIntelligence/figma/figmaConnector.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaConnector.js +184 -0
- package/dist/qualityIntelligence/figma/figmaConnectorAudit.d.ts +52 -0
- package/dist/qualityIntelligence/figma/figmaConnectorAudit.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaConnectorAudit.js +63 -0
- package/dist/qualityIntelligence/figma/figmaConnectorErrors.d.ts +31 -0
- package/dist/qualityIntelligence/figma/figmaConnectorErrors.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaConnectorErrors.js +220 -0
- package/dist/qualityIntelligence/figma/figmaConnectorMetrics.d.ts +44 -0
- package/dist/qualityIntelligence/figma/figmaConnectorMetrics.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaConnectorMetrics.js +49 -0
- package/dist/qualityIntelligence/figma/figmaConsent.d.ts +39 -0
- package/dist/qualityIntelligence/figma/figmaConsent.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaConsent.js +62 -0
- package/dist/qualityIntelligence/figma/figmaHttpPort.d.ts +28 -0
- package/dist/qualityIntelligence/figma/figmaHttpPort.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaHttpPort.js +70 -0
- package/dist/qualityIntelligence/figma/figmaObservedActions.d.ts +49 -0
- package/dist/qualityIntelligence/figma/figmaObservedActions.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaObservedActions.js +89 -0
- package/dist/qualityIntelligence/figma/figmaReadiness.d.ts +32 -0
- package/dist/qualityIntelligence/figma/figmaReadiness.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaReadiness.js +67 -0
- package/dist/qualityIntelligence/figma/figmaRenderPort.d.ts +29 -0
- package/dist/qualityIntelligence/figma/figmaRenderPort.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaRenderPort.js +93 -0
- package/dist/qualityIntelligence/figma/figmaResnapshot.d.ts +28 -0
- package/dist/qualityIntelligence/figma/figmaResnapshot.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaResnapshot.js +38 -0
- package/dist/qualityIntelligence/figma/figmaRetry.d.ts +31 -0
- package/dist/qualityIntelligence/figma/figmaRetry.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaRetry.js +62 -0
- package/dist/qualityIntelligence/figma/figmaScopeRef.d.ts +9 -0
- package/dist/qualityIntelligence/figma/figmaScopeRef.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaScopeRef.js +18 -0
- package/dist/qualityIntelligence/figma/figmaScopedPagination.d.ts +86 -0
- package/dist/qualityIntelligence/figma/figmaScopedPagination.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaScopedPagination.js +308 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotBuilder.d.ts +31 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotBuilder.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotBuilder.js +314 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotHash.d.ts +18 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotHash.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotHash.js +63 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotTypes.d.ts +65 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotTypes.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaSnapshotTypes.js +13 -0
- package/dist/qualityIntelligence/figma/figmaTokenSource.d.ts +9 -0
- package/dist/qualityIntelligence/figma/figmaTokenSource.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaTokenSource.js +61 -0
- package/dist/qualityIntelligence/figma/figmaTokenStore.d.ts +19 -0
- package/dist/qualityIntelligence/figma/figmaTokenStore.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaTokenStore.js +156 -0
- package/dist/qualityIntelligence/figma/figmaUrl.d.ts +6 -0
- package/dist/qualityIntelligence/figma/figmaUrl.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/figmaUrl.js +36 -0
- package/dist/qualityIntelligence/figma/index.d.ts +20 -0
- package/dist/qualityIntelligence/figma/index.d.ts.map +1 -0
- package/dist/qualityIntelligence/figma/index.js +26 -0
- package/dist/qualityIntelligence/figmaCodegenRoutes.d.ts +28 -0
- package/dist/qualityIntelligence/figmaCodegenRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaCodegenRoutes.js +165 -0
- package/dist/qualityIntelligence/figmaSnapshotAdapter.d.ts +55 -0
- package/dist/qualityIntelligence/figmaSnapshotAdapter.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshotAdapter.js +219 -0
- package/dist/qualityIntelligence/figmaSnapshotOrchestration.d.ts +64 -0
- package/dist/qualityIntelligence/figmaSnapshotOrchestration.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshotOrchestration.js +203 -0
- package/dist/qualityIntelligence/figmaSnapshotRoutes.d.ts +112 -0
- package/dist/qualityIntelligence/figmaSnapshotRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshotRoutes.js +1063 -0
- package/dist/qualityIntelligence/figmaSnapshotScreenIds.d.ts +19 -0
- package/dist/qualityIntelligence/figmaSnapshotScreenIds.d.ts.map +1 -0
- package/dist/qualityIntelligence/figmaSnapshotScreenIds.js +75 -0
- package/dist/qualityIntelligence/generationPort.d.ts +15 -0
- package/dist/qualityIntelligence/generationPort.d.ts.map +1 -0
- package/dist/qualityIntelligence/generationPort.js +185 -0
- package/dist/qualityIntelligence/handoffErrors.d.ts +9 -0
- package/dist/qualityIntelligence/handoffErrors.d.ts.map +1 -0
- package/dist/qualityIntelligence/handoffErrors.js +21 -0
- package/dist/qualityIntelligence/handoffRoutes.d.ts +15 -0
- package/dist/qualityIntelligence/handoffRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/handoffRoutes.js +341 -0
- package/dist/qualityIntelligence/index.d.ts +17 -0
- package/dist/qualityIntelligence/index.d.ts.map +1 -0
- package/dist/qualityIntelligence/index.js +36 -0
- package/dist/qualityIntelligence/judgePort.d.ts +30 -0
- package/dist/qualityIntelligence/judgePort.d.ts.map +1 -0
- package/dist/qualityIntelligence/judgePort.js +326 -0
- package/dist/qualityIntelligence/modelSelection.d.ts +58 -0
- package/dist/qualityIntelligence/modelSelection.d.ts.map +1 -0
- package/dist/qualityIntelligence/modelSelection.js +148 -0
- package/dist/qualityIntelligence/reCheckRoutes.d.ts +6 -0
- package/dist/qualityIntelligence/reCheckRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/reCheckRoutes.js +1157 -0
- package/dist/qualityIntelligence/retentionEnforcement.d.ts +13 -0
- package/dist/qualityIntelligence/retentionEnforcement.d.ts.map +1 -0
- package/dist/qualityIntelligence/retentionEnforcement.js +47 -0
- package/dist/qualityIntelligence/retentionRoutes.d.ts +8 -0
- package/dist/qualityIntelligence/retentionRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/retentionRoutes.js +74 -0
- package/dist/qualityIntelligence/reviewRoutes.d.ts +5 -0
- package/dist/qualityIntelligence/reviewRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/reviewRoutes.js +145 -0
- package/dist/qualityIntelligence/reviewStore.d.ts +75 -0
- package/dist/qualityIntelligence/reviewStore.d.ts.map +1 -0
- package/dist/qualityIntelligence/reviewStore.js +170 -0
- package/dist/qualityIntelligence/runExecution.d.ts +36 -0
- package/dist/qualityIntelligence/runExecution.d.ts.map +1 -0
- package/dist/qualityIntelligence/runExecution.js +180 -0
- package/dist/qualityIntelligence/runIngestion.d.ts +70 -0
- package/dist/qualityIntelligence/runIngestion.d.ts.map +1 -0
- package/dist/qualityIntelligence/runIngestion.js +1235 -0
- package/dist/qualityIntelligence/runRegistry.d.ts +31 -0
- package/dist/qualityIntelligence/runRegistry.d.ts.map +1 -0
- package/dist/qualityIntelligence/runRegistry.js +66 -0
- package/dist/qualityIntelligence/runRoutes.d.ts +16 -0
- package/dist/qualityIntelligence/runRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/runRoutes.js +357 -0
- package/dist/qualityIntelligence/traceabilityRoutes.d.ts +5 -0
- package/dist/qualityIntelligence/traceabilityRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/traceabilityRoutes.js +173 -0
- package/dist/qualityIntelligence/uiRoutes.d.ts +7 -0
- package/dist/qualityIntelligence/uiRoutes.d.ts.map +1 -0
- package/dist/qualityIntelligence/uiRoutes.js +336 -0
- package/dist/read-handlers.d.ts +9 -0
- package/dist/read-handlers.d.ts.map +1 -0
- package/dist/read-handlers.js +265 -0
- package/dist/relationship-handlers.d.ts +191 -0
- package/dist/relationship-handlers.d.ts.map +1 -0
- package/dist/relationship-handlers.js +0 -0
- package/dist/routes.d.ts +37 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +507 -0
- package/dist/run-engine.d.ts +25 -0
- package/dist/run-engine.d.ts.map +1 -0
- package/dist/run-engine.js +385 -0
- package/dist/run-handlers.d.ts +9 -0
- package/dist/run-handlers.d.ts.map +1 -0
- package/dist/run-handlers.js +465 -0
- package/dist/run-request.d.ts +17 -0
- package/dist/run-request.d.ts.map +1 -0
- package/dist/run-request.js +219 -0
- package/dist/runs.d.ts +47 -0
- package/dist/runs.d.ts.map +1 -0
- package/dist/runs.js +100 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +152 -0
- package/dist/sink.d.ts +28 -0
- package/dist/sink.d.ts.map +1 -0
- package/dist/sink.js +80 -0
- package/dist/sse-write.d.ts +9 -0
- package/dist/sse-write.d.ts.map +1 -0
- package/dist/sse-write.js +26 -0
- package/dist/sse.d.ts +8 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +27 -0
- package/dist/static.d.ts +5 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/static.js +76 -0
- package/dist/store/chats.d.ts +17 -0
- package/dist/store/chats.d.ts.map +1 -0
- package/dist/store/chats.js +624 -0
- package/dist/store/db.d.ts +11 -0
- package/dist/store/db.d.ts.map +1 -0
- package/dist/store/db.js +203 -0
- package/dist/store/errors.d.ts +13 -0
- package/dist/store/errors.d.ts.map +1 -0
- package/dist/store/errors.js +30 -0
- package/dist/store/index.d.ts +7 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +6 -0
- package/dist/store/messages.d.ts +8 -0
- package/dist/store/messages.d.ts.map +1 -0
- package/dist/store/messages.js +149 -0
- package/dist/store/paths.d.ts +5 -0
- package/dist/store/paths.d.ts.map +1 -0
- package/dist/store/paths.js +84 -0
- package/dist/store/projects.d.ts +8 -0
- package/dist/store/projects.d.ts.map +1 -0
- package/dist/store/projects.js +59 -0
- package/dist/store/relationship-audit.d.ts +42 -0
- package/dist/store/relationship-audit.d.ts.map +1 -0
- package/dist/store/relationship-audit.js +155 -0
- package/dist/store/relationships.d.ts +191 -0
- package/dist/store/relationships.d.ts.map +1 -0
- package/dist/store/relationships.js +724 -0
- package/dist/store/schema.d.ts +4 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/dist/store/schema.js +220 -0
- package/dist/store/types.d.ts +29 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +8 -0
- package/dist/store/validation.d.ts +7 -0
- package/dist/store/validation.d.ts.map +1 -0
- package/dist/store/validation.js +117 -0
- package/dist/store-handlers.d.ts +17 -0
- package/dist/store-handlers.d.ts.map +1 -0
- package/dist/store-handlers.js +872 -0
- package/dist/terminal-errors.d.ts +22 -0
- package/dist/terminal-errors.d.ts.map +1 -0
- package/dist/terminal-errors.js +45 -0
- package/dist/terminal-evidence.d.ts +21 -0
- package/dist/terminal-evidence.d.ts.map +1 -0
- package/dist/terminal-evidence.js +65 -0
- package/dist/terminal-routes.d.ts +10 -0
- package/dist/terminal-routes.d.ts.map +1 -0
- package/dist/terminal-routes.js +219 -0
- package/dist/terminal.d.ts +68 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +855 -0
- package/package.json +52 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type QualityIntelligenceRunDeletedEvent } from "@oscharko-dev/keiko-evidence";
|
|
2
|
+
export type QiRetentionAuditSink = (event: QualityIntelligenceRunDeletedEvent) => void;
|
|
3
|
+
export interface EnforceQiRetentionOptions {
|
|
4
|
+
readonly evidenceDir: string;
|
|
5
|
+
readonly now?: (() => number) | undefined;
|
|
6
|
+
readonly auditSink?: QiRetentionAuditSink | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Run QI run-retention once at server startup. Best-effort: any fault is swallowed so it never
|
|
10
|
+
* crashes bootstrap. Forwards each deletion receipt's audit event to `auditSink` exactly once.
|
|
11
|
+
*/
|
|
12
|
+
export declare function enforceQiRetentionAtStartup(options: EnforceQiRetentionOptions): void;
|
|
13
|
+
//# sourceMappingURL=retentionEnforcement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retentionEnforcement.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/retentionEnforcement.ts"],"names":[],"mappings":"AAmBA,OAAO,EAEL,KAAK,kCAAkC,EACxC,MAAM,8BAA8B,CAAC;AAOtC,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,kCAAkC,KAAK,IAAI,CAAC;AAQvF,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;IAE1C,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;CACvD;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAgBpF"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// QI retention-enforcement bootstrap seam (Issue #1323 AC4 — make retention policy ids operational).
|
|
2
|
+
//
|
|
3
|
+
// keiko-evidence ships the pure decision + hardened deletion + the `enforceQualityIntelligenceRetentionPolicy`
|
|
4
|
+
// orchestrator, but it is a LEAF: it never touches the audit ledger (ADR-0019 trust-rule 6). This
|
|
5
|
+
// module is the server-owned wrapper that (a) passes the SAME server-owned companion suffixes + figma
|
|
6
|
+
// snapshot side-file root the user-initiated DELETE route uses (single source of truth in
|
|
7
|
+
// retentionRoutes.ts), and (b) forwards every deletion receipt's audit event to an injectable sink.
|
|
8
|
+
//
|
|
9
|
+
// It is called ONCE per server instance from `buildUiHandlerDeps` (lazy, no timer — a setInterval
|
|
10
|
+
// would race the filesystem-backed store). It is best-effort and CRASH-AWARE: it never throws into
|
|
11
|
+
// bootstrap (mirrors migrateLocalConfigCredentials), so a transient fs fault simply re-runs next start.
|
|
12
|
+
//
|
|
13
|
+
// NOTE (audit visibility): keiko-server has no global persistent QI audit ledger today — the
|
|
14
|
+
// user-initiated DELETE route "forwards" its receipt by returning it in the HTTP response to the
|
|
15
|
+
// caller. The bootstrap purge has no HTTP caller, so the default sink is a no-op: production startup
|
|
16
|
+
// purge receipts are currently DROPPED pending a future audit-ledger wiring (recorded in ADR-0048).
|
|
17
|
+
// The sink is injectable so tests assert forwarding and a future ledger can be wired in one place.
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import { enforceQualityIntelligenceRetentionPolicy, } from "@oscharko-dev/keiko-evidence";
|
|
20
|
+
import { QI_SNAPSHOT_SIDE_FILE_ROOT_SUBDIR, QI_SUBDIR, SERVER_OWNED_COMPANION_SUFFIXES, } from "./retentionRoutes.js";
|
|
21
|
+
// Default sink: drop the event. keiko-server has no global persistent QI audit ledger today (see
|
|
22
|
+
// module note); production startup purge receipts are currently DROPPED pending a future ledger.
|
|
23
|
+
const noopAuditSink = (_event) => {
|
|
24
|
+
// Intentionally no-op until a persistent QI audit ledger seam exists (ADR-0048 follow-up).
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Run QI run-retention once at server startup. Best-effort: any fault is swallowed so it never
|
|
28
|
+
* crashes bootstrap. Forwards each deletion receipt's audit event to `auditSink` exactly once.
|
|
29
|
+
*/
|
|
30
|
+
export function enforceQiRetentionAtStartup(options) {
|
|
31
|
+
const sink = options.auditSink ?? noopAuditSink;
|
|
32
|
+
try {
|
|
33
|
+
const { receipts } = enforceQualityIntelligenceRetentionPolicy({
|
|
34
|
+
evidenceDir: options.evidenceDir,
|
|
35
|
+
now: options.now,
|
|
36
|
+
companionSuffixes: SERVER_OWNED_COMPANION_SUFFIXES,
|
|
37
|
+
sideFileRoot: join(options.evidenceDir, QI_SUBDIR, QI_SNAPSHOT_SIDE_FILE_ROOT_SUBDIR),
|
|
38
|
+
});
|
|
39
|
+
for (const receipt of receipts) {
|
|
40
|
+
sink(receipt.auditEvent);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Best-effort bootstrap side-effect: a transient fs fault leaves the store untouched and the
|
|
45
|
+
// next startup retries. Never propagates into server construction.
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RouteContext, RouteResult, RouteDefinition } from "../routes.js";
|
|
2
|
+
import type { UiHandlerDeps } from "../deps.js";
|
|
3
|
+
export declare const SERVER_OWNED_COMPANION_SUFFIXES: readonly string[];
|
|
4
|
+
export declare const QI_SUBDIR = "qi";
|
|
5
|
+
export declare const QI_SNAPSHOT_SIDE_FILE_ROOT_SUBDIR = "figma-snapshots";
|
|
6
|
+
export declare function handleQiDeleteRun(ctx: RouteContext, deps: UiHandlerDeps): RouteResult;
|
|
7
|
+
export declare const QI_RETENTION_ROUTE_GROUP: readonly RouteDefinition[];
|
|
8
|
+
//# sourceMappingURL=retentionRoutes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retentionRoutes.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/retentionRoutes.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAShD,eAAO,MAAM,+BAA+B,EAAE,SAAS,MAAM,EAM5D,CAAC;AAMF,eAAO,MAAM,SAAS,OAAO,CAAC;AAC9B,eAAO,MAAM,iCAAiC,oBAAoB,CAAC;AAOnE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CA+BrF;AAED,eAAO,MAAM,wBAAwB,EAAE,SAAS,eAAe,EAE9D,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Quality Intelligence run-deletion BFF route (Epic #270, Issue #282 follow-up; ADR-0023 D8).
|
|
2
|
+
//
|
|
3
|
+
// * DELETE /api/quality-intelligence/runs/:id — delete a run and ALL its local companions
|
|
4
|
+
//
|
|
5
|
+
// ADR-0023 (lines ~487-492) assigns the deletion-control wiring to the consuming epic: a UI/BFF
|
|
6
|
+
// delete action -> `deleteQualityIntelligenceRun` (the hardened keiko-evidence primitive) passing
|
|
7
|
+
// the SERVER-owned `companionSuffixes`. This route is that wiring. It passes EVERY server-owned
|
|
8
|
+
// companion so a deleted run leaves no orphaned customer-derived content (Stop-Condition b:
|
|
9
|
+
// lifecycle must not bypass retention semantics): `.review.json` (reviewer labels + the append-only
|
|
10
|
+
// review audit log, Issue #282), the three figma connector companions, the figma snapshot record,
|
|
11
|
+
// and the figma snapshot side-file directory. `.candidates.json` is evidence-owned and always swept
|
|
12
|
+
// by the primitive. CSRF is enforced by the dispatch layer for mutating methods.
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { deleteQualityIntelligenceRun, loadQualityIntelligenceRun, } from "@oscharko-dev/keiko-evidence";
|
|
15
|
+
// Companion artifacts written alongside the run manifest under `qi/` that are owned by HIGHER layers
|
|
16
|
+
// (keiko-server), not by keiko-evidence. The primitive ALWAYS sweeps the evidence-owned
|
|
17
|
+
// `.candidates.json`; these must be passed explicitly or a deleted run orphans them. Kept in one
|
|
18
|
+
// place so a new server-owned companion is added here rather than rediscovered per call site.
|
|
19
|
+
// Exported as the SINGLE SOURCE OF TRUTH for server-owned QI companion suffixes so both the
|
|
20
|
+
// user-initiated DELETE route AND the bootstrap retention seam (retentionEnforcement.ts) sweep the
|
|
21
|
+
// identical set — a new server-owned companion is added here once.
|
|
22
|
+
export const SERVER_OWNED_COMPANION_SUFFIXES = [
|
|
23
|
+
".review.json", // Issue #282 — reviewer labels + append-only review audit log
|
|
24
|
+
".figma-codegen.json", // Epic #750 — figma code-generation companion
|
|
25
|
+
".figma-audit.json", // Epic #750 — figma connector audit companion
|
|
26
|
+
".figma-consent.json", // Epic #750 — figma consent companion
|
|
27
|
+
".figma-snapshot.json", // Epic #750 — figma snapshot record
|
|
28
|
+
];
|
|
29
|
+
// The QI evidence sub-directory and the figma snapshot side-file sub-directory, mirrored from
|
|
30
|
+
// keiko-evidence (`QI_SUBDIR` / `SIDE_FILE_SUBDIR`). `sideFileRoot` lets the primitive remove
|
|
31
|
+
// `<evidenceDir>/qi/figma-snapshots/<runId>/` (binary snapshot side-files) alongside the manifest.
|
|
32
|
+
// Exported for reuse by the bootstrap retention seam (single source of truth).
|
|
33
|
+
export const QI_SUBDIR = "qi";
|
|
34
|
+
export const QI_SNAPSHOT_SIDE_FILE_ROOT_SUBDIR = "figma-snapshots";
|
|
35
|
+
const errorResult = (status, code, message) => ({
|
|
36
|
+
status,
|
|
37
|
+
body: { error: { code, message } },
|
|
38
|
+
});
|
|
39
|
+
export function handleQiDeleteRun(ctx, deps) {
|
|
40
|
+
const { id } = ctx.params;
|
|
41
|
+
if (id === undefined || id.trim().length === 0) {
|
|
42
|
+
return errorResult(400, "QI_BAD_REQUEST", "Run id is required.");
|
|
43
|
+
}
|
|
44
|
+
const evidenceDir = deps.evidenceDir;
|
|
45
|
+
if (evidenceDir === undefined) {
|
|
46
|
+
return errorResult(500, "QI_NO_EVIDENCE_DIR", "The evidence directory is not configured.");
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
// Not-found is an explicit 404 (the primitive itself is idempotent and would report "absent",
|
|
50
|
+
// but the BFF gives the caller a clear signal that nothing was there to delete).
|
|
51
|
+
if (loadQualityIntelligenceRun(id, { evidenceDir }) === undefined) {
|
|
52
|
+
return errorResult(404, "QI_NOT_FOUND", "Quality Intelligence run not found.");
|
|
53
|
+
}
|
|
54
|
+
const receipt = deleteQualityIntelligenceRun(id, {
|
|
55
|
+
evidenceDir,
|
|
56
|
+
companionSuffixes: SERVER_OWNED_COMPANION_SUFFIXES,
|
|
57
|
+
sideFileRoot: join(evidenceDir, QI_SUBDIR, QI_SNAPSHOT_SIDE_FILE_ROOT_SUBDIR),
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
status: 200,
|
|
61
|
+
body: {
|
|
62
|
+
runId: receipt.runId,
|
|
63
|
+
status: receipt.status,
|
|
64
|
+
removedCompanionSuffixes: receipt.removedCompanionSuffixes,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return errorResult(500, "QI_DELETE_FAILED", "Failed to delete the Quality Intelligence run.");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export const QI_RETENTION_ROUTE_GROUP = [
|
|
73
|
+
{ method: "DELETE", pattern: "/api/quality-intelligence/runs/:id", handler: handleQiDeleteRun },
|
|
74
|
+
];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RouteContext, RouteResult, RouteDefinition } from "../routes.js";
|
|
2
|
+
import type { UiHandlerDeps } from "../deps.js";
|
|
3
|
+
export declare function handleQiReview(ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
|
|
4
|
+
export declare const QI_REVIEW_ROUTE_GROUP: readonly RouteDefinition[];
|
|
5
|
+
//# sourceMappingURL=reviewRoutes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewRoutes.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/reviewRoutes.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgHhD,wBAAsB,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CA4CjG;AAED,eAAO,MAAM,qBAAqB,EAAE,SAAS,eAAe,EAE3D,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// Quality Intelligence review-action BFF route (Epic #270, Issue #282).
|
|
2
|
+
//
|
|
3
|
+
// * POST /api/quality-intelligence/runs/:id/review — record a human review decision
|
|
4
|
+
//
|
|
5
|
+
// Applies an explicit, auditable review decision (approve / reject / request-changes / reopen /
|
|
6
|
+
// withdraw) to a run or a single candidate, persisting it to the review companion artifact. Nothing
|
|
7
|
+
// is approved by default; a decision is required to flip state. The route never echoes raw content.
|
|
8
|
+
import { loadQualityIntelligenceRun } from "@oscharko-dev/keiko-evidence";
|
|
9
|
+
import { normaliseCandidateText } from "@oscharko-dev/keiko-quality-intelligence";
|
|
10
|
+
import { applyReviewDecision, QualityIntelligenceReviewTransitionRejected, } from "./reviewStore.js";
|
|
11
|
+
const MAX_BODY_BYTES = 16 * 1024;
|
|
12
|
+
const ACTIONS = new Set([
|
|
13
|
+
"approve",
|
|
14
|
+
"reject",
|
|
15
|
+
"request-changes",
|
|
16
|
+
"reopen",
|
|
17
|
+
"withdraw",
|
|
18
|
+
]);
|
|
19
|
+
class BodyTooLargeError extends Error {
|
|
20
|
+
}
|
|
21
|
+
const readBody = (req) => new Promise((resolve, reject) => {
|
|
22
|
+
const chunks = [];
|
|
23
|
+
let total = 0;
|
|
24
|
+
let capped = false;
|
|
25
|
+
req.on("data", (chunk) => {
|
|
26
|
+
total += chunk.length;
|
|
27
|
+
if (total > MAX_BODY_BYTES) {
|
|
28
|
+
if (!capped) {
|
|
29
|
+
capped = true;
|
|
30
|
+
chunks.length = 0;
|
|
31
|
+
reject(new BodyTooLargeError());
|
|
32
|
+
req.resume();
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
chunks.push(chunk);
|
|
37
|
+
});
|
|
38
|
+
req.on("end", () => {
|
|
39
|
+
if (!capped)
|
|
40
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
41
|
+
});
|
|
42
|
+
req.on("error", reject);
|
|
43
|
+
});
|
|
44
|
+
const errorResult = (status, code, message) => ({
|
|
45
|
+
status,
|
|
46
|
+
body: { error: { code, message } },
|
|
47
|
+
});
|
|
48
|
+
const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49
|
+
function parseDecision(body) {
|
|
50
|
+
const action = body.action;
|
|
51
|
+
if (typeof action !== "string" || !ACTIONS.has(action))
|
|
52
|
+
return undefined;
|
|
53
|
+
const candidateId = typeof body.candidateId === "string" ? body.candidateId : undefined;
|
|
54
|
+
const scope = candidateId !== undefined ? "candidate" : "run";
|
|
55
|
+
const rawLabel = typeof body.reviewerLabel === "string" ? normaliseCandidateText(body.reviewerLabel) : "";
|
|
56
|
+
const reviewerLabel = rawLabel.length > 0 ? rawLabel.slice(0, 80) : "reviewer";
|
|
57
|
+
return {
|
|
58
|
+
action: action,
|
|
59
|
+
scope,
|
|
60
|
+
reviewerLabel,
|
|
61
|
+
...(candidateId ? { candidateId } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function readDecision(req) {
|
|
65
|
+
let raw;
|
|
66
|
+
try {
|
|
67
|
+
raw = await readBody(req);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
result: errorResult(413, "QI_BODY_TOO_LARGE", "Review body is too large."),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
let parsed;
|
|
76
|
+
try {
|
|
77
|
+
parsed = JSON.parse(raw);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return {
|
|
81
|
+
ok: false,
|
|
82
|
+
result: errorResult(400, "QI_BAD_REQUEST", "Review body is not valid JSON."),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (!isObject(parsed)) {
|
|
86
|
+
return {
|
|
87
|
+
ok: false,
|
|
88
|
+
result: errorResult(400, "QI_BAD_REQUEST", "Review body must be an object."),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const decision = parseDecision(parsed);
|
|
92
|
+
if (decision === undefined) {
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
result: errorResult(400, "QI_BAD_ACTION", "A valid review action is required."),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return { ok: true, decision };
|
|
99
|
+
}
|
|
100
|
+
export async function handleQiReview(ctx, deps) {
|
|
101
|
+
const { id } = ctx.params;
|
|
102
|
+
if (id === undefined || id.trim().length === 0) {
|
|
103
|
+
return errorResult(400, "QI_BAD_REQUEST", "Run id is required.");
|
|
104
|
+
}
|
|
105
|
+
const evidenceDir = deps.evidenceDir;
|
|
106
|
+
if (evidenceDir === undefined) {
|
|
107
|
+
return errorResult(500, "QI_NO_EVIDENCE_DIR", "The evidence directory is not configured.");
|
|
108
|
+
}
|
|
109
|
+
const parsed = await readDecision(ctx.req);
|
|
110
|
+
if (!parsed.ok)
|
|
111
|
+
return parsed.result;
|
|
112
|
+
const { decision } = parsed;
|
|
113
|
+
try {
|
|
114
|
+
if (loadQualityIntelligenceRun(id, { evidenceDir }) === undefined) {
|
|
115
|
+
return errorResult(404, "QI_NOT_FOUND", "Quality Intelligence run not found.");
|
|
116
|
+
}
|
|
117
|
+
const next = applyReviewDecision({
|
|
118
|
+
runId: id,
|
|
119
|
+
evidenceDir,
|
|
120
|
+
action: decision.action,
|
|
121
|
+
scope: decision.scope,
|
|
122
|
+
reviewerLabel: decision.reviewerLabel,
|
|
123
|
+
now: new Date().toISOString(),
|
|
124
|
+
redact: deps.redactor,
|
|
125
|
+
...(decision.candidateId ? { candidateId: decision.candidateId } : {}),
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
status: 200,
|
|
129
|
+
body: {
|
|
130
|
+
runState: next.runState,
|
|
131
|
+
candidateStates: next.candidateStates,
|
|
132
|
+
auditCount: next.auditLog.length,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (error instanceof QualityIntelligenceReviewTransitionRejected) {
|
|
138
|
+
return errorResult(409, "QI_REVIEW_TRANSITION_NOT_ALLOWED", `Review transition not permitted: cannot ${error.action} a run/candidate in state "${error.from}".`);
|
|
139
|
+
}
|
|
140
|
+
return errorResult(500, "QI_REVIEW_FAILED", "Failed to record the review decision.");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export const QI_REVIEW_ROUTE_GROUP = [
|
|
144
|
+
{ method: "POST", pattern: "/api/quality-intelligence/runs/:id/review", handler: handleQiReview },
|
|
145
|
+
];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type QualityIntelligence as QI } from "@oscharko-dev/keiko-contracts";
|
|
2
|
+
type ReviewState = QI.QualityIntelligenceReviewState;
|
|
3
|
+
/** Redacts a payload leaf before it is persisted; `deepRedactStrings` preserves string→string. */
|
|
4
|
+
export type ReviewRedactor = (value: unknown) => unknown;
|
|
5
|
+
export declare const QI_REVIEW_SCHEMA_VERSION: 1;
|
|
6
|
+
export type QiReviewAction = "approve" | "reject" | "request-changes" | "reopen" | "withdraw";
|
|
7
|
+
export type QiAuditAction = QiReviewAction | "edit";
|
|
8
|
+
export interface QiReviewAuditEntry {
|
|
9
|
+
readonly at: string;
|
|
10
|
+
readonly action: QiAuditAction;
|
|
11
|
+
readonly scope: "run" | "candidate";
|
|
12
|
+
readonly candidateId?: string;
|
|
13
|
+
readonly reviewerLabel: string;
|
|
14
|
+
readonly fromState: ReviewState;
|
|
15
|
+
readonly toState: ReviewState;
|
|
16
|
+
}
|
|
17
|
+
export interface QiReviewStateArtifact {
|
|
18
|
+
readonly qiReviewSchemaVersion: typeof QI_REVIEW_SCHEMA_VERSION;
|
|
19
|
+
readonly runId: string;
|
|
20
|
+
readonly runState: ReviewState;
|
|
21
|
+
readonly candidateStates: Readonly<Record<string, ReviewState>>;
|
|
22
|
+
readonly auditLog: readonly QiReviewAuditEntry[];
|
|
23
|
+
readonly lastUpdatedAt: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const loadRunReviewState: (runId: string, evidenceDir: string) => QiReviewStateArtifact | undefined;
|
|
26
|
+
export declare const runReviewStateOf: (artifact: QiReviewStateArtifact | undefined) => ReviewState;
|
|
27
|
+
export declare const candidateReviewStateOf: (artifact: QiReviewStateArtifact | undefined, candidateId: string) => ReviewState;
|
|
28
|
+
/**
|
|
29
|
+
* Thrown by `applyReviewDecision` when the requested action is not a legal transition from the
|
|
30
|
+
* current review state. Nothing is persisted and no audit entry is appended — the append-only log
|
|
31
|
+
* never attests a transition the audited domain declares illegal. The route maps this to a 409.
|
|
32
|
+
*/
|
|
33
|
+
export declare class QualityIntelligenceReviewTransitionRejected extends Error {
|
|
34
|
+
readonly from: ReviewState;
|
|
35
|
+
readonly action: QiReviewAction;
|
|
36
|
+
readonly toState: ReviewState;
|
|
37
|
+
constructor(from: ReviewState, action: QiReviewAction, toState: ReviewState);
|
|
38
|
+
}
|
|
39
|
+
export interface ApplyReviewDecisionInput {
|
|
40
|
+
readonly runId: string;
|
|
41
|
+
readonly evidenceDir: string;
|
|
42
|
+
readonly action: QiReviewAction;
|
|
43
|
+
readonly scope: "run" | "candidate";
|
|
44
|
+
readonly candidateId?: string;
|
|
45
|
+
readonly reviewerLabel: string;
|
|
46
|
+
readonly now: string;
|
|
47
|
+
/** Redacts the reviewer label before it lands in the persisted audit log (Issue #282 FIX M1). */
|
|
48
|
+
readonly redact: ReviewRedactor;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Apply a review decision and persist the updated artifact. Validates transition legality first
|
|
52
|
+
* (FIX A): an illegal transition throws `QualityIntelligenceReviewTransitionRejected` and persists
|
|
53
|
+
* nothing — no audit entry is ever appended for a rejected transition. On success, appends an
|
|
54
|
+
* append-only audit entry (with a redacted reviewer label, FIX M1) and returns the new artifact.
|
|
55
|
+
* The caller is responsible for authorising the action.
|
|
56
|
+
*/
|
|
57
|
+
export declare const applyReviewDecision: (input: ApplyReviewDecisionInput) => QiReviewStateArtifact;
|
|
58
|
+
export interface AppendEditAuditInput {
|
|
59
|
+
readonly runId: string;
|
|
60
|
+
readonly evidenceDir: string;
|
|
61
|
+
readonly candidateId: string;
|
|
62
|
+
readonly reviewerLabel: string;
|
|
63
|
+
readonly now: string;
|
|
64
|
+
/** Redacts the reviewer label before it lands in the persisted audit log (Issue #282 FIX M1). */
|
|
65
|
+
readonly redact: ReviewRedactor;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Append an append-only `edit` audit entry for an inline candidate edit. Review state is NOT
|
|
69
|
+
* transitioned — `fromState`/`toState` are the candidate's existing review state. The reviewer label
|
|
70
|
+
* is redacted before persist (FIX M1). Persists and returns the updated review artifact (created
|
|
71
|
+
* empty on first use).
|
|
72
|
+
*/
|
|
73
|
+
export declare const appendEditAudit: (input: AppendEditAuditInput) => QiReviewStateArtifact;
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=reviewStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewStore.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/reviewStore.ts"],"names":[],"mappings":"AAYA,OAAO,EAAuB,KAAK,mBAAmB,IAAI,EAAE,EAAE,MAAM,+BAA+B,CAAC;AAGpG,KAAK,WAAW,GAAG,EAAE,CAAC,8BAA8B,CAAC;AAErD,kGAAkG;AAClG,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAazD,eAAO,MAAM,wBAAwB,EAAG,CAAU,CAAC;AAOnD,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAK9F,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,qBAAqB,EAAE,OAAO,wBAAwB,CAAC;IAChE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,QAAQ,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAmCD,eAAO,MAAM,kBAAkB,GAC7B,OAAO,MAAM,EACb,aAAa,MAAM,KAClB,qBAAqB,GAAG,SAA8C,CAAC;AAE1E,eAAO,MAAM,gBAAgB,GAAI,UAAU,qBAAqB,GAAG,SAAS,KAAG,WACjD,CAAC;AAE/B,eAAO,MAAM,sBAAsB,GACjC,UAAU,qBAAqB,GAAG,SAAS,EAC3C,aAAa,MAAM,KAClB,WAGF,CAAC;AA2BF;;;;GAIG;AACH,qBAAa,2CAA4C,SAAQ,KAAK;IACpE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;gBAElB,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW;CAO5E;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;CACjC;AAWD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,wBAAwB,KAAG,qBAiCrE,CAAC;AAIF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;CACjC;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,oBAAoB,KAAG,qBAoB7D,CAAC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// Quality Intelligence review-state companion store (Epic #270, Issue #282).
|
|
2
|
+
//
|
|
3
|
+
// The run manifest is immutable evidence; the candidate artifact is the generated body. The MUTABLE
|
|
4
|
+
// human-review/lifecycle decisions (per-candidate + run-level approve / reject / request-changes,
|
|
5
|
+
// plus an append-only audit log) live in a third companion artifact `<runId>.review.json`, managed
|
|
6
|
+
// through the generic contained JSON artifact store from keiko-evidence. Default state is "open" —
|
|
7
|
+
// nothing is approved by default (#282 AC). All reads tolerate a missing artifact.
|
|
8
|
+
import { createNodeContainedJsonArtifactStore, } from "@oscharko-dev/keiko-evidence";
|
|
9
|
+
import { QualityIntelligence } from "@oscharko-dev/keiko-contracts";
|
|
10
|
+
import { QualityIntelligenceReview } from "@oscharko-dev/keiko-quality-intelligence";
|
|
11
|
+
/**
|
|
12
|
+
* Redact a reviewer label before it lands in the persisted (append-only) audit log. The label is
|
|
13
|
+
* user-supplied, so a secret-shaped value must be scrubbed at persist time — the `.review.json`
|
|
14
|
+
* companion otherwise bypasses the QI persist redactor (Issue #282 FIX M1). The live redactor maps
|
|
15
|
+
* string→string; the non-string fallback keeps the type honest without `any`.
|
|
16
|
+
*/
|
|
17
|
+
const redactLabel = (label, redact) => {
|
|
18
|
+
const redacted = redact(label);
|
|
19
|
+
return typeof redacted === "string" ? redacted : label;
|
|
20
|
+
};
|
|
21
|
+
export const QI_REVIEW_SCHEMA_VERSION = 1;
|
|
22
|
+
const REVIEW_SUFFIX = ".review.json";
|
|
23
|
+
const REVIEW_STATES = new Set(QualityIntelligence.QUALITY_INTELLIGENCE_REVIEW_STATES);
|
|
24
|
+
const isReviewState = (value) => typeof value === "string" && REVIEW_STATES.has(value);
|
|
25
|
+
// FIX L1 (Issue #282) — candidate ids are arbitrary strings. Building the candidate-state map over a
|
|
26
|
+
// null-prototype object means a candidate literally named `__proto__` / `constructor` cannot collide
|
|
27
|
+
// with an Object.prototype member (no prototype-pollution, no spurious own-key reads). Behaviour is
|
|
28
|
+
// identical for normal ids.
|
|
29
|
+
const toNullProtoStates = (source) => {
|
|
30
|
+
const target = Object.create(null);
|
|
31
|
+
for (const [id, state] of Object.entries(source))
|
|
32
|
+
target[id] = state;
|
|
33
|
+
return target;
|
|
34
|
+
};
|
|
35
|
+
const parseArtifact = (value) => {
|
|
36
|
+
if (typeof value !== "object" || value === null)
|
|
37
|
+
return undefined;
|
|
38
|
+
const record = value;
|
|
39
|
+
if (record.qiReviewSchemaVersion !== QI_REVIEW_SCHEMA_VERSION)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (typeof record.runId !== "string" || !isReviewState(record.runState))
|
|
42
|
+
return undefined;
|
|
43
|
+
if (typeof record.candidateStates !== "object" || record.candidateStates === null)
|
|
44
|
+
return undefined;
|
|
45
|
+
// Rehydrate candidateStates onto a null-proto object so a persisted `__proto__`/`constructor`
|
|
46
|
+
// candidate id round-trips as an own key rather than the prototype member it was parsed into.
|
|
47
|
+
const candidateStates = toNullProtoStates(record.candidateStates);
|
|
48
|
+
return { ...value, candidateStates };
|
|
49
|
+
};
|
|
50
|
+
const storeFor = (evidenceDir) => createNodeContainedJsonArtifactStore(evidenceDir, REVIEW_SUFFIX, { parse: parseArtifact });
|
|
51
|
+
export const loadRunReviewState = (runId, evidenceDir) => storeFor(evidenceDir).load(runId);
|
|
52
|
+
export const runReviewStateOf = (artifact) => artifact?.runState ?? "open";
|
|
53
|
+
export const candidateReviewStateOf = (artifact, candidateId) => {
|
|
54
|
+
const state = artifact?.candidateStates[candidateId];
|
|
55
|
+
return isReviewState(state) ? state : "open";
|
|
56
|
+
};
|
|
57
|
+
// ─── Mutation (used by the review-action route, Issue #282) ─────────────────────
|
|
58
|
+
const ACTION_TARGET = {
|
|
59
|
+
approve: "approved",
|
|
60
|
+
reject: "rejected",
|
|
61
|
+
"request-changes": "changes-requested",
|
|
62
|
+
reopen: "open",
|
|
63
|
+
withdraw: "withdrawn",
|
|
64
|
+
};
|
|
65
|
+
// FIX A (Issue #282) — legal-transition predicate, resurrecting the audited pure terminal-state
|
|
66
|
+
// check from keiko-quality-intelligence. A transition from `from` via `action` (target `to`) is
|
|
67
|
+
// legal iff:
|
|
68
|
+
// * to !== from (reject every no-op, including reopen-from-open), AND
|
|
69
|
+
// * action === "reopen" OR the source state is not terminal.
|
|
70
|
+
// reopen is the deliberate, audited undo from any non-open state (changes-requested / approved /
|
|
71
|
+
// rejected / withdrawn → open). Every other action (approve / reject / request-changes / withdraw)
|
|
72
|
+
// is legal only from a non-terminal state — this blocks silent illegal flips (approve a rejected,
|
|
73
|
+
// reject an approved) while keeping re-decision possible via an explicit reopen.
|
|
74
|
+
const isLegalTransition = (from, action) => {
|
|
75
|
+
const to = ACTION_TARGET[action];
|
|
76
|
+
if (to === from)
|
|
77
|
+
return false;
|
|
78
|
+
return action === "reopen" || !QualityIntelligenceReview.isTerminalReviewState(from);
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Thrown by `applyReviewDecision` when the requested action is not a legal transition from the
|
|
82
|
+
* current review state. Nothing is persisted and no audit entry is appended — the append-only log
|
|
83
|
+
* never attests a transition the audited domain declares illegal. The route maps this to a 409.
|
|
84
|
+
*/
|
|
85
|
+
export class QualityIntelligenceReviewTransitionRejected extends Error {
|
|
86
|
+
from;
|
|
87
|
+
action;
|
|
88
|
+
toState;
|
|
89
|
+
constructor(from, action, toState) {
|
|
90
|
+
super(`Review transition ${from} → ${action} (${toState}) is not permitted.`);
|
|
91
|
+
this.name = "QualityIntelligenceReviewTransitionRejected";
|
|
92
|
+
this.from = from;
|
|
93
|
+
this.action = action;
|
|
94
|
+
this.toState = toState;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const emptyArtifact = (runId, now) => ({
|
|
98
|
+
qiReviewSchemaVersion: QI_REVIEW_SCHEMA_VERSION,
|
|
99
|
+
runId,
|
|
100
|
+
runState: "open",
|
|
101
|
+
candidateStates: toNullProtoStates({}),
|
|
102
|
+
auditLog: [],
|
|
103
|
+
lastUpdatedAt: now,
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* Apply a review decision and persist the updated artifact. Validates transition legality first
|
|
107
|
+
* (FIX A): an illegal transition throws `QualityIntelligenceReviewTransitionRejected` and persists
|
|
108
|
+
* nothing — no audit entry is ever appended for a rejected transition. On success, appends an
|
|
109
|
+
* append-only audit entry (with a redacted reviewer label, FIX M1) and returns the new artifact.
|
|
110
|
+
* The caller is responsible for authorising the action.
|
|
111
|
+
*/
|
|
112
|
+
export const applyReviewDecision = (input) => {
|
|
113
|
+
const current = loadRunReviewState(input.runId, input.evidenceDir) ?? emptyArtifact(input.runId, input.now);
|
|
114
|
+
const toState = ACTION_TARGET[input.action];
|
|
115
|
+
const isCandidate = input.scope === "candidate" && input.candidateId !== undefined;
|
|
116
|
+
const fromState = isCandidate
|
|
117
|
+
? candidateReviewStateOf(current, input.candidateId)
|
|
118
|
+
: current.runState;
|
|
119
|
+
if (!isLegalTransition(fromState, input.action)) {
|
|
120
|
+
throw new QualityIntelligenceReviewTransitionRejected(fromState, input.action, toState);
|
|
121
|
+
}
|
|
122
|
+
const candidateStates = isCandidate
|
|
123
|
+
? Object.assign(toNullProtoStates(current.candidateStates), { [input.candidateId]: toState })
|
|
124
|
+
: current.candidateStates;
|
|
125
|
+
const audit = {
|
|
126
|
+
at: input.now,
|
|
127
|
+
action: input.action,
|
|
128
|
+
scope: input.scope,
|
|
129
|
+
...(isCandidate ? { candidateId: input.candidateId } : {}),
|
|
130
|
+
reviewerLabel: redactLabel(input.reviewerLabel, input.redact),
|
|
131
|
+
fromState,
|
|
132
|
+
toState,
|
|
133
|
+
};
|
|
134
|
+
const next = {
|
|
135
|
+
qiReviewSchemaVersion: QI_REVIEW_SCHEMA_VERSION,
|
|
136
|
+
runId: input.runId,
|
|
137
|
+
runState: isCandidate ? current.runState : toState,
|
|
138
|
+
candidateStates,
|
|
139
|
+
auditLog: [...current.auditLog, audit],
|
|
140
|
+
lastUpdatedAt: input.now,
|
|
141
|
+
};
|
|
142
|
+
storeFor(input.evidenceDir).record(input.runId, next);
|
|
143
|
+
return next;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Append an append-only `edit` audit entry for an inline candidate edit. Review state is NOT
|
|
147
|
+
* transitioned — `fromState`/`toState` are the candidate's existing review state. The reviewer label
|
|
148
|
+
* is redacted before persist (FIX M1). Persists and returns the updated review artifact (created
|
|
149
|
+
* empty on first use).
|
|
150
|
+
*/
|
|
151
|
+
export const appendEditAudit = (input) => {
|
|
152
|
+
const current = loadRunReviewState(input.runId, input.evidenceDir) ?? emptyArtifact(input.runId, input.now);
|
|
153
|
+
const state = candidateReviewStateOf(current, input.candidateId);
|
|
154
|
+
const audit = {
|
|
155
|
+
at: input.now,
|
|
156
|
+
action: "edit",
|
|
157
|
+
scope: "candidate",
|
|
158
|
+
candidateId: input.candidateId,
|
|
159
|
+
reviewerLabel: redactLabel(input.reviewerLabel, input.redact),
|
|
160
|
+
fromState: state,
|
|
161
|
+
toState: state,
|
|
162
|
+
};
|
|
163
|
+
const next = {
|
|
164
|
+
...current,
|
|
165
|
+
auditLog: [...current.auditLog, audit],
|
|
166
|
+
lastUpdatedAt: input.now,
|
|
167
|
+
};
|
|
168
|
+
storeFor(input.evidenceDir).record(input.runId, next);
|
|
169
|
+
return next;
|
|
170
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type QualityIntelligence as QI } from "@oscharko-dev/keiko-contracts";
|
|
2
|
+
import { type QualityIntelligenceRunSummary } from "@oscharko-dev/keiko-workflows";
|
|
3
|
+
import type { QualityIntelligenceStartRunRequest } from "@oscharko-dev/keiko-contracts";
|
|
4
|
+
import { type UiHandlerDeps } from "../deps.js";
|
|
5
|
+
import { QiIngestionError } from "./runIngestion.js";
|
|
6
|
+
import type { QiSkippedSource } from "./runIngestion.js";
|
|
7
|
+
import { QiGenerationError } from "./generationPort.js";
|
|
8
|
+
export interface QiRunAccepted {
|
|
9
|
+
readonly runId: string;
|
|
10
|
+
readonly requestedAt: string;
|
|
11
|
+
readonly sourceCount: number;
|
|
12
|
+
readonly atomCount: number;
|
|
13
|
+
readonly modelId?: string | undefined;
|
|
14
|
+
/** Sources dropped because the request exceeded the 16-source cap (Epic #729). */
|
|
15
|
+
readonly droppedSourceCount: number;
|
|
16
|
+
/** Connected sources skipped because they ingested to nothing usable (Epic #729 N+1 resilience). */
|
|
17
|
+
readonly skippedSources: readonly QiSkippedSource[];
|
|
18
|
+
}
|
|
19
|
+
export interface ExecuteQiRunInput {
|
|
20
|
+
readonly request: QualityIntelligenceStartRunRequest;
|
|
21
|
+
readonly runId: string;
|
|
22
|
+
readonly deps: UiHandlerDeps;
|
|
23
|
+
readonly registeredAt: string;
|
|
24
|
+
readonly signal: AbortSignal;
|
|
25
|
+
readonly onEvent: (event: QI.QualityIntelligenceRunEvent) => void;
|
|
26
|
+
readonly onAccepted: (accepted: QiRunAccepted) => void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Execute a QI run end to end. Throws `QiIngestionError` / `QiGenerationError` (safe, coded) when
|
|
30
|
+
* the request cannot start; otherwise returns the run summary after the workflow reaches a terminal
|
|
31
|
+
* state. `onAccepted` fires once, after ingestion + model/judge resolution succeed and before
|
|
32
|
+
* generation.
|
|
33
|
+
*/
|
|
34
|
+
export declare function executeQiRun(input: ExecuteQiRunInput): Promise<QualityIntelligenceRunSummary>;
|
|
35
|
+
export { QiIngestionError, QiGenerationError };
|
|
36
|
+
//# sourceMappingURL=runExecution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runExecution.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/runExecution.ts"],"names":[],"mappings":"AASA,OAAO,EAAuB,KAAK,mBAAmB,IAAI,EAAE,EAAE,MAAM,+BAA+B,CAAC;AAUpG,OAAO,EAEL,KAAK,6BAA6B,EAEnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAA4B,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EAA0B,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAqBhF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,oGAAoG;IACpG,QAAQ,CAAC,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,kCAAkC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,2BAA2B,KAAK,IAAI,CAAC;IAClE,QAAQ,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAC;CACxD;AAmED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,6BAA6B,CAAC,CAaxC;AAwGD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC"}
|