open-multi-agent-kit 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -1
- package/README.md +2 -2
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +1 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/coordination/awareness.d.ts +32 -0
- package/dist/coordination/awareness.d.ts.map +1 -0
- package/dist/coordination/awareness.js +55 -0
- package/dist/coordination/awareness.js.map +1 -0
- package/dist/coordination/broker.d.ts +79 -0
- package/dist/coordination/broker.d.ts.map +1 -0
- package/dist/coordination/broker.js +195 -0
- package/dist/coordination/broker.js.map +1 -0
- package/dist/coordination/index.d.ts +16 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +16 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/integration.d.ts +59 -0
- package/dist/coordination/integration.d.ts.map +1 -0
- package/dist/coordination/integration.js +126 -0
- package/dist/coordination/integration.js.map +1 -0
- package/dist/coordination/operation.d.ts +106 -0
- package/dist/coordination/operation.d.ts.map +1 -0
- package/dist/coordination/operation.js +179 -0
- package/dist/coordination/operation.js.map +1 -0
- package/dist/coordination/resource.d.ts +33 -0
- package/dist/coordination/resource.d.ts.map +1 -0
- package/dist/coordination/resource.js +89 -0
- package/dist/coordination/resource.js.map +1 -0
- package/dist/coordination/session.d.ts +74 -0
- package/dist/coordination/session.d.ts.map +1 -0
- package/dist/coordination/session.js +143 -0
- package/dist/coordination/session.js.map +1 -0
- package/dist/coordination/types.d.ts +68 -0
- package/dist/coordination/types.d.ts.map +1 -0
- package/dist/coordination/types.js +26 -0
- package/dist/coordination/types.js.map +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +28 -7
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/control-state.d.ts +41 -0
- package/dist/core/compaction/control-state.d.ts.map +1 -0
- package/dist/core/compaction/control-state.js +85 -0
- package/dist/core/compaction/control-state.js.map +1 -0
- package/dist/core/compaction/fallback.d.ts +60 -0
- package/dist/core/compaction/fallback.d.ts.map +1 -0
- package/dist/core/compaction/fallback.js +117 -0
- package/dist/core/compaction/fallback.js.map +1 -0
- package/dist/core/compaction/index.d.ts +2 -0
- package/dist/core/compaction/index.d.ts.map +1 -1
- package/dist/core/compaction/index.js +2 -0
- package/dist/core/compaction/index.js.map +1 -1
- package/dist/core/context-budget-headroom-candidates.d.ts +16 -1
- package/dist/core/context-budget-headroom-candidates.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-candidates.js +31 -13
- package/dist/core/context-budget-headroom-candidates.js.map +1 -1
- package/dist/core/context-budget-headroom-types.d.ts +7 -1
- package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
- package/dist/core/context-budget-headroom-types.js +0 -1
- package/dist/core/context-budget-headroom-types.js.map +1 -1
- package/dist/core/context-budget-headroom.d.ts +10 -0
- package/dist/core/context-budget-headroom.d.ts.map +1 -1
- package/dist/core/context-budget-headroom.js +11 -2
- package/dist/core/context-budget-headroom.js.map +1 -1
- package/dist/core/context-budget-v2-global-pass.d.ts +21 -0
- package/dist/core/context-budget-v2-global-pass.d.ts.map +1 -0
- package/dist/core/context-budget-v2-global-pass.js +203 -0
- package/dist/core/context-budget-v2-global-pass.js.map +1 -0
- package/dist/core/context-budget-v2-planned-items.d.ts +12 -0
- package/dist/core/context-budget-v2-planned-items.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planned-items.js +21 -2
- package/dist/core/context-budget-v2-planned-items.js.map +1 -1
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +18 -19
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-scoring.d.ts +7 -1
- package/dist/core/context-budget-v2-scoring.d.ts.map +1 -1
- package/dist/core/context-budget-v2-scoring.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +3 -0
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +6 -2
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +6 -1
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js +6 -1
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/provider-default-models.d.ts +1 -0
- package/dist/core/provider-default-models.d.ts.map +1 -1
- package/dist/core/provider-default-models.js +1 -0
- package/dist/core/provider-default-models.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +1 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/reasoning-router-resolver.d.ts +7 -0
- package/dist/core/reasoning-router-resolver.d.ts.map +1 -1
- package/dist/core/reasoning-router-resolver.js +21 -3
- package/dist/core/reasoning-router-resolver.js.map +1 -1
- package/dist/core/reasoning-router-v4.d.ts +8 -5
- package/dist/core/reasoning-router-v4.d.ts.map +1 -1
- package/dist/core/reasoning-router-v4.js +8 -5
- package/dist/core/reasoning-router-v4.js.map +1 -1
- package/dist/core/session-compaction-service.d.ts +15 -0
- package/dist/core/session-compaction-service.d.ts.map +1 -1
- package/dist/core/session-compaction-service.js +17 -4
- package/dist/core/session-compaction-service.js.map +1 -1
- package/dist/core/todo-runtime-state.d.ts +12 -0
- package/dist/core/todo-runtime-state.d.ts.map +1 -1
- package/dist/core/todo-runtime-state.js +23 -0
- package/dist/core/todo-runtime-state.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/metacognition/calibration-selective.d.ts +78 -0
- package/dist/metacognition/calibration-selective.d.ts.map +1 -0
- package/dist/metacognition/calibration-selective.js +161 -0
- package/dist/metacognition/calibration-selective.js.map +1 -0
- package/dist/metacognition/calibration.d.ts +62 -0
- package/dist/metacognition/calibration.d.ts.map +1 -0
- package/dist/metacognition/calibration.js +122 -0
- package/dist/metacognition/calibration.js.map +1 -0
- package/dist/metacognition/checkpoint.d.ts +60 -0
- package/dist/metacognition/checkpoint.d.ts.map +1 -0
- package/dist/metacognition/checkpoint.js +57 -0
- package/dist/metacognition/checkpoint.js.map +1 -0
- package/dist/metacognition/context7.d.ts +48 -0
- package/dist/metacognition/context7.d.ts.map +1 -0
- package/dist/metacognition/context7.js +154 -0
- package/dist/metacognition/context7.js.map +1 -0
- package/dist/metacognition/decision.d.ts +44 -0
- package/dist/metacognition/decision.d.ts.map +1 -0
- package/dist/metacognition/decision.js +111 -0
- package/dist/metacognition/decision.js.map +1 -0
- package/dist/metacognition/evaluation.d.ts +73 -0
- package/dist/metacognition/evaluation.d.ts.map +1 -0
- package/dist/metacognition/evaluation.js +97 -0
- package/dist/metacognition/evaluation.js.map +1 -0
- package/dist/metacognition/index.d.ts +31 -0
- package/dist/metacognition/index.d.ts.map +1 -0
- package/dist/metacognition/index.js +31 -0
- package/dist/metacognition/index.js.map +1 -0
- package/dist/metacognition/knowledge-action.d.ts +43 -0
- package/dist/metacognition/knowledge-action.d.ts.map +1 -0
- package/dist/metacognition/knowledge-action.js +60 -0
- package/dist/metacognition/knowledge-action.js.map +1 -0
- package/dist/metacognition/knowledge.d.ts +84 -0
- package/dist/metacognition/knowledge.d.ts.map +1 -0
- package/dist/metacognition/knowledge.js +165 -0
- package/dist/metacognition/knowledge.js.map +1 -0
- package/dist/metacognition/obligations.d.ts +82 -0
- package/dist/metacognition/obligations.d.ts.map +1 -0
- package/dist/metacognition/obligations.js +139 -0
- package/dist/metacognition/obligations.js.map +1 -0
- package/dist/metacognition/observation-validity.d.ts +83 -0
- package/dist/metacognition/observation-validity.d.ts.map +1 -0
- package/dist/metacognition/observation-validity.js +118 -0
- package/dist/metacognition/observation-validity.js.map +1 -0
- package/dist/metacognition/observe.d.ts +45 -0
- package/dist/metacognition/observe.d.ts.map +1 -0
- package/dist/metacognition/observe.js +59 -0
- package/dist/metacognition/observe.js.map +1 -0
- package/dist/metacognition/policy.d.ts +53 -0
- package/dist/metacognition/policy.d.ts.map +1 -0
- package/dist/metacognition/policy.js +155 -0
- package/dist/metacognition/policy.js.map +1 -0
- package/dist/metacognition/predictions.d.ts +78 -0
- package/dist/metacognition/predictions.d.ts.map +1 -0
- package/dist/metacognition/predictions.js +181 -0
- package/dist/metacognition/predictions.js.map +1 -0
- package/dist/metacognition/retrieval.d.ts +53 -0
- package/dist/metacognition/retrieval.d.ts.map +1 -0
- package/dist/metacognition/retrieval.js +170 -0
- package/dist/metacognition/retrieval.js.map +1 -0
- package/dist/metacognition/risk.d.ts +48 -0
- package/dist/metacognition/risk.d.ts.map +1 -0
- package/dist/metacognition/risk.js +165 -0
- package/dist/metacognition/risk.js.map +1 -0
- package/dist/metacognition/route-economics.d.ts +95 -0
- package/dist/metacognition/route-economics.d.ts.map +1 -0
- package/dist/metacognition/route-economics.js +110 -0
- package/dist/metacognition/route-economics.js.map +1 -0
- package/dist/metacognition/runtime-bridge.d.ts +54 -0
- package/dist/metacognition/runtime-bridge.d.ts.map +1 -0
- package/dist/metacognition/runtime-bridge.js +140 -0
- package/dist/metacognition/runtime-bridge.js.map +1 -0
- package/dist/metacognition/skills.d.ts +42 -0
- package/dist/metacognition/skills.d.ts.map +1 -0
- package/dist/metacognition/skills.js +220 -0
- package/dist/metacognition/skills.js.map +1 -0
- package/dist/metacognition/state.d.ts +110 -0
- package/dist/metacognition/state.d.ts.map +1 -0
- package/dist/metacognition/state.js +52 -0
- package/dist/metacognition/state.js.map +1 -0
- package/dist/metacognition/validation.d.ts +19 -0
- package/dist/metacognition/validation.d.ts.map +1 -0
- package/dist/metacognition/validation.js +58 -0
- package/dist/metacognition/validation.js.map +1 -0
- package/dist/metacognition/verification.d.ts +93 -0
- package/dist/metacognition/verification.d.ts.map +1 -0
- package/dist/metacognition/verification.js +132 -0
- package/dist/metacognition/verification.js.map +1 -0
- package/dist/metacognition/verifier.d.ts +49 -0
- package/dist/metacognition/verifier.d.ts.map +1 -0
- package/dist/metacognition/verifier.js +88 -0
- package/dist/metacognition/verifier.js.map +1 -0
- package/dist/observation/identity.d.ts +14 -0
- package/dist/observation/identity.d.ts.map +1 -0
- package/dist/observation/identity.js +29 -0
- package/dist/observation/identity.js.map +1 -0
- package/dist/observation/index.d.ts +13 -0
- package/dist/observation/index.d.ts.map +1 -0
- package/dist/observation/index.js +13 -0
- package/dist/observation/index.js.map +1 -0
- package/dist/observation/observe-mode.d.ts +46 -0
- package/dist/observation/observe-mode.d.ts.map +1 -0
- package/dist/observation/observe-mode.js +83 -0
- package/dist/observation/observe-mode.js.map +1 -0
- package/dist/observation/store.d.ts +53 -0
- package/dist/observation/store.d.ts.map +1 -0
- package/dist/observation/store.js +126 -0
- package/dist/observation/store.js.map +1 -0
- package/dist/observation/types.d.ts +72 -0
- package/dist/observation/types.d.ts.map +1 -0
- package/dist/observation/types.js +9 -0
- package/dist/observation/types.js.map +1 -0
- package/dist/observation/view.d.ts +39 -0
- package/dist/observation/view.d.ts.map +1 -0
- package/dist/observation/view.js +173 -0
- package/dist/observation/view.js.map +1 -0
- package/docs/metacognition.md +51 -0
- package/docs/model-catalog-refresh.md +59 -0
- package/docs/providers.md +53 -0
- package/docs/runtime-algorithms.md +107 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +6 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/metacognition/state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Metacognitive state tuple and checkpoint evaluation.\n * Spec §3: X_t = (G, F, O, E, Z, H, M, V, B, P).\n *\n * The tuple is host-owned structured state; the model receives only the\n * hypotheses, evidence, and questions it needs right now. Recommended\n * computation unit is a decision checkpoint — before a new external symbol,\n * after an important change, after a check failure, after verification, after\n * a source conflict, or when strategy repetition is detected.\n */\nimport type { CalibrationStore } from \"./calibration.ts\";\nimport type { KnowledgeReport } from \"./knowledge.ts\";\nimport type { Obligation } from \"./obligations.ts\";\nimport type { Prediction } from \"./predictions.ts\";\nimport { canonical, ensure, integer, member, text } from \"./validation.ts\";\nimport type { VerifierEvaluation } from \"./verifier.ts\";\n\n/** G_t: current goal, stage, target artifact. */\nexport interface GoalState {\n\treadonly taskId: string;\n\treadonly stageId: string;\n\treadonly targetArtifact: string;\n\treadonly goalScope: string;\n}\n/** F_t: observed facts about repository, environment, pinned versions, change scope. */\nexport interface FactState {\n\treadonly candidateHash: string;\n\treadonly environmentHash: string;\n\treadonly changeScope: readonly string[];\n\treadonly analyzerCoverage: \"covered\" | \"partial\" | \"unsupported\" | \"unknown\";\n}\n/** E_t: evidence candidates, adopted evidence, checks bound to the current artifact. */\nexport interface EvidenceState {\n\treadonly report: KnowledgeReport | null;\n\treadonly adoptedSourceIds: readonly string[];\n}\n/** H_t: competing cause/design hypotheses and unresolved classification. */\nexport interface HypothesisState {\n\treadonly open: readonly string[];\n\treadonly discriminatorCandidates: readonly string[];\n\treadonly modelMismatch: boolean;\n}\n/** V_t: verifier detection coverage, known blind spots, runner health. */\nexport interface VerifierState {\n\treadonly evaluations: readonly VerifierEvaluation[];\n\treadonly runnerHealth: \"healthy\" | \"degraded\" | \"unverified\";\n}\n/** B_t: remaining time, requests, tokens, concurrency budget. */\nexport interface BudgetState {\n\treadonly remainingMs: number;\n\treadonly remainingRequests: number;\n\treadonly remainingTokens: number;\n\treadonly remainingConcurrent: number;\n}\n/** P_t: host-owned authorization, verification, interruption policy. */\nexport interface PolicyState {\n\treadonly policyVersion: string;\n\treadonly authorizedActions: readonly string[];\n\treadonly requiredApprovals: readonly string[];\n\treadonly interruptionReason: string | null;\n}\n/** Z_t: predictions registered before execution and post-execution mismatches. */\nexport type PredictionState = readonly Prediction[];\n/** O_t: premises and completion obligations, plus unverified candidate duties. */\nexport type ObligationState = readonly Obligation[];\n/** M_t: conditional performance and calibration records. */\nexport type CalibrationState = CalibrationStore;\n\nexport interface MetaState {\n\treadonly goal: GoalState;\n\treadonly facts: FactState;\n\treadonly obligations: ObligationState;\n\treadonly evidence: EvidenceState;\n\treadonly predictions: PredictionState;\n\treadonly hypotheses: HypothesisState;\n\treadonly calibration: CalibrationState;\n\treadonly verifier: VerifierState;\n\treadonly budget: BudgetState;\n\treadonly policy: PolicyState;\n\treadonly hostSequence: number;\n\treadonly progressHistory: readonly {\n\t\tkey: string;\n\t\tnewEvidence: boolean;\n\t\tresolvedObligations: number;\n\t\tnewValidChecks: number;\n\t}[];\n\treadonly checkpointCount: number;\n}\n\nexport function validateMetaState(state: MetaState): void {\n\ttext(state.goal.taskId, \"taskId\", 128);\n\ttext(state.goal.stageId, \"stageId\", 128);\n\ttext(state.goal.targetArtifact, \"targetArtifact\", 512);\n\ttext(state.goal.goalScope, \"goalScope\", 256);\n\ttext(state.facts.candidateHash, \"candidateHash\", 128);\n\ttext(state.facts.environmentHash, \"environmentHash\", 128);\n\tmember(state.facts.analyzerCoverage, [\"covered\", \"partial\", \"unsupported\", \"unknown\"], \"analyzerCoverage\");\n\tmember(state.verifier.runnerHealth, [\"healthy\", \"degraded\", \"unverified\"], \"runnerHealth\");\n\ttext(state.policy.policyVersion, \"policyVersion\", 64);\n\tinteger(state.budget.remainingMs, \"remainingMs\");\n\tinteger(state.budget.remainingRequests, \"remainingRequests\");\n\tinteger(state.budget.remainingTokens, \"remainingTokens\");\n\tinteger(state.budget.remainingConcurrent, \"remainingConcurrent\");\n\tinteger(state.hostSequence, \"hostSequence\");\n\tinteger(state.checkpointCount, \"checkpointCount\");\n}\n\n/** Finish states per §9.5: continue, verified-bounded completion, inconclusive stop. */\nexport type FinishState =\n\t| { readonly kind: \"continue\" }\n\t| { readonly kind: \"verified-completion\"; readonly receiptId: string; readonly scope: string }\n\t| { readonly kind: \"inconclusive\"; readonly reason: string };\n\n/**\n * §9.5: a VOI of zero never implies verified completion. Completion requires\n * required obligations satisfied AND an approved completion receipt bound to\n * the current candidate.\n */\nexport function finishState(\n\tstate: MetaState,\n\treceipt: { receiptId: string; candidateHash: string; scope: string } | null,\n): FinishState {\n\tconst openRequired = state.obligations.filter((o) => o.status === \"required\" || o.status === \"violated\");\n\tif (receipt !== null) {\n\t\tensure(receipt.candidateHash === state.facts.candidateHash, \"receipt candidate binding mismatch\");\n\t\tif (openRequired.length === 0) {\n\t\t\treturn { kind: \"verified-completion\", receiptId: receipt.receiptId, scope: receipt.scope };\n\t\t}\n\t}\n\tif (openRequired.length > 0) {\n\t\treturn { kind: \"inconclusive\", reason: `unresolved-obligations:${openRequired.length}` };\n\t}\n\tif (state.budget.remainingMs === 0 || state.budget.remainingRequests === 0) {\n\t\treturn { kind: \"inconclusive\", reason: \"budget-exhausted\" };\n\t}\n\treturn { kind: \"continue\" };\n}\n\n/** Fingerprint of the full state for checkpoint diffs and receipts. */\nexport function stateFingerprint(state: MetaState): string {\n\treturn canonical([\n\t\tstate.goal.taskId,\n\t\tstate.goal.stageId,\n\t\tstate.facts.candidateHash,\n\t\tstate.facts.environmentHash,\n\t\tstate.policy.policyVersion,\n\t\tstate.obligations.map((o) => [o.id, o.status]),\n\t\tstate.predictions.map((p) => [p.predictionId, p.status]),\n\t]);\n}\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { canonical, ensure, integer, member, text } from "./validation.js";
|
|
2
|
+
export function validateMetaState(state) {
|
|
3
|
+
text(state.goal.taskId, "taskId", 128);
|
|
4
|
+
text(state.goal.stageId, "stageId", 128);
|
|
5
|
+
text(state.goal.targetArtifact, "targetArtifact", 512);
|
|
6
|
+
text(state.goal.goalScope, "goalScope", 256);
|
|
7
|
+
text(state.facts.candidateHash, "candidateHash", 128);
|
|
8
|
+
text(state.facts.environmentHash, "environmentHash", 128);
|
|
9
|
+
member(state.facts.analyzerCoverage, ["covered", "partial", "unsupported", "unknown"], "analyzerCoverage");
|
|
10
|
+
member(state.verifier.runnerHealth, ["healthy", "degraded", "unverified"], "runnerHealth");
|
|
11
|
+
text(state.policy.policyVersion, "policyVersion", 64);
|
|
12
|
+
integer(state.budget.remainingMs, "remainingMs");
|
|
13
|
+
integer(state.budget.remainingRequests, "remainingRequests");
|
|
14
|
+
integer(state.budget.remainingTokens, "remainingTokens");
|
|
15
|
+
integer(state.budget.remainingConcurrent, "remainingConcurrent");
|
|
16
|
+
integer(state.hostSequence, "hostSequence");
|
|
17
|
+
integer(state.checkpointCount, "checkpointCount");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* §9.5: a VOI of zero never implies verified completion. Completion requires
|
|
21
|
+
* required obligations satisfied AND an approved completion receipt bound to
|
|
22
|
+
* the current candidate.
|
|
23
|
+
*/
|
|
24
|
+
export function finishState(state, receipt) {
|
|
25
|
+
const openRequired = state.obligations.filter((o) => o.status === "required" || o.status === "violated");
|
|
26
|
+
if (receipt !== null) {
|
|
27
|
+
ensure(receipt.candidateHash === state.facts.candidateHash, "receipt candidate binding mismatch");
|
|
28
|
+
if (openRequired.length === 0) {
|
|
29
|
+
return { kind: "verified-completion", receiptId: receipt.receiptId, scope: receipt.scope };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (openRequired.length > 0) {
|
|
33
|
+
return { kind: "inconclusive", reason: `unresolved-obligations:${openRequired.length}` };
|
|
34
|
+
}
|
|
35
|
+
if (state.budget.remainingMs === 0 || state.budget.remainingRequests === 0) {
|
|
36
|
+
return { kind: "inconclusive", reason: "budget-exhausted" };
|
|
37
|
+
}
|
|
38
|
+
return { kind: "continue" };
|
|
39
|
+
}
|
|
40
|
+
/** Fingerprint of the full state for checkpoint diffs and receipts. */
|
|
41
|
+
export function stateFingerprint(state) {
|
|
42
|
+
return canonical([
|
|
43
|
+
state.goal.taskId,
|
|
44
|
+
state.goal.stageId,
|
|
45
|
+
state.facts.candidateHash,
|
|
46
|
+
state.facts.environmentHash,
|
|
47
|
+
state.policy.policyVersion,
|
|
48
|
+
state.obligations.map((o) => [o.id, o.status]),
|
|
49
|
+
state.predictions.map((p) => [p.predictionId, p.status]),
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/metacognition/state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Metacognitive state tuple and checkpoint evaluation.\n * Spec §3: X_t = (G, F, O, E, Z, H, M, V, B, P).\n *\n * The tuple is host-owned structured state; the model receives only the\n * hypotheses, evidence, and questions it needs right now. Recommended\n * computation unit is a decision checkpoint — before a new external symbol,\n * after an important change, after a check failure, after verification, after\n * a source conflict, or when strategy repetition is detected.\n */\nimport type { CalibrationStore } from \"./calibration.ts\";\nimport type { KnowledgeReport } from \"./knowledge.ts\";\nimport type { Obligation } from \"./obligations.ts\";\nimport type { Prediction } from \"./predictions.ts\";\nimport { canonical, ensure, integer, member, text } from \"./validation.ts\";\nimport type { VerifierEvaluation } from \"./verifier.ts\";\n\n/** G_t: current goal, stage, target artifact. */\nexport interface GoalState {\n\treadonly taskId: string;\n\treadonly stageId: string;\n\treadonly targetArtifact: string;\n\treadonly goalScope: string;\n}\n/** F_t: observed facts about repository, environment, pinned versions, change scope. */\nexport interface FactState {\n\treadonly candidateHash: string;\n\treadonly environmentHash: string;\n\treadonly changeScope: readonly string[];\n\treadonly analyzerCoverage: \"covered\" | \"partial\" | \"unsupported\" | \"unknown\";\n}\n/** E_t: evidence candidates, adopted evidence, checks bound to the current artifact. */\nexport interface EvidenceState {\n\treadonly report: KnowledgeReport | null;\n\treadonly adoptedSourceIds: readonly string[];\n}\n/** H_t: competing cause/design hypotheses and unresolved classification. */\nexport interface HypothesisState {\n\treadonly open: readonly string[];\n\treadonly discriminatorCandidates: readonly string[];\n\treadonly modelMismatch: boolean;\n}\n/** V_t: verifier detection coverage, known blind spots, runner health. */\nexport interface VerifierState {\n\treadonly evaluations: readonly VerifierEvaluation[];\n\treadonly runnerHealth: \"healthy\" | \"degraded\" | \"unverified\";\n}\n/** B_t: remaining time, requests, tokens, concurrency budget. */\nexport interface BudgetState {\n\treadonly remainingMs: number;\n\treadonly remainingRequests: number;\n\treadonly remainingTokens: number;\n\treadonly remainingConcurrent: number;\n}\n/** P_t: host-owned authorization, verification, interruption policy. */\nexport interface PolicyState {\n\treadonly policyVersion: string;\n\treadonly authorizedActions: readonly string[];\n\treadonly requiredApprovals: readonly string[];\n\treadonly interruptionReason: string | null;\n}\n/** Z_t: predictions registered before execution and post-execution mismatches. */\nexport type PredictionState = readonly Prediction[];\n/** O_t: premises and completion obligations, plus unverified candidate duties. */\nexport type ObligationState = readonly Obligation[];\n/** M_t: conditional performance and calibration records. */\nexport type CalibrationState = CalibrationStore;\n\nexport interface MetaState {\n\treadonly goal: GoalState;\n\treadonly facts: FactState;\n\treadonly obligations: ObligationState;\n\treadonly evidence: EvidenceState;\n\treadonly predictions: PredictionState;\n\treadonly hypotheses: HypothesisState;\n\treadonly calibration: CalibrationState;\n\treadonly verifier: VerifierState;\n\treadonly budget: BudgetState;\n\treadonly policy: PolicyState;\n\treadonly hostSequence: number;\n\treadonly progressHistory: readonly {\n\t\tkey: string;\n\t\tnewEvidence: boolean;\n\t\tresolvedObligations: number;\n\t\tnewValidChecks: number;\n\t}[];\n\treadonly checkpointCount: number;\n}\n\nexport function validateMetaState(state: MetaState): void {\n\ttext(state.goal.taskId, \"taskId\", 128);\n\ttext(state.goal.stageId, \"stageId\", 128);\n\ttext(state.goal.targetArtifact, \"targetArtifact\", 512);\n\ttext(state.goal.goalScope, \"goalScope\", 256);\n\ttext(state.facts.candidateHash, \"candidateHash\", 128);\n\ttext(state.facts.environmentHash, \"environmentHash\", 128);\n\tmember(state.facts.analyzerCoverage, [\"covered\", \"partial\", \"unsupported\", \"unknown\"], \"analyzerCoverage\");\n\tmember(state.verifier.runnerHealth, [\"healthy\", \"degraded\", \"unverified\"], \"runnerHealth\");\n\ttext(state.policy.policyVersion, \"policyVersion\", 64);\n\tinteger(state.budget.remainingMs, \"remainingMs\");\n\tinteger(state.budget.remainingRequests, \"remainingRequests\");\n\tinteger(state.budget.remainingTokens, \"remainingTokens\");\n\tinteger(state.budget.remainingConcurrent, \"remainingConcurrent\");\n\tinteger(state.hostSequence, \"hostSequence\");\n\tinteger(state.checkpointCount, \"checkpointCount\");\n}\n\n/** Finish states per §9.5: continue, verified-bounded completion, inconclusive stop. */\nexport type FinishState =\n\t| { readonly kind: \"continue\" }\n\t| { readonly kind: \"verified-completion\"; readonly receiptId: string; readonly scope: string }\n\t| { readonly kind: \"inconclusive\"; readonly reason: string };\n\n/**\n * §9.5: a VOI of zero never implies verified completion. Completion requires\n * required obligations satisfied AND an approved completion receipt bound to\n * the current candidate.\n */\nexport function finishState(\n\tstate: MetaState,\n\treceipt: { receiptId: string; candidateHash: string; scope: string } | null,\n): FinishState {\n\tconst openRequired = state.obligations.filter((o) => o.status === \"required\" || o.status === \"violated\");\n\tif (receipt !== null) {\n\t\tensure(receipt.candidateHash === state.facts.candidateHash, \"receipt candidate binding mismatch\");\n\t\tif (openRequired.length === 0) {\n\t\t\treturn { kind: \"verified-completion\", receiptId: receipt.receiptId, scope: receipt.scope };\n\t\t}\n\t}\n\tif (openRequired.length > 0) {\n\t\treturn { kind: \"inconclusive\", reason: `unresolved-obligations:${openRequired.length}` };\n\t}\n\tif (state.budget.remainingMs === 0 || state.budget.remainingRequests === 0) {\n\t\treturn { kind: \"inconclusive\", reason: \"budget-exhausted\" };\n\t}\n\treturn { kind: \"continue\" };\n}\n\n/** Fingerprint of the full state for checkpoint diffs and receipts. */\nexport function stateFingerprint(state: MetaState): string {\n\treturn canonical([\n\t\tstate.goal.taskId,\n\t\tstate.goal.stageId,\n\t\tstate.facts.candidateHash,\n\t\tstate.facts.environmentHash,\n\t\tstate.policy.policyVersion,\n\t\tstate.obligations.map((o) => [o.id, o.status]),\n\t\tstate.predictions.map((p) => [p.predictionId, p.status]),\n\t]);\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input-validation primitives for the metacognition kernel.
|
|
3
|
+
*
|
|
4
|
+
* Ported from docs/OMK_skill_knowledge_control_2026-09-19.zip
|
|
5
|
+
* (src/validation.ts). Deterministic, allocation-bounded, no I/O.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ensure(condition: unknown, message: string): asserts condition;
|
|
8
|
+
export declare function integer(value: number, label: string, max?: number): void;
|
|
9
|
+
export declare function finite(value: number, label: string, max?: number): void;
|
|
10
|
+
export declare function probability(value: number, label: string): void;
|
|
11
|
+
export declare function text(value: string, label: string, max?: number): void;
|
|
12
|
+
export declare function unique(values: readonly string[], label: string, max?: number): void;
|
|
13
|
+
export declare function member<T extends string>(value: T, values: readonly T[] | readonly string[], label: string): void;
|
|
14
|
+
export declare function lexical(a: string, b: string): number;
|
|
15
|
+
export declare function canonical(value: unknown): string;
|
|
16
|
+
export declare function arrayBound(value: unknown, label: string, max: number): void;
|
|
17
|
+
/** Probability vector: finite, [0,1], sums to 1. Mirrors check_examples.py. */
|
|
18
|
+
export declare function probabilityVector(values: readonly number[], label: string): void;
|
|
19
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/metacognition/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAE7E;AACD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAA0B,GAAG,IAAI,CAEzF;AACD,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAmB,GAAG,IAAI,CAKjF;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAK9D;AACD,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,IAAI,CAEnE;AACD,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,SAAM,GAAG,IAAI,CAIhF;AACD,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEhH;AACD,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AACD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAUhD;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3E;AACD,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAIhF","sourcesContent":["/**\n * Input-validation primitives for the metacognition kernel.\n *\n * Ported from docs/OMK_skill_knowledge_control_2026-09-19.zip\n * (src/validation.ts). Deterministic, allocation-bounded, no I/O.\n */\nexport function ensure(condition: unknown, message: string): asserts condition {\n\tif (!condition) throw new TypeError(message);\n}\nexport function integer(value: number, label: string, max = Number.MAX_SAFE_INTEGER): void {\n\tensure(Number.isSafeInteger(value) && value >= 0 && value <= max, `${label}: expected integer in [0, ${max}]`);\n}\nexport function finite(value: number, label: string, max = Number.MAX_VALUE): void {\n\tensure(\n\t\ttypeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= max,\n\t\t`${label}: expected finite number in [0, ${max}]`,\n\t);\n}\nexport function probability(value: number, label: string): void {\n\tensure(\n\t\ttypeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= 1,\n\t\t`${label}: expected probability in [0, 1]`,\n\t);\n}\nexport function text(value: string, label: string, max = 4096): void {\n\tensure(typeof value === \"string\" && value.trim().length > 0 && value.length <= max, `${label}: invalid string`);\n}\nexport function unique(values: readonly string[], label: string, max = 500): void {\n\tensure(Array.isArray(values) && values.length <= max, `${label}: invalid array`);\n\tfor (const value of values) text(value, label, 500);\n\tensure(new Set(values).size === values.length, `${label}: duplicate identifier`);\n}\nexport function member<T extends string>(value: T, values: readonly T[] | readonly string[], label: string): void {\n\tensure(values.includes(value), `${label}: invalid enum`);\n}\nexport function lexical(a: string, b: string): number {\n\treturn a < b ? -1 : a > b ? 1 : 0;\n}\nexport function canonical(value: unknown): string {\n\tif (value === undefined) return '\"__undefined__\"';\n\tif (Array.isArray(value)) return `[${value.map(canonical).join(\",\")}]`;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn `{${Object.entries(value)\n\t\t\t.sort(([a], [b]) => lexical(a, b))\n\t\t\t.map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)\n\t\t\t.join(\",\")}}`;\n\t}\n\treturn JSON.stringify(value);\n}\nexport function arrayBound(value: unknown, label: string, max: number): void {\n\tensure(Array.isArray(value) && value.length <= max, `${label}: invalid array`);\n}\n/** Probability vector: finite, [0,1], sums to 1. Mirrors check_examples.py. */\nexport function probabilityVector(values: readonly number[], label: string): void {\n\tensure(values.length > 0, `${label}: empty probability vector`);\n\tfor (const v of values) probability(v, label);\n\tensure(Math.abs(values.reduce((a, b) => a + b, 0) - 1) <= 1e-9, `${label}: probabilities must sum to one`);\n}\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input-validation primitives for the metacognition kernel.
|
|
3
|
+
*
|
|
4
|
+
* Ported from docs/OMK_skill_knowledge_control_2026-09-19.zip
|
|
5
|
+
* (src/validation.ts). Deterministic, allocation-bounded, no I/O.
|
|
6
|
+
*/
|
|
7
|
+
export function ensure(condition, message) {
|
|
8
|
+
if (!condition)
|
|
9
|
+
throw new TypeError(message);
|
|
10
|
+
}
|
|
11
|
+
export function integer(value, label, max = Number.MAX_SAFE_INTEGER) {
|
|
12
|
+
ensure(Number.isSafeInteger(value) && value >= 0 && value <= max, `${label}: expected integer in [0, ${max}]`);
|
|
13
|
+
}
|
|
14
|
+
export function finite(value, label, max = Number.MAX_VALUE) {
|
|
15
|
+
ensure(typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= max, `${label}: expected finite number in [0, ${max}]`);
|
|
16
|
+
}
|
|
17
|
+
export function probability(value, label) {
|
|
18
|
+
ensure(typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1, `${label}: expected probability in [0, 1]`);
|
|
19
|
+
}
|
|
20
|
+
export function text(value, label, max = 4096) {
|
|
21
|
+
ensure(typeof value === "string" && value.trim().length > 0 && value.length <= max, `${label}: invalid string`);
|
|
22
|
+
}
|
|
23
|
+
export function unique(values, label, max = 500) {
|
|
24
|
+
ensure(Array.isArray(values) && values.length <= max, `${label}: invalid array`);
|
|
25
|
+
for (const value of values)
|
|
26
|
+
text(value, label, 500);
|
|
27
|
+
ensure(new Set(values).size === values.length, `${label}: duplicate identifier`);
|
|
28
|
+
}
|
|
29
|
+
export function member(value, values, label) {
|
|
30
|
+
ensure(values.includes(value), `${label}: invalid enum`);
|
|
31
|
+
}
|
|
32
|
+
export function lexical(a, b) {
|
|
33
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
34
|
+
}
|
|
35
|
+
export function canonical(value) {
|
|
36
|
+
if (value === undefined)
|
|
37
|
+
return '"__undefined__"';
|
|
38
|
+
if (Array.isArray(value))
|
|
39
|
+
return `[${value.map(canonical).join(",")}]`;
|
|
40
|
+
if (value !== null && typeof value === "object") {
|
|
41
|
+
return `{${Object.entries(value)
|
|
42
|
+
.sort(([a], [b]) => lexical(a, b))
|
|
43
|
+
.map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)
|
|
44
|
+
.join(",")}}`;
|
|
45
|
+
}
|
|
46
|
+
return JSON.stringify(value);
|
|
47
|
+
}
|
|
48
|
+
export function arrayBound(value, label, max) {
|
|
49
|
+
ensure(Array.isArray(value) && value.length <= max, `${label}: invalid array`);
|
|
50
|
+
}
|
|
51
|
+
/** Probability vector: finite, [0,1], sums to 1. Mirrors check_examples.py. */
|
|
52
|
+
export function probabilityVector(values, label) {
|
|
53
|
+
ensure(values.length > 0, `${label}: empty probability vector`);
|
|
54
|
+
for (const v of values)
|
|
55
|
+
probability(v, label);
|
|
56
|
+
ensure(Math.abs(values.reduce((a, b) => a + b, 0) - 1) <= 1e-9, `${label}: probabilities must sum to one`);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/metacognition/validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Input-validation primitives for the metacognition kernel.\n *\n * Ported from docs/OMK_skill_knowledge_control_2026-09-19.zip\n * (src/validation.ts). Deterministic, allocation-bounded, no I/O.\n */\nexport function ensure(condition: unknown, message: string): asserts condition {\n\tif (!condition) throw new TypeError(message);\n}\nexport function integer(value: number, label: string, max = Number.MAX_SAFE_INTEGER): void {\n\tensure(Number.isSafeInteger(value) && value >= 0 && value <= max, `${label}: expected integer in [0, ${max}]`);\n}\nexport function finite(value: number, label: string, max = Number.MAX_VALUE): void {\n\tensure(\n\t\ttypeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= max,\n\t\t`${label}: expected finite number in [0, ${max}]`,\n\t);\n}\nexport function probability(value: number, label: string): void {\n\tensure(\n\t\ttypeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= 1,\n\t\t`${label}: expected probability in [0, 1]`,\n\t);\n}\nexport function text(value: string, label: string, max = 4096): void {\n\tensure(typeof value === \"string\" && value.trim().length > 0 && value.length <= max, `${label}: invalid string`);\n}\nexport function unique(values: readonly string[], label: string, max = 500): void {\n\tensure(Array.isArray(values) && values.length <= max, `${label}: invalid array`);\n\tfor (const value of values) text(value, label, 500);\n\tensure(new Set(values).size === values.length, `${label}: duplicate identifier`);\n}\nexport function member<T extends string>(value: T, values: readonly T[] | readonly string[], label: string): void {\n\tensure(values.includes(value), `${label}: invalid enum`);\n}\nexport function lexical(a: string, b: string): number {\n\treturn a < b ? -1 : a > b ? 1 : 0;\n}\nexport function canonical(value: unknown): string {\n\tif (value === undefined) return '\"__undefined__\"';\n\tif (Array.isArray(value)) return `[${value.map(canonical).join(\",\")}]`;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn `{${Object.entries(value)\n\t\t\t.sort(([a], [b]) => lexical(a, b))\n\t\t\t.map(([key, item]) => `${JSON.stringify(key)}:${canonical(item)}`)\n\t\t\t.join(\",\")}}`;\n\t}\n\treturn JSON.stringify(value);\n}\nexport function arrayBound(value: unknown, label: string, max: number): void {\n\tensure(Array.isArray(value) && value.length <= max, `${label}: invalid array`);\n}\n/** Probability vector: finite, [0,1], sums to 1. Mirrors check_examples.py. */\nexport function probabilityVector(values: readonly number[], label: string): void {\n\tensure(values.length > 0, `${label}: empty probability vector`);\n\tfor (const v of values) probability(v, label);\n\tensure(Math.abs(values.reduce((a, b) => a + b, 0) - 1) <= 1e-9, `${label}: probabilities must sum to one`);\n}\n"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time-aware independent verification (Jev audit algorithm A7, finding F07).
|
|
3
|
+
*
|
|
4
|
+
* F07 is the confusion between "each condition was satisfied at some point"
|
|
5
|
+
* and "they hold together now". Keeping `CompleteCurrent` and `CompleteEver`
|
|
6
|
+
* apart resolves it without throwing away valid history.
|
|
7
|
+
*
|
|
8
|
+
* `unknown` is a third value, not a synonym for `false`. A missing field or an
|
|
9
|
+
* incomplete collection scope means the evidence is absent; any binary rule
|
|
10
|
+
* that negates it into `true` manufactures a verification that never happened.
|
|
11
|
+
*
|
|
12
|
+
* Evidence strength is ordered but deliberately not a universal trust score:
|
|
13
|
+
* a backend response still has to be matched to the right account and request.
|
|
14
|
+
* The point is to hold a verification signal that does not share the executing
|
|
15
|
+
* model's uncertainty.
|
|
16
|
+
*/
|
|
17
|
+
export type ConditionValue = "true" | "false" | "unknown";
|
|
18
|
+
export interface ConditionObservation {
|
|
19
|
+
readonly snapshotId: string;
|
|
20
|
+
/** Target generation this snapshot belongs to. */
|
|
21
|
+
readonly generation: number;
|
|
22
|
+
readonly values: Readonly<Record<string, ConditionValue>>;
|
|
23
|
+
}
|
|
24
|
+
export interface UnsatisfiedCondition {
|
|
25
|
+
readonly condition: string;
|
|
26
|
+
readonly value: ConditionValue;
|
|
27
|
+
}
|
|
28
|
+
export type CompletionResult = {
|
|
29
|
+
readonly complete: true;
|
|
30
|
+
} | {
|
|
31
|
+
readonly complete: false;
|
|
32
|
+
readonly unsatisfied: readonly UnsatisfiedCondition[];
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Every current condition must hold in the *same* snapshot.
|
|
36
|
+
*
|
|
37
|
+
* Evaluating them across snapshots would let a condition that has since
|
|
38
|
+
* flipped keep satisfying the gate.
|
|
39
|
+
*/
|
|
40
|
+
export declare function completeCurrent(conditions: readonly string[], snapshot: ConditionObservation): CompletionResult;
|
|
41
|
+
/**
|
|
42
|
+
* Each historical condition must have been observed true at least once in the
|
|
43
|
+
* supplied evidence set, which the caller scopes to the current task.
|
|
44
|
+
*/
|
|
45
|
+
export declare function completeEver(conditions: readonly string[], history: readonly ConditionObservation[]): CompletionResult;
|
|
46
|
+
export type EvidenceKind = "authoritative-query" | "structured-remote-linked" | "independent-ui" | "page-success-text" | "model-completion-claim";
|
|
47
|
+
export declare function evidenceStrength(kind: EvidenceKind): number;
|
|
48
|
+
export type VerificationLevel = "REMOTE_EFFECT_VERIFIED" | "UI_VERIFIED" | "CLAIMED_ONLY";
|
|
49
|
+
/**
|
|
50
|
+
* Label a result by the strongest evidence actually held.
|
|
51
|
+
*
|
|
52
|
+
* A UI observation is reported as `UI_VERIFIED`, never as
|
|
53
|
+
* `REMOTE_EFFECT_VERIFIED`: if the target system offers no authoritative
|
|
54
|
+
* query, the honest move is to lower the claimed level, not to borrow one.
|
|
55
|
+
*/
|
|
56
|
+
export declare function strongestEvidence(kinds: readonly EvidenceKind[]): VerificationLevel;
|
|
57
|
+
export interface EvidenceItem {
|
|
58
|
+
readonly id: string;
|
|
59
|
+
/** Common-cause group, e.g. one DOM snapshot that many readings derive from. */
|
|
60
|
+
readonly sourceGroup: string;
|
|
61
|
+
}
|
|
62
|
+
export interface EvidenceGrouping {
|
|
63
|
+
readonly independentCount: number;
|
|
64
|
+
readonly byGroup: Readonly<Record<string, number>>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Collapse correlated readings into their source groups.
|
|
68
|
+
*
|
|
69
|
+
* Fifty screenshots of one screen are one witness. Text, accessibility names
|
|
70
|
+
* and rendered copy from the same DOM share a common cause, so counting them
|
|
71
|
+
* separately inflates apparent independent confirmation.
|
|
72
|
+
*/
|
|
73
|
+
export declare function independentEvidenceGroups(items: readonly EvidenceItem[]): EvidenceGrouping;
|
|
74
|
+
export interface VerifierSample {
|
|
75
|
+
readonly verdict: ConditionValue;
|
|
76
|
+
/** Externally established truth, not another model's opinion. */
|
|
77
|
+
readonly truth: "true" | "false";
|
|
78
|
+
}
|
|
79
|
+
export interface VerifierQuality {
|
|
80
|
+
/** Undefined when no negative case was sampled; that is absent evidence. */
|
|
81
|
+
readonly falsePositiveRate: number | undefined;
|
|
82
|
+
readonly falseNegativeRate: number | undefined;
|
|
83
|
+
readonly unknownRate: number;
|
|
84
|
+
readonly samples: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Measure the verifier before reporting any success rate.
|
|
88
|
+
*
|
|
89
|
+
* A mislabelling verifier contaminates every downstream selector and bandit
|
|
90
|
+
* trained on its labels, so its error rates are the prior question.
|
|
91
|
+
*/
|
|
92
|
+
export declare function verifierQuality(samples: readonly VerifierSample[]): VerifierQuality;
|
|
93
|
+
//# sourceMappingURL=verification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../src/metacognition/verification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;CAC/B;AAED,MAAM,MAAM,gBAAgB,GACzB;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAA;CAAE,CAAC;AAEvF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,oBAAoB,GAAG,gBAAgB,CAS/G;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,SAAS,oBAAoB,EAAE,GACtC,gBAAgB,CAWlB;AAED,MAAM,MAAM,YAAY,GACrB,qBAAqB,GACrB,0BAA0B,GAC1B,gBAAgB,GAChB,mBAAmB,GACnB,wBAAwB,CAAC;AAU5B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAI3D;AAED,MAAM,MAAM,iBAAiB,GAAG,wBAAwB,GAAG,aAAa,GAAG,cAAc,CAAC;AAE1F;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,iBAAiB,CAOnF;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACnD;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,GAAG,gBAAgB,CAW1F;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,eAAe,CAuBnF","sourcesContent":["/**\n * Time-aware independent verification (Jev audit algorithm A7, finding F07).\n *\n * F07 is the confusion between \"each condition was satisfied at some point\"\n * and \"they hold together now\". Keeping `CompleteCurrent` and `CompleteEver`\n * apart resolves it without throwing away valid history.\n *\n * `unknown` is a third value, not a synonym for `false`. A missing field or an\n * incomplete collection scope means the evidence is absent; any binary rule\n * that negates it into `true` manufactures a verification that never happened.\n *\n * Evidence strength is ordered but deliberately not a universal trust score:\n * a backend response still has to be matched to the right account and request.\n * The point is to hold a verification signal that does not share the executing\n * model's uncertainty.\n */\n\nimport { ensure } from \"./validation.ts\";\n\nexport type ConditionValue = \"true\" | \"false\" | \"unknown\";\n\nexport interface ConditionObservation {\n\treadonly snapshotId: string;\n\t/** Target generation this snapshot belongs to. */\n\treadonly generation: number;\n\treadonly values: Readonly<Record<string, ConditionValue>>;\n}\n\nexport interface UnsatisfiedCondition {\n\treadonly condition: string;\n\treadonly value: ConditionValue;\n}\n\nexport type CompletionResult =\n\t| { readonly complete: true }\n\t| { readonly complete: false; readonly unsatisfied: readonly UnsatisfiedCondition[] };\n\n/**\n * Every current condition must hold in the *same* snapshot.\n *\n * Evaluating them across snapshots would let a condition that has since\n * flipped keep satisfying the gate.\n */\nexport function completeCurrent(conditions: readonly string[], snapshot: ConditionObservation): CompletionResult {\n\tensure(Array.isArray(conditions) && conditions.length > 0, \"current conditions must be non-empty\");\n\tconst unsatisfied: UnsatisfiedCondition[] = [];\n\tfor (const condition of conditions) {\n\t\t// An absent field is unknown, never false.\n\t\tconst value = snapshot.values[condition] ?? \"unknown\";\n\t\tif (value !== \"true\") unsatisfied.push({ condition, value });\n\t}\n\treturn unsatisfied.length === 0 ? { complete: true } : { complete: false, unsatisfied };\n}\n\n/**\n * Each historical condition must have been observed true at least once in the\n * supplied evidence set, which the caller scopes to the current task.\n */\nexport function completeEver(\n\tconditions: readonly string[],\n\thistory: readonly ConditionObservation[],\n): CompletionResult {\n\tensure(Array.isArray(conditions) && conditions.length > 0, \"ever conditions must be non-empty\");\n\tensure(Array.isArray(history) && history.length > 0, \"history must be non-empty to judge an ever condition\");\n\tconst unsatisfied: UnsatisfiedCondition[] = [];\n\tfor (const condition of conditions) {\n\t\tconst seenTrue = history.some((snapshot) => snapshot.values[condition] === \"true\");\n\t\tif (seenTrue) continue;\n\t\tconst anyKnown = history.some((snapshot) => snapshot.values[condition] === \"false\");\n\t\tunsatisfied.push({ condition, value: anyKnown ? \"false\" : \"unknown\" });\n\t}\n\treturn unsatisfied.length === 0 ? { complete: true } : { complete: false, unsatisfied };\n}\n\nexport type EvidenceKind =\n\t| \"authoritative-query\"\n\t| \"structured-remote-linked\"\n\t| \"independent-ui\"\n\t| \"page-success-text\"\n\t| \"model-completion-claim\";\n\nconst EVIDENCE_RANK: Readonly<Record<EvidenceKind, number>> = {\n\t\"authoritative-query\": 4,\n\t\"structured-remote-linked\": 3,\n\t\"independent-ui\": 2,\n\t\"page-success-text\": 1,\n\t\"model-completion-claim\": 0,\n};\n\nexport function evidenceStrength(kind: EvidenceKind): number {\n\tconst rank = EVIDENCE_RANK[kind];\n\tensure(rank !== undefined, `unknown evidence kind: ${String(kind)}`);\n\treturn rank;\n}\n\nexport type VerificationLevel = \"REMOTE_EFFECT_VERIFIED\" | \"UI_VERIFIED\" | \"CLAIMED_ONLY\";\n\n/**\n * Label a result by the strongest evidence actually held.\n *\n * A UI observation is reported as `UI_VERIFIED`, never as\n * `REMOTE_EFFECT_VERIFIED`: if the target system offers no authoritative\n * query, the honest move is to lower the claimed level, not to borrow one.\n */\nexport function strongestEvidence(kinds: readonly EvidenceKind[]): VerificationLevel {\n\tensure(Array.isArray(kinds) && kinds.length > 0, \"evidence set must be non-empty\");\n\tlet best = -1;\n\tfor (const kind of kinds) best = Math.max(best, evidenceStrength(kind));\n\tif (best >= EVIDENCE_RANK[\"structured-remote-linked\"]) return \"REMOTE_EFFECT_VERIFIED\";\n\tif (best >= EVIDENCE_RANK[\"independent-ui\"]) return \"UI_VERIFIED\";\n\treturn \"CLAIMED_ONLY\";\n}\n\nexport interface EvidenceItem {\n\treadonly id: string;\n\t/** Common-cause group, e.g. one DOM snapshot that many readings derive from. */\n\treadonly sourceGroup: string;\n}\n\nexport interface EvidenceGrouping {\n\treadonly independentCount: number;\n\treadonly byGroup: Readonly<Record<string, number>>;\n}\n\n/**\n * Collapse correlated readings into their source groups.\n *\n * Fifty screenshots of one screen are one witness. Text, accessibility names\n * and rendered copy from the same DOM share a common cause, so counting them\n * separately inflates apparent independent confirmation.\n */\nexport function independentEvidenceGroups(items: readonly EvidenceItem[]): EvidenceGrouping {\n\tensure(Array.isArray(items) && items.length > 0, \"evidence items must be non-empty\");\n\tconst byGroup: Record<string, number> = {};\n\tfor (const item of items) {\n\t\tensure(\n\t\t\ttypeof item.sourceGroup === \"string\" && item.sourceGroup.length > 0,\n\t\t\t\"each evidence item needs a declared sourceGroup\",\n\t\t);\n\t\tbyGroup[item.sourceGroup] = (byGroup[item.sourceGroup] ?? 0) + 1;\n\t}\n\treturn { independentCount: Object.keys(byGroup).length, byGroup };\n}\n\nexport interface VerifierSample {\n\treadonly verdict: ConditionValue;\n\t/** Externally established truth, not another model's opinion. */\n\treadonly truth: \"true\" | \"false\";\n}\n\nexport interface VerifierQuality {\n\t/** Undefined when no negative case was sampled; that is absent evidence. */\n\treadonly falsePositiveRate: number | undefined;\n\treadonly falseNegativeRate: number | undefined;\n\treadonly unknownRate: number;\n\treadonly samples: number;\n}\n\n/**\n * Measure the verifier before reporting any success rate.\n *\n * A mislabelling verifier contaminates every downstream selector and bandit\n * trained on its labels, so its error rates are the prior question.\n */\nexport function verifierQuality(samples: readonly VerifierSample[]): VerifierQuality {\n\tensure(Array.isArray(samples) && samples.length > 0, \"verifier samples must be non-empty\");\n\tlet positives = 0;\n\tlet negatives = 0;\n\tlet falsePositives = 0;\n\tlet falseNegatives = 0;\n\tlet unknowns = 0;\n\tfor (const sample of samples) {\n\t\tif (sample.verdict === \"unknown\") unknowns += 1;\n\t\tif (sample.truth === \"true\") {\n\t\t\tpositives += 1;\n\t\t\tif (sample.verdict === \"false\") falseNegatives += 1;\n\t\t} else {\n\t\t\tnegatives += 1;\n\t\t\tif (sample.verdict === \"true\") falsePositives += 1;\n\t\t}\n\t}\n\treturn {\n\t\tfalsePositiveRate: negatives > 0 ? falsePositives / negatives : undefined,\n\t\tfalseNegativeRate: positives > 0 ? falseNegatives / positives : undefined,\n\t\tunknownRate: unknowns / samples.length,\n\t\tsamples: samples.length,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time-aware independent verification (Jev audit algorithm A7, finding F07).
|
|
3
|
+
*
|
|
4
|
+
* F07 is the confusion between "each condition was satisfied at some point"
|
|
5
|
+
* and "they hold together now". Keeping `CompleteCurrent` and `CompleteEver`
|
|
6
|
+
* apart resolves it without throwing away valid history.
|
|
7
|
+
*
|
|
8
|
+
* `unknown` is a third value, not a synonym for `false`. A missing field or an
|
|
9
|
+
* incomplete collection scope means the evidence is absent; any binary rule
|
|
10
|
+
* that negates it into `true` manufactures a verification that never happened.
|
|
11
|
+
*
|
|
12
|
+
* Evidence strength is ordered but deliberately not a universal trust score:
|
|
13
|
+
* a backend response still has to be matched to the right account and request.
|
|
14
|
+
* The point is to hold a verification signal that does not share the executing
|
|
15
|
+
* model's uncertainty.
|
|
16
|
+
*/
|
|
17
|
+
import { ensure } from "./validation.js";
|
|
18
|
+
/**
|
|
19
|
+
* Every current condition must hold in the *same* snapshot.
|
|
20
|
+
*
|
|
21
|
+
* Evaluating them across snapshots would let a condition that has since
|
|
22
|
+
* flipped keep satisfying the gate.
|
|
23
|
+
*/
|
|
24
|
+
export function completeCurrent(conditions, snapshot) {
|
|
25
|
+
ensure(Array.isArray(conditions) && conditions.length > 0, "current conditions must be non-empty");
|
|
26
|
+
const unsatisfied = [];
|
|
27
|
+
for (const condition of conditions) {
|
|
28
|
+
// An absent field is unknown, never false.
|
|
29
|
+
const value = snapshot.values[condition] ?? "unknown";
|
|
30
|
+
if (value !== "true")
|
|
31
|
+
unsatisfied.push({ condition, value });
|
|
32
|
+
}
|
|
33
|
+
return unsatisfied.length === 0 ? { complete: true } : { complete: false, unsatisfied };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Each historical condition must have been observed true at least once in the
|
|
37
|
+
* supplied evidence set, which the caller scopes to the current task.
|
|
38
|
+
*/
|
|
39
|
+
export function completeEver(conditions, history) {
|
|
40
|
+
ensure(Array.isArray(conditions) && conditions.length > 0, "ever conditions must be non-empty");
|
|
41
|
+
ensure(Array.isArray(history) && history.length > 0, "history must be non-empty to judge an ever condition");
|
|
42
|
+
const unsatisfied = [];
|
|
43
|
+
for (const condition of conditions) {
|
|
44
|
+
const seenTrue = history.some((snapshot) => snapshot.values[condition] === "true");
|
|
45
|
+
if (seenTrue)
|
|
46
|
+
continue;
|
|
47
|
+
const anyKnown = history.some((snapshot) => snapshot.values[condition] === "false");
|
|
48
|
+
unsatisfied.push({ condition, value: anyKnown ? "false" : "unknown" });
|
|
49
|
+
}
|
|
50
|
+
return unsatisfied.length === 0 ? { complete: true } : { complete: false, unsatisfied };
|
|
51
|
+
}
|
|
52
|
+
const EVIDENCE_RANK = {
|
|
53
|
+
"authoritative-query": 4,
|
|
54
|
+
"structured-remote-linked": 3,
|
|
55
|
+
"independent-ui": 2,
|
|
56
|
+
"page-success-text": 1,
|
|
57
|
+
"model-completion-claim": 0,
|
|
58
|
+
};
|
|
59
|
+
export function evidenceStrength(kind) {
|
|
60
|
+
const rank = EVIDENCE_RANK[kind];
|
|
61
|
+
ensure(rank !== undefined, `unknown evidence kind: ${String(kind)}`);
|
|
62
|
+
return rank;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Label a result by the strongest evidence actually held.
|
|
66
|
+
*
|
|
67
|
+
* A UI observation is reported as `UI_VERIFIED`, never as
|
|
68
|
+
* `REMOTE_EFFECT_VERIFIED`: if the target system offers no authoritative
|
|
69
|
+
* query, the honest move is to lower the claimed level, not to borrow one.
|
|
70
|
+
*/
|
|
71
|
+
export function strongestEvidence(kinds) {
|
|
72
|
+
ensure(Array.isArray(kinds) && kinds.length > 0, "evidence set must be non-empty");
|
|
73
|
+
let best = -1;
|
|
74
|
+
for (const kind of kinds)
|
|
75
|
+
best = Math.max(best, evidenceStrength(kind));
|
|
76
|
+
if (best >= EVIDENCE_RANK["structured-remote-linked"])
|
|
77
|
+
return "REMOTE_EFFECT_VERIFIED";
|
|
78
|
+
if (best >= EVIDENCE_RANK["independent-ui"])
|
|
79
|
+
return "UI_VERIFIED";
|
|
80
|
+
return "CLAIMED_ONLY";
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Collapse correlated readings into their source groups.
|
|
84
|
+
*
|
|
85
|
+
* Fifty screenshots of one screen are one witness. Text, accessibility names
|
|
86
|
+
* and rendered copy from the same DOM share a common cause, so counting them
|
|
87
|
+
* separately inflates apparent independent confirmation.
|
|
88
|
+
*/
|
|
89
|
+
export function independentEvidenceGroups(items) {
|
|
90
|
+
ensure(Array.isArray(items) && items.length > 0, "evidence items must be non-empty");
|
|
91
|
+
const byGroup = {};
|
|
92
|
+
for (const item of items) {
|
|
93
|
+
ensure(typeof item.sourceGroup === "string" && item.sourceGroup.length > 0, "each evidence item needs a declared sourceGroup");
|
|
94
|
+
byGroup[item.sourceGroup] = (byGroup[item.sourceGroup] ?? 0) + 1;
|
|
95
|
+
}
|
|
96
|
+
return { independentCount: Object.keys(byGroup).length, byGroup };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Measure the verifier before reporting any success rate.
|
|
100
|
+
*
|
|
101
|
+
* A mislabelling verifier contaminates every downstream selector and bandit
|
|
102
|
+
* trained on its labels, so its error rates are the prior question.
|
|
103
|
+
*/
|
|
104
|
+
export function verifierQuality(samples) {
|
|
105
|
+
ensure(Array.isArray(samples) && samples.length > 0, "verifier samples must be non-empty");
|
|
106
|
+
let positives = 0;
|
|
107
|
+
let negatives = 0;
|
|
108
|
+
let falsePositives = 0;
|
|
109
|
+
let falseNegatives = 0;
|
|
110
|
+
let unknowns = 0;
|
|
111
|
+
for (const sample of samples) {
|
|
112
|
+
if (sample.verdict === "unknown")
|
|
113
|
+
unknowns += 1;
|
|
114
|
+
if (sample.truth === "true") {
|
|
115
|
+
positives += 1;
|
|
116
|
+
if (sample.verdict === "false")
|
|
117
|
+
falseNegatives += 1;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
negatives += 1;
|
|
121
|
+
if (sample.verdict === "true")
|
|
122
|
+
falsePositives += 1;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
falsePositiveRate: negatives > 0 ? falsePositives / negatives : undefined,
|
|
127
|
+
falseNegativeRate: positives > 0 ? falseNegatives / positives : undefined,
|
|
128
|
+
unknownRate: unknowns / samples.length,
|
|
129
|
+
samples: samples.length,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/metacognition/verification.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Time-aware independent verification (Jev audit algorithm A7, finding F07).\n *\n * F07 is the confusion between \"each condition was satisfied at some point\"\n * and \"they hold together now\". Keeping `CompleteCurrent` and `CompleteEver`\n * apart resolves it without throwing away valid history.\n *\n * `unknown` is a third value, not a synonym for `false`. A missing field or an\n * incomplete collection scope means the evidence is absent; any binary rule\n * that negates it into `true` manufactures a verification that never happened.\n *\n * Evidence strength is ordered but deliberately not a universal trust score:\n * a backend response still has to be matched to the right account and request.\n * The point is to hold a verification signal that does not share the executing\n * model's uncertainty.\n */\n\nimport { ensure } from \"./validation.ts\";\n\nexport type ConditionValue = \"true\" | \"false\" | \"unknown\";\n\nexport interface ConditionObservation {\n\treadonly snapshotId: string;\n\t/** Target generation this snapshot belongs to. */\n\treadonly generation: number;\n\treadonly values: Readonly<Record<string, ConditionValue>>;\n}\n\nexport interface UnsatisfiedCondition {\n\treadonly condition: string;\n\treadonly value: ConditionValue;\n}\n\nexport type CompletionResult =\n\t| { readonly complete: true }\n\t| { readonly complete: false; readonly unsatisfied: readonly UnsatisfiedCondition[] };\n\n/**\n * Every current condition must hold in the *same* snapshot.\n *\n * Evaluating them across snapshots would let a condition that has since\n * flipped keep satisfying the gate.\n */\nexport function completeCurrent(conditions: readonly string[], snapshot: ConditionObservation): CompletionResult {\n\tensure(Array.isArray(conditions) && conditions.length > 0, \"current conditions must be non-empty\");\n\tconst unsatisfied: UnsatisfiedCondition[] = [];\n\tfor (const condition of conditions) {\n\t\t// An absent field is unknown, never false.\n\t\tconst value = snapshot.values[condition] ?? \"unknown\";\n\t\tif (value !== \"true\") unsatisfied.push({ condition, value });\n\t}\n\treturn unsatisfied.length === 0 ? { complete: true } : { complete: false, unsatisfied };\n}\n\n/**\n * Each historical condition must have been observed true at least once in the\n * supplied evidence set, which the caller scopes to the current task.\n */\nexport function completeEver(\n\tconditions: readonly string[],\n\thistory: readonly ConditionObservation[],\n): CompletionResult {\n\tensure(Array.isArray(conditions) && conditions.length > 0, \"ever conditions must be non-empty\");\n\tensure(Array.isArray(history) && history.length > 0, \"history must be non-empty to judge an ever condition\");\n\tconst unsatisfied: UnsatisfiedCondition[] = [];\n\tfor (const condition of conditions) {\n\t\tconst seenTrue = history.some((snapshot) => snapshot.values[condition] === \"true\");\n\t\tif (seenTrue) continue;\n\t\tconst anyKnown = history.some((snapshot) => snapshot.values[condition] === \"false\");\n\t\tunsatisfied.push({ condition, value: anyKnown ? \"false\" : \"unknown\" });\n\t}\n\treturn unsatisfied.length === 0 ? { complete: true } : { complete: false, unsatisfied };\n}\n\nexport type EvidenceKind =\n\t| \"authoritative-query\"\n\t| \"structured-remote-linked\"\n\t| \"independent-ui\"\n\t| \"page-success-text\"\n\t| \"model-completion-claim\";\n\nconst EVIDENCE_RANK: Readonly<Record<EvidenceKind, number>> = {\n\t\"authoritative-query\": 4,\n\t\"structured-remote-linked\": 3,\n\t\"independent-ui\": 2,\n\t\"page-success-text\": 1,\n\t\"model-completion-claim\": 0,\n};\n\nexport function evidenceStrength(kind: EvidenceKind): number {\n\tconst rank = EVIDENCE_RANK[kind];\n\tensure(rank !== undefined, `unknown evidence kind: ${String(kind)}`);\n\treturn rank;\n}\n\nexport type VerificationLevel = \"REMOTE_EFFECT_VERIFIED\" | \"UI_VERIFIED\" | \"CLAIMED_ONLY\";\n\n/**\n * Label a result by the strongest evidence actually held.\n *\n * A UI observation is reported as `UI_VERIFIED`, never as\n * `REMOTE_EFFECT_VERIFIED`: if the target system offers no authoritative\n * query, the honest move is to lower the claimed level, not to borrow one.\n */\nexport function strongestEvidence(kinds: readonly EvidenceKind[]): VerificationLevel {\n\tensure(Array.isArray(kinds) && kinds.length > 0, \"evidence set must be non-empty\");\n\tlet best = -1;\n\tfor (const kind of kinds) best = Math.max(best, evidenceStrength(kind));\n\tif (best >= EVIDENCE_RANK[\"structured-remote-linked\"]) return \"REMOTE_EFFECT_VERIFIED\";\n\tif (best >= EVIDENCE_RANK[\"independent-ui\"]) return \"UI_VERIFIED\";\n\treturn \"CLAIMED_ONLY\";\n}\n\nexport interface EvidenceItem {\n\treadonly id: string;\n\t/** Common-cause group, e.g. one DOM snapshot that many readings derive from. */\n\treadonly sourceGroup: string;\n}\n\nexport interface EvidenceGrouping {\n\treadonly independentCount: number;\n\treadonly byGroup: Readonly<Record<string, number>>;\n}\n\n/**\n * Collapse correlated readings into their source groups.\n *\n * Fifty screenshots of one screen are one witness. Text, accessibility names\n * and rendered copy from the same DOM share a common cause, so counting them\n * separately inflates apparent independent confirmation.\n */\nexport function independentEvidenceGroups(items: readonly EvidenceItem[]): EvidenceGrouping {\n\tensure(Array.isArray(items) && items.length > 0, \"evidence items must be non-empty\");\n\tconst byGroup: Record<string, number> = {};\n\tfor (const item of items) {\n\t\tensure(\n\t\t\ttypeof item.sourceGroup === \"string\" && item.sourceGroup.length > 0,\n\t\t\t\"each evidence item needs a declared sourceGroup\",\n\t\t);\n\t\tbyGroup[item.sourceGroup] = (byGroup[item.sourceGroup] ?? 0) + 1;\n\t}\n\treturn { independentCount: Object.keys(byGroup).length, byGroup };\n}\n\nexport interface VerifierSample {\n\treadonly verdict: ConditionValue;\n\t/** Externally established truth, not another model's opinion. */\n\treadonly truth: \"true\" | \"false\";\n}\n\nexport interface VerifierQuality {\n\t/** Undefined when no negative case was sampled; that is absent evidence. */\n\treadonly falsePositiveRate: number | undefined;\n\treadonly falseNegativeRate: number | undefined;\n\treadonly unknownRate: number;\n\treadonly samples: number;\n}\n\n/**\n * Measure the verifier before reporting any success rate.\n *\n * A mislabelling verifier contaminates every downstream selector and bandit\n * trained on its labels, so its error rates are the prior question.\n */\nexport function verifierQuality(samples: readonly VerifierSample[]): VerifierQuality {\n\tensure(Array.isArray(samples) && samples.length > 0, \"verifier samples must be non-empty\");\n\tlet positives = 0;\n\tlet negatives = 0;\n\tlet falsePositives = 0;\n\tlet falseNegatives = 0;\n\tlet unknowns = 0;\n\tfor (const sample of samples) {\n\t\tif (sample.verdict === \"unknown\") unknowns += 1;\n\t\tif (sample.truth === \"true\") {\n\t\t\tpositives += 1;\n\t\t\tif (sample.verdict === \"false\") falseNegatives += 1;\n\t\t} else {\n\t\t\tnegatives += 1;\n\t\t\tif (sample.verdict === \"true\") falsePositives += 1;\n\t\t}\n\t}\n\treturn {\n\t\tfalsePositiveRate: negatives > 0 ? falsePositives / negatives : undefined,\n\t\tfalseNegativeRate: positives > 0 ? falseNegatives / positives : undefined,\n\t\tunknownRate: unknowns / samples.length,\n\t\tsamples: samples.length,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type MutantClass = "killed-intended" | "survived" | "equivalent" | "invalid-compile" | "environment-failure" | "timeout" | "killed-unintended";
|
|
2
|
+
export interface MutantRecord {
|
|
3
|
+
readonly mutantId: string;
|
|
4
|
+
readonly obligationId: string;
|
|
5
|
+
/** The host classifies the outcome; this module never guesses. */
|
|
6
|
+
readonly classification: MutantClass;
|
|
7
|
+
/** Whether the intended obligation violation was what the check caught. */
|
|
8
|
+
readonly intendedViolation: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface VerifierEvaluation {
|
|
11
|
+
readonly obligationId: string;
|
|
12
|
+
/** D_v over valid non-equivalent mutants; "unknown" when empty. */
|
|
13
|
+
readonly detectionRate: number | "unknown";
|
|
14
|
+
readonly evaluated: number;
|
|
15
|
+
readonly excluded: Readonly<Record<Exclude<MutantClass, "killed-intended" | "survived">, number>>;
|
|
16
|
+
readonly survivingMutantIds: readonly string[];
|
|
17
|
+
readonly blindSpots: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
export declare function evaluateVerifier(obligationId: string, mutants: readonly MutantRecord[], checksValidOnHealthy: boolean): VerifierEvaluation;
|
|
20
|
+
/**
|
|
21
|
+
* §7.4 metamorphic relation: Pre(x,T) ⟹ R(f(x), f(T(x))). The relation must
|
|
22
|
+
* be a declared required property of this program — never a universal rule.
|
|
23
|
+
*/
|
|
24
|
+
export interface MetamorphicRelation {
|
|
25
|
+
readonly relationId: string;
|
|
26
|
+
readonly description: string;
|
|
27
|
+
readonly precondition: string;
|
|
28
|
+
readonly requiredProperty: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function relationApplicable(rel: MetamorphicRelation): boolean;
|
|
31
|
+
/** §10.1 progress key: same key + no new adopted evidence = repetition. */
|
|
32
|
+
export interface ProgressKey {
|
|
33
|
+
readonly goalScope: string;
|
|
34
|
+
readonly candidateFamily: string;
|
|
35
|
+
readonly errorClass: string;
|
|
36
|
+
readonly approach: string;
|
|
37
|
+
readonly checkMethod: string;
|
|
38
|
+
readonly sourceFamily: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function progressKey(k: ProgressKey): string;
|
|
41
|
+
export declare function isStagnant(current: ProgressKey, history: readonly {
|
|
42
|
+
key: string;
|
|
43
|
+
newEvidence: boolean;
|
|
44
|
+
resolvedObligations: number;
|
|
45
|
+
newValidChecks: number;
|
|
46
|
+
}[], maxRepetitions: number): boolean;
|
|
47
|
+
/** §10.2 net strategy-switch score with hysteresis margin. */
|
|
48
|
+
export declare function netSwitchValue(estimatedLossDelta: number, cost: number, switchCost: number): number;
|
|
49
|
+
//# sourceMappingURL=verifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../src/metacognition/verifier.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,WAAW,GACpB,iBAAiB,GACjB,UAAU,GACV,YAAY,GACZ,iBAAiB,GACjB,qBAAqB,GACrB,SAAS,GACT,mBAAmB,CAAC;AACvB,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACpC;AACD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,iBAAiB,GAAG,UAAU,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAClG,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAID,wBAAgB,gBAAgB,CAC/B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,oBAAoB,EAAE,OAAO,GAC3B,kBAAkB,CAsDpB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACnC;AACD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAEpE;AAED,4EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC9B;AACD,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAElD;AACD,wBAAgB,UAAU,CACzB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,EAAE,EAC9G,cAAc,EAAE,MAAM,GACpB,OAAO,CAUT;AAED,+DAA8D;AAC9D,wBAAgB,cAAc,CAAC,kBAAkB,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAKnG","sourcesContent":["/**\n * Algorithm D — meta-verification: checking that a check detects the defect\n * it claims to cover. Spec §7.\n *\n * Obligation-scoped negative controls are evaluated over VALID, non-equivalent\n * mutants only. Environment failures, compile-broken mutants, and timeouts are\n * never counted as semantic detections. An empty denominator is `unknown`,\n * never a score. This is an empirical detection rate for this mutant set,\n * not the probability the code is correct.\n */\nimport { ensure, finite, integer, lexical, member, text, unique } from \"./validation.ts\";\n\nexport type MutantClass =\n\t| \"killed-intended\"\n\t| \"survived\"\n\t| \"equivalent\"\n\t| \"invalid-compile\"\n\t| \"environment-failure\"\n\t| \"timeout\"\n\t| \"killed-unintended\";\nexport interface MutantRecord {\n\treadonly mutantId: string;\n\treadonly obligationId: string;\n\t/** The host classifies the outcome; this module never guesses. */\n\treadonly classification: MutantClass;\n\t/** Whether the intended obligation violation was what the check caught. */\n\treadonly intendedViolation: boolean;\n}\nexport interface VerifierEvaluation {\n\treadonly obligationId: string;\n\t/** D_v over valid non-equivalent mutants; \"unknown\" when empty. */\n\treadonly detectionRate: number | \"unknown\";\n\treadonly evaluated: number;\n\treadonly excluded: Readonly<Record<Exclude<MutantClass, \"killed-intended\" | \"survived\">, number>>;\n\treadonly survivingMutantIds: readonly string[];\n\treadonly blindSpots: readonly string[];\n}\n\nconst MUTANT_BOUND = 1024;\n\nexport function evaluateVerifier(\n\tobligationId: string,\n\tmutants: readonly MutantRecord[],\n\tchecksValidOnHealthy: boolean,\n): VerifierEvaluation {\n\ttext(obligationId, \"obligationId\", 256);\n\tensure(mutants.length <= MUTANT_BOUND, \"too many mutants\");\n\tunique(\n\t\tmutants.map((m) => m.mutantId),\n\t\t\"mutant ids\",\n\t);\n\tconst scoped = mutants.filter((m) => m.obligationId === obligationId);\n\tconst excluded: Record<Exclude<MutantClass, \"killed-intended\" | \"survived\">, number> = {\n\t\tequivalent: 0,\n\t\t\"invalid-compile\": 0,\n\t\t\"environment-failure\": 0,\n\t\ttimeout: 0,\n\t\t\"killed-unintended\": 0,\n\t};\n\tlet detected = 0;\n\tconst survivors: string[] = [];\n\tconst blindSpots: string[] = [];\n\tfor (const m of scoped) {\n\t\tmember(\n\t\t\tm.classification,\n\t\t\t[\n\t\t\t\t\"killed-intended\",\n\t\t\t\t\"survived\",\n\t\t\t\t\"equivalent\",\n\t\t\t\t\"invalid-compile\",\n\t\t\t\t\"environment-failure\",\n\t\t\t\t\"timeout\",\n\t\t\t\t\"killed-unintended\",\n\t\t\t],\n\t\t\t\"mutant classification\",\n\t\t);\n\t\tif (m.classification === \"killed-intended\" && m.intendedViolation) {\n\t\t\tdetected += 1;\n\t\t} else if (m.classification === \"survived\") {\n\t\t\tsurvivors.push(m.mutantId);\n\t\t\tblindSpots.push(`undetected-violation:${m.mutantId}`);\n\t\t} else {\n\t\t\texcluded[m.classification as keyof typeof excluded] += 1;\n\t\t\tif (m.classification === \"invalid-compile\" || m.classification === \"environment-failure\") {\n\t\t\t\tblindSpots.push(`uninformative-mutant:${m.mutantId}`);\n\t\t\t}\n\t\t}\n\t}\n\tif (!checksValidOnHealthy) blindSpots.push(\"check-invalid-on-healthy-candidate\");\n\tconst denominator = detected + survivors.length;\n\treturn {\n\t\tobligationId,\n\t\tdetectionRate: denominator === 0 ? \"unknown\" : detected / denominator,\n\t\tevaluated: denominator,\n\t\texcluded,\n\t\tsurvivingMutantIds: survivors.sort(lexical),\n\t\tblindSpots: blindSpots.sort(lexical),\n\t};\n}\n\n/**\n * §7.4 metamorphic relation: Pre(x,T) ⟹ R(f(x), f(T(x))). The relation must\n * be a declared required property of this program — never a universal rule.\n */\nexport interface MetamorphicRelation {\n\treadonly relationId: string;\n\treadonly description: string;\n\treadonly precondition: string;\n\treadonly requiredProperty: boolean;\n}\nexport function relationApplicable(rel: MetamorphicRelation): boolean {\n\treturn rel.requiredProperty;\n}\n\n/** §10.1 progress key: same key + no new adopted evidence = repetition. */\nexport interface ProgressKey {\n\treadonly goalScope: string;\n\treadonly candidateFamily: string;\n\treadonly errorClass: string;\n\treadonly approach: string;\n\treadonly checkMethod: string;\n\treadonly sourceFamily: string;\n}\nexport function progressKey(k: ProgressKey): string {\n\treturn [k.goalScope, k.candidateFamily, k.errorClass, k.approach, k.checkMethod, k.sourceFamily].join(\"\\u001f\");\n}\nexport function isStagnant(\n\tcurrent: ProgressKey,\n\thistory: readonly { key: string; newEvidence: boolean; resolvedObligations: number; newValidChecks: number }[],\n\tmaxRepetitions: number,\n): boolean {\n\tinteger(maxRepetitions, \"maxRepetitions\", 64);\n\tconst key = progressKey(current);\n\tlet repeats = 0;\n\tfor (const entry of history) {\n\t\tif (entry.key === key && !entry.newEvidence && entry.resolvedObligations === 0 && entry.newValidChecks === 0) {\n\t\t\trepeats += 1;\n\t\t}\n\t}\n\treturn repeats >= maxRepetitions;\n}\n\n/** §10.2 net strategy-switch score with hysteresis margin. */\nexport function netSwitchValue(estimatedLossDelta: number, cost: number, switchCost: number): number {\n\tfinite(estimatedLossDelta, \"estimatedLossDelta\");\n\tfinite(cost, \"cost\");\n\tfinite(switchCost, \"switchCost\");\n\treturn estimatedLossDelta - cost - switchCost;\n}\n"]}
|