@oscharko-dev/keiko 0.2.0-beta.4 → 0.2.0-beta.5
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/ui/csp-hashes.json +18 -18
- package/dist/ui/static/404.html +1 -1
- package/dist/ui/static/__next.__PAGE__.txt +2 -2
- package/dist/ui/static/__next._full.txt +3 -3
- package/dist/ui/static/__next._head.txt +1 -1
- package/dist/ui/static/__next._index.txt +2 -2
- package/dist/ui/static/__next._tree.txt +2 -2
- package/dist/ui/static/_next/static/chunks/1m-kvwm6_90_3.css +1 -0
- package/dist/ui/static/_next/static/chunks/2ngm8iwdb1cbv.js +106 -0
- package/dist/ui/static/_not-found/__next._full.txt +2 -2
- package/dist/ui/static/_not-found/__next._head.txt +1 -1
- package/dist/ui/static/_not-found/__next._index.txt +2 -2
- package/dist/ui/static/_not-found/__next._not-found.__PAGE__.txt +1 -1
- package/dist/ui/static/_not-found/__next._not-found.txt +1 -1
- package/dist/ui/static/_not-found/__next._tree.txt +2 -2
- package/dist/ui/static/_not-found.html +1 -1
- package/dist/ui/static/_not-found.txt +2 -2
- package/dist/ui/static/index.html +1 -1
- package/dist/ui/static/index.txt +3 -3
- package/dist/ui/static/launch/__next._full.txt +3 -3
- package/dist/ui/static/launch/__next._head.txt +1 -1
- package/dist/ui/static/launch/__next._index.txt +2 -2
- package/dist/ui/static/launch/__next._tree.txt +2 -2
- package/dist/ui/static/launch/__next.launch.__PAGE__.txt +2 -2
- package/dist/ui/static/launch/__next.launch.txt +1 -1
- package/dist/ui/static/launch.html +1 -1
- package/dist/ui/static/launch.txt +3 -3
- package/dist/ui/static/local-knowledge/__next._full.txt +3 -3
- package/dist/ui/static/local-knowledge/__next._head.txt +1 -1
- package/dist/ui/static/local-knowledge/__next._index.txt +2 -2
- package/dist/ui/static/local-knowledge/__next._tree.txt +2 -2
- package/dist/ui/static/local-knowledge/__next.local-knowledge.__PAGE__.txt +2 -2
- package/dist/ui/static/local-knowledge/__next.local-knowledge.txt +1 -1
- package/dist/ui/static/local-knowledge/capsule/__next._full.txt +2 -2
- package/dist/ui/static/local-knowledge/capsule/__next._head.txt +1 -1
- package/dist/ui/static/local-knowledge/capsule/__next._index.txt +2 -2
- package/dist/ui/static/local-knowledge/capsule/__next._tree.txt +2 -2
- package/dist/ui/static/local-knowledge/capsule/__next.local-knowledge.capsule.__PAGE__.txt +1 -1
- package/dist/ui/static/local-knowledge/capsule/__next.local-knowledge.capsule.txt +1 -1
- package/dist/ui/static/local-knowledge/capsule/__next.local-knowledge.txt +1 -1
- package/dist/ui/static/local-knowledge/capsule.html +1 -1
- package/dist/ui/static/local-knowledge/capsule.txt +2 -2
- package/dist/ui/static/local-knowledge.html +1 -1
- package/dist/ui/static/local-knowledge.txt +3 -3
- package/dist/ui/static/memoriaviva/__next._full.txt +2 -2
- package/dist/ui/static/memoriaviva/__next._head.txt +1 -1
- package/dist/ui/static/memoriaviva/__next._index.txt +2 -2
- package/dist/ui/static/memoriaviva/__next._tree.txt +2 -2
- package/dist/ui/static/memoriaviva/__next.memoriaviva.__PAGE__.txt +1 -1
- package/dist/ui/static/memoriaviva/__next.memoriaviva.txt +1 -1
- package/dist/ui/static/memoriaviva/consolidation/__next._full.txt +2 -2
- package/dist/ui/static/memoriaviva/consolidation/__next._head.txt +1 -1
- package/dist/ui/static/memoriaviva/consolidation/__next._index.txt +2 -2
- package/dist/ui/static/memoriaviva/consolidation/__next._tree.txt +2 -2
- package/dist/ui/static/memoriaviva/consolidation/__next.memoriaviva.consolidation.__PAGE__.txt +1 -1
- package/dist/ui/static/memoriaviva/consolidation/__next.memoriaviva.consolidation.txt +1 -1
- package/dist/ui/static/memoriaviva/consolidation/__next.memoriaviva.txt +1 -1
- package/dist/ui/static/memoriaviva/consolidation.html +1 -1
- package/dist/ui/static/memoriaviva/consolidation.txt +2 -2
- package/dist/ui/static/memoriaviva/detail/__next._full.txt +2 -2
- package/dist/ui/static/memoriaviva/detail/__next._head.txt +1 -1
- package/dist/ui/static/memoriaviva/detail/__next._index.txt +2 -2
- package/dist/ui/static/memoriaviva/detail/__next._tree.txt +2 -2
- package/dist/ui/static/memoriaviva/detail/__next.memoriaviva.detail.__PAGE__.txt +1 -1
- package/dist/ui/static/memoriaviva/detail/__next.memoriaviva.detail.txt +1 -1
- package/dist/ui/static/memoriaviva/detail/__next.memoriaviva.txt +1 -1
- package/dist/ui/static/memoriaviva/detail.html +1 -1
- package/dist/ui/static/memoriaviva/detail.txt +2 -2
- package/dist/ui/static/memoriaviva/review-queue/__next._full.txt +2 -2
- package/dist/ui/static/memoriaviva/review-queue/__next._head.txt +1 -1
- package/dist/ui/static/memoriaviva/review-queue/__next._index.txt +2 -2
- package/dist/ui/static/memoriaviva/review-queue/__next._tree.txt +2 -2
- package/dist/ui/static/memoriaviva/review-queue/__next.memoriaviva.review-queue.__PAGE__.txt +1 -1
- package/dist/ui/static/memoriaviva/review-queue/__next.memoriaviva.review-queue.txt +1 -1
- package/dist/ui/static/memoriaviva/review-queue/__next.memoriaviva.txt +1 -1
- package/dist/ui/static/memoriaviva/review-queue.html +1 -1
- package/dist/ui/static/memoriaviva/review-queue.txt +2 -2
- package/dist/ui/static/memoriaviva.html +1 -1
- package/dist/ui/static/memoriaviva.txt +2 -2
- package/node_modules/@oscharko-dev/keiko-cli/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-cli/dist/run.d.ts +3 -1
- package/node_modules/@oscharko-dev/keiko-cli/dist/run.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-cli/dist/run.js +73 -41
- package/node_modules/@oscharko-dev/keiko-cli/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-contracts/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-contracts/dist/index.d.ts +1 -1
- package/node_modules/@oscharko-dev/keiko-contracts/dist/index.js +1 -1
- package/node_modules/@oscharko-dev/keiko-contracts/dist/qualityIntelligence/bffWire.d.ts +2 -0
- package/node_modules/@oscharko-dev/keiko-contracts/dist/qualityIntelligence/bffWire.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-contracts/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-evaluations/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-evaluations/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/index.d.ts +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/index.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/index.js +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/index.d.ts +3 -3
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/index.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/index.js +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/manifestSchema.d.ts +18 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/manifestSchema.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/store.d.ts +33 -0
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/store.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-evidence/dist/qualityIntelligence/store.js +69 -0
- package/node_modules/@oscharko-dev/keiko-evidence/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-harness/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-harness/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/index.d.ts +0 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/index.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/index.js +0 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/model-gateway-answer-generator.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/model-gateway-answer-generator.js +7 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/types.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/types.js +2 -3
- package/node_modules/@oscharko-dev/keiko-local-knowledge/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-memory-capture/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-memory-consolidation/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-memory-governance/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-memory-retrieval/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-memory-vault/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-memory-vault/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-model-gateway/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-model-gateway/dist/normalize.d.ts +1 -0
- package/node_modules/@oscharko-dev/keiko-model-gateway/dist/normalize.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-model-gateway/dist/normalize.js +22 -1
- package/node_modules/@oscharko-dev/keiko-model-gateway/dist/openai-adapter.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-model-gateway/dist/openai-adapter.js +18 -4
- package/node_modules/@oscharko-dev/keiko-model-gateway/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/alm.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/alm.js +29 -30
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/markdown.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/markdown.js +29 -5
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/qtest.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/qtest.js +29 -29
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/spreadsheetSafeCsv.d.ts +2 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/spreadsheetSafeCsv.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/spreadsheetSafeCsv.js +40 -2
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/xray.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/dist/export/adapters/xray.js +6 -2
- package/node_modules/@oscharko-dev/keiko-quality-intelligence/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-sdk/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-sdk/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-security/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-security/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/assistant-response.d.ts +6 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/assistant-response.d.ts.map +1 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/assistant-response.js +12 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/chat-handlers.d.ts +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/chat-handlers.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/chat-handlers.js +11 -4
- package/node_modules/@oscharko-dev/keiko-server/dist/chat-stream-handlers.js +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-orchestrator.d.ts +0 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-orchestrator.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-orchestrator.js +222 -18
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-qa-hybrid.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-qa-hybrid.js +3 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-qa-multi-source.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-qa-multi-source.js +3 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-qa.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/grounded-qa.js +3 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/local-knowledge-grounded-qa.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/local-knowledge-grounded-qa.js +4 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/connectorErrors.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/connectorErrors.js +11 -8
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/editRoutes.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/editRoutes.js +1 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/exportRoutes.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/exportRoutes.js +89 -30
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/generationPort.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/generationPort.js +12 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/handoffErrors.d.ts +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/handoffErrors.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/handoffErrors.js +1 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/handoffRoutes.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/handoffRoutes.js +41 -9
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/index.d.ts +1 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/index.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/index.js +2 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/judgePort.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/judgePort.js +17 -3
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/retentionRoutes.d.ts +5 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/retentionRoutes.d.ts.map +1 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/retentionRoutes.js +70 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/reviewRoutes.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/reviewRoutes.js +6 -2
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/reviewStore.d.ts +25 -4
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/reviewStore.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/reviewStore.js +72 -9
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/runIngestion.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/runIngestion.js +46 -3
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/runRegistry.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/runRegistry.js +2 -0
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/uiRoutes.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/uiRoutes.js +12 -2
- package/node_modules/@oscharko-dev/keiko-server/dist/routes.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/routes.js +4 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/store-handlers.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-server/dist/store-handlers.js +4 -1
- package/node_modules/@oscharko-dev/keiko-server/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-tools/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-tools/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-verification/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-verification/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-workflows/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-workflows/dist/planner/anchors.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-workflows/dist/planner/anchors.js +68 -0
- package/node_modules/@oscharko-dev/keiko-workflows/package.json +1 -1
- package/node_modules/@oscharko-dev/keiko-workspace/dist/.tsbuildinfo +1 -1
- package/node_modules/@oscharko-dev/keiko-workspace/dist/discovery.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-workspace/dist/discovery.js +34 -2
- package/node_modules/@oscharko-dev/keiko-workspace/dist/realpath.d.ts +1 -0
- package/node_modules/@oscharko-dev/keiko-workspace/dist/realpath.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-workspace/dist/realpath.js +2 -2
- package/node_modules/@oscharko-dev/keiko-workspace/dist/repoSearchMatchers.d.ts.map +1 -1
- package/node_modules/@oscharko-dev/keiko-workspace/dist/repoSearchMatchers.js +68 -0
- package/node_modules/@oscharko-dev/keiko-workspace/package.json +1 -1
- package/package.json +1 -1
- package/dist/ui/static/_next/static/chunks/1t04tfgin0v_g.js +0 -106
- package/dist/ui/static/_next/static/chunks/3wr_35f2vg6sd.css +0 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/scripted-answer-generator.d.ts +0 -6
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/scripted-answer-generator.d.ts.map +0 -1
- package/node_modules/@oscharko-dev/keiko-local-knowledge/dist/conversation/scripted-answer-generator.js +0 -49
- /package/dist/ui/static/_next/static/{Hb6brrvZY2nZtizQlYhVt → hR2gBQqCDKdPdSxBqZhqv}/_buildManifest.js +0 -0
- /package/dist/ui/static/_next/static/{Hb6brrvZY2nZtizQlYhVt → hR2gBQqCDKdPdSxBqZhqv}/_clientMiddlewareManifest.js +0 -0
- /package/dist/ui/static/_next/static/{Hb6brrvZY2nZtizQlYhVt → hR2gBQqCDKdPdSxBqZhqv}/_ssgManifest.js +0 -0
|
@@ -7,10 +7,31 @@
|
|
|
7
7
|
// nothing is approved by default (#282 AC). All reads tolerate a missing artifact.
|
|
8
8
|
import { createNodeContainedJsonArtifactStore, } from "@oscharko-dev/keiko-evidence";
|
|
9
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
|
+
};
|
|
10
21
|
export const QI_REVIEW_SCHEMA_VERSION = 1;
|
|
11
22
|
const REVIEW_SUFFIX = ".review.json";
|
|
12
23
|
const REVIEW_STATES = new Set(QualityIntelligence.QUALITY_INTELLIGENCE_REVIEW_STATES);
|
|
13
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
|
+
};
|
|
14
35
|
const parseArtifact = (value) => {
|
|
15
36
|
if (typeof value !== "object" || value === null)
|
|
16
37
|
return undefined;
|
|
@@ -21,7 +42,10 @@ const parseArtifact = (value) => {
|
|
|
21
42
|
return undefined;
|
|
22
43
|
if (typeof record.candidateStates !== "object" || record.candidateStates === null)
|
|
23
44
|
return undefined;
|
|
24
|
-
|
|
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 };
|
|
25
49
|
};
|
|
26
50
|
const storeFor = (evidenceDir) => createNodeContainedJsonArtifactStore(evidenceDir, REVIEW_SUFFIX, { parse: parseArtifact });
|
|
27
51
|
export const loadRunReviewState = (runId, evidenceDir) => storeFor(evidenceDir).load(runId);
|
|
@@ -38,17 +62,52 @@ const ACTION_TARGET = {
|
|
|
38
62
|
reopen: "open",
|
|
39
63
|
withdraw: "withdrawn",
|
|
40
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
|
+
}
|
|
41
97
|
const emptyArtifact = (runId, now) => ({
|
|
42
98
|
qiReviewSchemaVersion: QI_REVIEW_SCHEMA_VERSION,
|
|
43
99
|
runId,
|
|
44
100
|
runState: "open",
|
|
45
|
-
candidateStates: {},
|
|
101
|
+
candidateStates: toNullProtoStates({}),
|
|
46
102
|
auditLog: [],
|
|
47
103
|
lastUpdatedAt: now,
|
|
48
104
|
});
|
|
49
105
|
/**
|
|
50
|
-
* Apply a review decision and persist the updated artifact.
|
|
51
|
-
*
|
|
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.
|
|
52
111
|
*/
|
|
53
112
|
export const applyReviewDecision = (input) => {
|
|
54
113
|
const current = loadRunReviewState(input.runId, input.evidenceDir) ?? emptyArtifact(input.runId, input.now);
|
|
@@ -57,15 +116,18 @@ export const applyReviewDecision = (input) => {
|
|
|
57
116
|
const fromState = isCandidate
|
|
58
117
|
? candidateReviewStateOf(current, input.candidateId)
|
|
59
118
|
: current.runState;
|
|
119
|
+
if (!isLegalTransition(fromState, input.action)) {
|
|
120
|
+
throw new QualityIntelligenceReviewTransitionRejected(fromState, input.action, toState);
|
|
121
|
+
}
|
|
60
122
|
const candidateStates = isCandidate
|
|
61
|
-
?
|
|
123
|
+
? Object.assign(toNullProtoStates(current.candidateStates), { [input.candidateId]: toState })
|
|
62
124
|
: current.candidateStates;
|
|
63
125
|
const audit = {
|
|
64
126
|
at: input.now,
|
|
65
127
|
action: input.action,
|
|
66
128
|
scope: input.scope,
|
|
67
129
|
...(isCandidate ? { candidateId: input.candidateId } : {}),
|
|
68
|
-
reviewerLabel: input.reviewerLabel,
|
|
130
|
+
reviewerLabel: redactLabel(input.reviewerLabel, input.redact),
|
|
69
131
|
fromState,
|
|
70
132
|
toState,
|
|
71
133
|
};
|
|
@@ -82,8 +144,9 @@ export const applyReviewDecision = (input) => {
|
|
|
82
144
|
};
|
|
83
145
|
/**
|
|
84
146
|
* Append an append-only `edit` audit entry for an inline candidate edit. Review state is NOT
|
|
85
|
-
* transitioned — `fromState`/`toState` are the candidate's existing review state.
|
|
86
|
-
* returns the updated review artifact (created
|
|
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).
|
|
87
150
|
*/
|
|
88
151
|
export const appendEditAudit = (input) => {
|
|
89
152
|
const current = loadRunReviewState(input.runId, input.evidenceDir) ?? emptyArtifact(input.runId, input.now);
|
|
@@ -93,7 +156,7 @@ export const appendEditAudit = (input) => {
|
|
|
93
156
|
action: "edit",
|
|
94
157
|
scope: "candidate",
|
|
95
158
|
candidateId: input.candidateId,
|
|
96
|
-
reviewerLabel: input.reviewerLabel,
|
|
159
|
+
reviewerLabel: redactLabel(input.reviewerLabel, input.redact),
|
|
97
160
|
fromState: state,
|
|
98
161
|
toState: state,
|
|
99
162
|
};
|
package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/runIngestion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runIngestion.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/runIngestion.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runIngestion.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/runIngestion.ts"],"names":[],"mappings":"AAUA,OAAO,EAAuB,KAAK,mBAAmB,IAAI,EAAE,EAAE,MAAM,+BAA+B,CAAC;AAqBpG,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,KAAK,EACV,+BAA+B,EAC/B,kCAAkC,EACnC,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAyC9F,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,SAAgB,IAAI,EAAE,MAAM,CAAC;gBACjB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAK1C;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,iCAAiC,EAAE,CAAC;IACpE,QAAQ,CAAC,aAAa,EAAE,SAAS,+BAA+B,EAAE,CAAC;IACnE,QAAQ,CAAC,cAAc,EAAE;QACvB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;QACxC,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,iCAAiC,CAAC;KAC/D,CAAC;IACF,QAAQ,CAAC,eAAe,EAAE,SAAS,eAAe,EAAE,CAAC;IACrD,yFAAyF;IACzF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;CACrD;AAk1BD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,kCAAkC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,gHAAgH;IAChH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;CAC5D;AAsED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,iBAAiB,CAiDtF"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// `@oscharko-dev/keiko-quality-intelligence`. The server tier owns IO (it is the only layer that
|
|
6
6
|
// may touch the filesystem); the pure domain owns splitting + hashing. Oversize and unsupported
|
|
7
7
|
// inputs fail with user-actionable errors (#278 AC) before any model prompt is built.
|
|
8
|
+
import { realpathSync } from "node:fs";
|
|
8
9
|
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
9
10
|
import { QualityIntelligence } from "@oscharko-dev/keiko-contracts";
|
|
10
11
|
import { redact, sha256Hex } from "@oscharko-dev/keiko-security";
|
|
@@ -66,6 +67,18 @@ const CREDENTIAL_LABEL_SHAPES = [
|
|
|
66
67
|
/\bBearer\s+\S+/giu,
|
|
67
68
|
/-----BEGIN [A-Z ]*PRIVATE KEY-----/gu,
|
|
68
69
|
];
|
|
70
|
+
// Replace every control character (C0 range incl. tab/newline/CR, plus DEL) with a space using a
|
|
71
|
+
// code-point scan — the `no-control-regex` lint rule forbids a control-range regex literal, and a
|
|
72
|
+
// scan is the established in-package idiom (mirrors generationPort.scrubEvidenceText). Keeps a
|
|
73
|
+
// label single-line.
|
|
74
|
+
function collapseControlCharsToSpace(value) {
|
|
75
|
+
let out = "";
|
|
76
|
+
for (const ch of value) {
|
|
77
|
+
const cp = ch.codePointAt(0) ?? 0;
|
|
78
|
+
out += cp <= 0x1f || cp === 0x7f ? " " : ch;
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
69
82
|
const sanitiseLabel = (label) => {
|
|
70
83
|
// Strip any URL authority — ANY scheme (http, file, s3, ftp, …), not just http(s) — plus the
|
|
71
84
|
// well-known credential token shapes, so a browser-supplied label never carries a URL or secret
|
|
@@ -73,6 +86,12 @@ const sanitiseLabel = (label) => {
|
|
|
73
86
|
let cleaned = label.replace(/[a-z][a-z0-9+.-]*:\/\/\S+/giu, " ");
|
|
74
87
|
for (const shape of CREDENTIAL_LABEL_SHAPES)
|
|
75
88
|
cleaned = cleaned.replace(shape, " ");
|
|
89
|
+
// Replace every control character (newline, CR, tab, NUL, DEL, …) with a space so a multi-line or
|
|
90
|
+
// control-laden label can never carry a second line of content into the browser-streamed envelope
|
|
91
|
+
// displayLabel. Without this, the absolute-path basename-collapse below (which splits on "/" only)
|
|
92
|
+
// would keep a trailing "\n<more content>" glued inside the final path segment — defeating the
|
|
93
|
+
// basename defence and emitting a multi-line label (#277/#278 envelope display-surface invariant).
|
|
94
|
+
cleaned = collapseControlCharsToSpace(cleaned);
|
|
76
95
|
cleaned = cleaned.trim();
|
|
77
96
|
// Collapse an absolute POSIX / Windows-drive / UNC path label to its final segment so the
|
|
78
97
|
// display label never leaks the filesystem layout (the basename is the useful display token).
|
|
@@ -86,10 +105,34 @@ const sanitiseLabel = (label) => {
|
|
|
86
105
|
// Reject a source whose absolute path (any segment) names a denied credential location. isDenied
|
|
87
106
|
// inspects EVERY path segment, so a denied ancestor cannot be hidden by rooting a read deeper. Shared
|
|
88
107
|
// by the folder and single-file paths so both honour the same containment guard (Epic #729 security).
|
|
108
|
+
// Also rejects the symlink variant (assertRealPathNotDenied) so a benign-named link cannot resolve
|
|
109
|
+
// into a protected location.
|
|
89
110
|
function assertNotDenied(absPath, label, noun) {
|
|
90
111
|
if (isDenied(absPath)) {
|
|
91
112
|
throw new QiIngestionError("QI_SOURCE_DENIED", `${noun} "${label}" is in a protected location.`);
|
|
92
113
|
}
|
|
114
|
+
assertRealPathNotDenied(absPath, label, noun);
|
|
115
|
+
}
|
|
116
|
+
// Defense-in-depth against a symlinked workspace root. The keiko-workspace deny gate (readWorkspaceFile)
|
|
117
|
+
// inspects only the path RELATIVE to the realpath'd root, so a denied segment AT or ABOVE the connected
|
|
118
|
+
// root is invisible to it: a benign-named "~/docs" symlink whose real target is "~/.aws" lets a
|
|
119
|
+
// supported file inside it read through to the model, even though the lexical assertNotDenied above sees
|
|
120
|
+
// only "docs". Re-running the deny gate over the REAL (symlink-resolved) absolute path rejects it. The
|
|
121
|
+
// lexical check above already covers the no-symlink case, so this only ADDS denials when realpath
|
|
122
|
+
// diverges into a protected location; a non-existent target surfaces later as NOT_FOUND, so a failed
|
|
123
|
+
// realpath is a deliberate no-op here. (#713 single-file security review: "deny-list still applies";
|
|
124
|
+
// #729 folder-root parity — both ingest paths share this boundary blind spot.)
|
|
125
|
+
function assertRealPathNotDenied(absPath, label, noun) {
|
|
126
|
+
let realPath;
|
|
127
|
+
try {
|
|
128
|
+
realPath = realpathSync(absPath);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (realPath !== absPath && isDenied(realPath)) {
|
|
134
|
+
throw new QiIngestionError("QI_SOURCE_DENIED", `${noun} "${label}" is in a protected location.`);
|
|
135
|
+
}
|
|
93
136
|
}
|
|
94
137
|
const envelopeIdFor = (index, label, content) => {
|
|
95
138
|
const digest = sha256Hex(`qi-src-v1|${String(index)}|${label}|${content}`).slice(0, 24);
|
|
@@ -194,8 +237,8 @@ function atomsForWorkspaceEntry(entry, envelopeId) {
|
|
|
194
237
|
// entry becomes one content-bearing atom under a single repository-context envelope.
|
|
195
238
|
function ingestWorkspace(source, index, registeredAt, byteBudget) {
|
|
196
239
|
const label = sanitiseLabel(source.label);
|
|
197
|
-
// Reject a folder whose ROOT names a denied credential location
|
|
198
|
-
// ~/.
|
|
240
|
+
// Reject a folder whose ROOT names a denied credential location (lexically or via a symlinked root):
|
|
241
|
+
// connecting e.g. ~/.aws AS A FOLDER would otherwise ingest credential files whose RELATIVE paths
|
|
199
242
|
// ("credentials", "config.json") never trip the per-file deny check (#729 security).
|
|
200
243
|
assertNotDenied(resolve(source.path), label, "Folder");
|
|
201
244
|
let workspace;
|
|
@@ -332,7 +375,7 @@ function ingestFile(source, index, registeredAt, byteBudget) {
|
|
|
332
375
|
throw new QiIngestionError("QI_SOURCE_UNSUPPORTED", `File "${label}" is not a supported single-file document.`);
|
|
333
376
|
}
|
|
334
377
|
// Reject any path whose segments name a denied credential directory or file (.ssh, .aws, .env,
|
|
335
|
-
// *.pem, id_rsa, …) regardless of
|
|
378
|
+
// *.pem, id_rsa, …) — lexically or after symlink resolution — regardless of the workspace root below.
|
|
336
379
|
assertNotDenied(absFile, label, "File");
|
|
337
380
|
const content = readSingleFileContent(absFile, label);
|
|
338
381
|
// keiko-workspace decodes as UTF-8; a NUL byte is the canonical binary marker. A binary file that
|
package/node_modules/@oscharko-dev/keiko-server/dist/qualityIntelligence/runRegistry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runRegistry.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/runRegistry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjF,UAAU,WAAW;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACnE;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IAEvD,oGAAoG;IACpG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe;IAY7D,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI;IAMzE,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG,IAAI;IAM5E,oFAAoF;IACpF,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAO9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC,oFAAoF;IACpF,mBAAmB,IAAI,SAAS,+BAA+B,EAAE;
|
|
1
|
+
{"version":3,"file":"runRegistry.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/runRegistry.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjF,UAAU,WAAW;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACnE;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IAEvD,oGAAoG;IACpG,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe;IAY7D,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI;IAMzE,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG,IAAI;IAM5E,oFAAoF;IACpF,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAO9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC,oFAAoF;IACpF,mBAAmB,IAAI,SAAS,+BAA+B,EAAE;IAYjE,wCAAwC;IACxC,KAAK,IAAI,IAAI;CAId;AAGD,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -51,6 +51,8 @@ export class QiRunRegistry {
|
|
|
51
51
|
requestedAt: run.requestedAt,
|
|
52
52
|
completedAt: null,
|
|
53
53
|
totals: { ...run.totals },
|
|
54
|
+
// An in-flight run is not yet persisted and cannot have been reviewed (Issue #282 FIX A11y-2).
|
|
55
|
+
reviewState: "open",
|
|
54
56
|
}));
|
|
55
57
|
}
|
|
56
58
|
/** Test seam: clear all active runs. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uiRoutes.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/uiRoutes.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,qBAAqB,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"uiRoutes.d.ts","sourceRoot":"","sources":["../../src/qualityIntelligence/uiRoutes.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAmNzC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAkDpF;AAMD,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAmClF"}
|
|
@@ -29,7 +29,7 @@ function resolveEvidenceDir(deps) {
|
|
|
29
29
|
// Projection helpers — build browser-safe wire shapes from manifest data.
|
|
30
30
|
// NEVER include raw prompt, raw source content, credentials, or unsafe markdown.
|
|
31
31
|
// ---------------------------------------------------------------------------
|
|
32
|
-
function projectRunSummary(manifest) {
|
|
32
|
+
function projectRunSummary(manifest, reviewState) {
|
|
33
33
|
if (manifest === undefined)
|
|
34
34
|
return null;
|
|
35
35
|
return {
|
|
@@ -42,8 +42,18 @@ function projectRunSummary(manifest) {
|
|
|
42
42
|
findings: manifest.totals.findings,
|
|
43
43
|
exports: manifest.totals.exports,
|
|
44
44
|
},
|
|
45
|
+
reviewState,
|
|
45
46
|
};
|
|
46
47
|
}
|
|
48
|
+
// FIX A11y-2 (Issue #282) — resolve the run's overall review state for the list item so the hub list
|
|
49
|
+
// can show a per-run lifecycle badge (AC1). Loads the small `.review.json` companion per listed run;
|
|
50
|
+
// this is acceptable because the list path already loads a per-run manifest and the list is bounded
|
|
51
|
+
// by the route limit. Defaults to "open" when no companion exists or no evidence dir is configured.
|
|
52
|
+
function listReviewStateFor(runId, evidenceDir) {
|
|
53
|
+
if (evidenceDir === undefined)
|
|
54
|
+
return "open";
|
|
55
|
+
return runReviewStateOf(loadRunReviewState(runId, evidenceDir));
|
|
56
|
+
}
|
|
47
57
|
/**
|
|
48
58
|
* Build a candidateId → weak-test flag map from the persisted test-quality findings (Epic #736).
|
|
49
59
|
* Only findings of kind "test-quality" that carry a candidateId contribute; the first finding wins
|
|
@@ -202,7 +212,7 @@ export function handleListQiRuns(ctx, deps) {
|
|
|
202
212
|
break;
|
|
203
213
|
try {
|
|
204
214
|
const manifest = loadQualityIntelligenceRun(id, { evidenceDir });
|
|
205
|
-
const summary = projectRunSummary(manifest);
|
|
215
|
+
const summary = projectRunSummary(manifest, listReviewStateFor(id, evidenceDir));
|
|
206
216
|
if (summary !== null)
|
|
207
217
|
runs.push(summary);
|
|
208
218
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAqI/C,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AAID,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,SAAS,eAAsB,CAAC;AAC7C,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,OAAO,SAAS,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAElD,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,KAChB,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;CAChC;AAUD,eAAO,MAAM,UAAU,EAAE,SAAS,eAAe,EA2RhD,CAAC;AA6BF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD;AAKD,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,UAAU,GAAG,oBAAoB,GAAG,SAAS,CA2B/C;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,CAEjE;AAED,wBAAgB,YAAY,IAAI,QAAQ,CAEvC;AAED,wBAAgB,oBAAoB,IAAI,QAAQ,CAE/C"}
|
|
@@ -22,7 +22,7 @@ import { handleFilesContent, handleFilesDirectories, handleFilesPreview, handleF
|
|
|
22
22
|
import { handleBrowserApplyScreenshot, handleBrowserContent, handleBrowserEvents, handleBrowserNavigate, handleBrowserScreenshot, handleBrowserStatus, handleCreateBrowserSession, handleDeleteBrowserSession, } from "./browser.js";
|
|
23
23
|
import { handleCancelLocalKnowledgeCapsuleIndexing, handleConnectLocalKnowledgeCapsule, handleCreateLocalKnowledgeCapsule, handleCreateLocalKnowledgeCapsuleSet, handleDeleteLocalKnowledgeCapsule, handleDisconnectLocalKnowledgeCapsule, handleGetLocalKnowledgeCapsule, handleListLocalKnowledgeCapsules, handleListLocalKnowledgeCapsuleSets, handleReindexLocalKnowledgeCapsule, handleStartLocalKnowledgeCapsuleIndexing, handleUpdateLocalKnowledgeCapsule, } from "./local-knowledge-handlers.js";
|
|
24
24
|
import { handleRelationshipCreate, handleRelationshipDelete, handleRelationshipDependencies, handleRelationshipEvents, handleRelationshipExplain, handleRelationshipGet, handleRelationshipHealth, handleRelationshipImpact, handleRelationshipList, handleRelationshipPatch, handleRelationshipValidate, } from "./relationship-handlers.js";
|
|
25
|
-
import { handleQiCapabilities, handleQiDryRunFigma, handleQiDryRunJira, handleQiSourceSelect, handleListQiRuns, handleGetQiRun, QI_HANDOFF_ROUTE_GROUP, QI_RUN_EXECUTION_ROUTE_GROUP, QI_REVIEW_ROUTE_GROUP, QI_EXPORT_ROUTE_GROUP, QI_EDIT_ROUTE_GROUP, QI_TRACEABILITY_ROUTE_GROUP, QI_RECHECK_ROUTE_GROUP, } from "./qualityIntelligence/index.js";
|
|
25
|
+
import { handleQiCapabilities, handleQiDryRunFigma, handleQiDryRunJira, handleQiSourceSelect, handleListQiRuns, handleGetQiRun, QI_HANDOFF_ROUTE_GROUP, QI_RUN_EXECUTION_ROUTE_GROUP, QI_REVIEW_ROUTE_GROUP, QI_EXPORT_ROUTE_GROUP, QI_EDIT_ROUTE_GROUP, QI_RETENTION_ROUTE_GROUP, QI_TRACEABILITY_ROUTE_GROUP, QI_RECHECK_ROUTE_GROUP, } from "./qualityIntelligence/index.js";
|
|
26
26
|
import { handleFigmaTriggerSnapshot, handleFigmaLoadSnapshot, handleFigmaRevokeToken, } from "./qualityIntelligence/figmaSnapshotRoutes.js";
|
|
27
27
|
import { handleFigmaGenerateCode } from "./qualityIntelligence/figmaCodegenRoutes.js";
|
|
28
28
|
export const STREAMING = Symbol("streaming");
|
|
@@ -274,6 +274,9 @@ export const API_ROUTES = [
|
|
|
274
274
|
// Issue #726 (Epic #712) — inline candidate editing. Literal-suffix POST /runs/:id/edit
|
|
275
275
|
// disambiguates against /runs/:id/cancel just like /review and /export above.
|
|
276
276
|
...QI_EDIT_ROUTE_GROUP,
|
|
277
|
+
// Issue #282 follow-up (Epic #270) — run-deletion control. DELETE /runs/:id is method-distinct
|
|
278
|
+
// from GET /runs/:id and sweeps every server-owned companion (ADR-0023 D8).
|
|
279
|
+
...QI_RETENTION_ROUTE_GROUP,
|
|
277
280
|
// Issue #740 (Epic #734) — requirement↔test traceability matrix export.
|
|
278
281
|
...QI_TRACEABILITY_ROUTE_GROUP,
|
|
279
282
|
// Issue #743 (Epic #735) — drift re-check + targeted regeneration. Literal-suffix POST routes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-handlers.d.ts","sourceRoot":"","sources":["../src/store-handlers.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"store-handlers.d.ts","sourceRoot":"","sources":["../src/store-handlers.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAwH/C,iBAAS,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAEpD;AAmND,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAMvF;AAMD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAatB;AAeD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAQtB;AAMD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAcvF;AAgBD,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAYnF;AAMD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAetB;AA0bD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAuBtB;AAMD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAQpF;AAMD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,WAAW,CAkBtF;AAMD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAwBtB;AA6CD,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAWtB;AAuBD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,WAAW,CAAC,CAgBtB;AAGD,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -10,6 +10,7 @@ import { UiStoreError, assertUiDbOutsideProject, isProjectAvailable, validatePro
|
|
|
10
10
|
import { pathIsDenied } from "./files-deny.js";
|
|
11
11
|
import { clearGroundedContextIndexesForConversation, clearGroundedContextIndexesForWorkspace, } from "./grounded-context-index.js";
|
|
12
12
|
import { clearGroundedTurnsForConversation, clearGroundedTurnsForWorkspace, } from "./grounded-turn-registry.js";
|
|
13
|
+
import { isLegacyEmptyAssistantPlaceholder } from "./assistant-response.js";
|
|
13
14
|
// Issue #184 — workspace-relative path gate. isValidScopePath is the canonical validator from
|
|
14
15
|
// @oscharko-dev/keiko-contracts/connected-context (issue #178). Reusing it here keeps the BFF
|
|
15
16
|
// boundary aligned with the rest of the connected-repo surface and avoids regex drift.
|
|
@@ -748,7 +749,9 @@ export function handleListMessages(ctx, deps) {
|
|
|
748
749
|
if (!chatBelongsToProject(deps, projectPath, chatId)) {
|
|
749
750
|
return notFoundResult("Chat not found.");
|
|
750
751
|
}
|
|
751
|
-
const messages = deps.store
|
|
752
|
+
const messages = deps.store
|
|
753
|
+
.listMessages(chatId, limit)
|
|
754
|
+
.filter((message) => !isLegacyEmptyAssistantPlaceholder(message));
|
|
752
755
|
return { status: 200, body: { messages } };
|
|
753
756
|
});
|
|
754
757
|
}
|