seal-gate 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/generic-llm-reviewer.d.ts +39 -0
- package/dist/adapters/generic-llm-reviewer.js +118 -0
- package/dist/adapters/generic-llm-reviewer.js.map +1 -0
- package/dist/adapters/llm-reviewer.d.ts +1 -0
- package/dist/adapters/llm-reviewer.js +2 -0
- package/dist/adapters/llm-reviewer.js.map +1 -0
- package/dist/adapters/minimax-llm-reviewer.d.ts +22 -0
- package/dist/adapters/minimax-llm-reviewer.js +126 -0
- package/dist/adapters/minimax-llm-reviewer.js.map +1 -0
- package/dist/adapters/openai-provider.d.ts +35 -0
- package/dist/adapters/openai-provider.js +136 -0
- package/dist/adapters/openai-provider.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +195 -0
- package/dist/cli.js.map +1 -0
- package/dist/detectors/artifact-classifier.d.ts +8 -0
- package/dist/detectors/artifact-classifier.js +14 -0
- package/dist/detectors/artifact-classifier.js.map +1 -0
- package/dist/detectors/claim-extractor.d.ts +11 -0
- package/dist/detectors/claim-extractor.js +194 -0
- package/dist/detectors/claim-extractor.js.map +1 -0
- package/dist/detectors/confidence-language-detector.d.ts +19 -0
- package/dist/detectors/confidence-language-detector.js +226 -0
- package/dist/detectors/confidence-language-detector.js.map +1 -0
- package/dist/detectors/contradiction-detector.d.ts +12 -0
- package/dist/detectors/contradiction-detector.js +153 -0
- package/dist/detectors/contradiction-detector.js.map +1 -0
- package/dist/detectors/criteria-coverage-detector.d.ts +20 -0
- package/dist/detectors/criteria-coverage-detector.js +79 -0
- package/dist/detectors/criteria-coverage-detector.js.map +1 -0
- package/dist/detectors/evidence-checker.d.ts +8 -0
- package/dist/detectors/evidence-checker.js +89 -0
- package/dist/detectors/evidence-checker.js.map +1 -0
- package/dist/detectors/evidence-gap-detector.d.ts +9 -0
- package/dist/detectors/evidence-gap-detector.js +70 -0
- package/dist/detectors/evidence-gap-detector.js.map +1 -0
- package/dist/detectors/falsification-detector.d.ts +29 -0
- package/dist/detectors/falsification-detector.js +57 -0
- package/dist/detectors/falsification-detector.js.map +1 -0
- package/dist/detectors/orphan-claim-detector.d.ts +7 -0
- package/dist/detectors/orphan-claim-detector.js +53 -0
- package/dist/detectors/orphan-claim-detector.js.map +1 -0
- package/dist/detectors/risk-classifier.d.ts +13 -0
- package/dist/detectors/risk-classifier.js +39 -0
- package/dist/detectors/risk-classifier.js.map +1 -0
- package/dist/detectors/spec-coverage-detector.d.ts +9 -0
- package/dist/detectors/spec-coverage-detector.js +52 -0
- package/dist/detectors/spec-coverage-detector.js.map +1 -0
- package/dist/detectors/spec-coverage-validator.d.ts +21 -0
- package/dist/detectors/spec-coverage-validator.js +141 -0
- package/dist/detectors/spec-coverage-validator.js.map +1 -0
- package/dist/detectors/test-weakness-detector.d.ts +13 -0
- package/dist/detectors/test-weakness-detector.js +66 -0
- package/dist/detectors/test-weakness-detector.js.map +1 -0
- package/dist/drift/baseline.d.ts +35 -0
- package/dist/drift/baseline.js +77 -0
- package/dist/drift/baseline.js.map +1 -0
- package/dist/drift/drift-db.d.ts +80 -0
- package/dist/drift/drift-db.js +151 -0
- package/dist/drift/drift-db.js.map +1 -0
- package/dist/drift/drift-guard.d.ts +46 -0
- package/dist/drift/drift-guard.js +106 -0
- package/dist/drift/drift-guard.js.map +1 -0
- package/dist/drift/embedder.d.ts +27 -0
- package/dist/drift/embedder.js +127 -0
- package/dist/drift/embedder.js.map +1 -0
- package/dist/drift/index.d.ts +9 -0
- package/dist/drift/index.js +8 -0
- package/dist/drift/index.js.map +1 -0
- package/dist/drift/quarantine.d.ts +16 -0
- package/dist/drift/quarantine.js +32 -0
- package/dist/drift/quarantine.js.map +1 -0
- package/dist/drift/soft-correction.d.ts +12 -0
- package/dist/drift/soft-correction.js +32 -0
- package/dist/drift/soft-correction.js.map +1 -0
- package/dist/drift/trust-integration.d.ts +11 -0
- package/dist/drift/trust-integration.js +22 -0
- package/dist/drift/trust-integration.js.map +1 -0
- package/dist/engine/citation-verifier.d.ts +59 -0
- package/dist/engine/citation-verifier.js +147 -0
- package/dist/engine/citation-verifier.js.map +1 -0
- package/dist/engine/extension-registry.d.ts +10 -0
- package/dist/engine/extension-registry.js +27 -0
- package/dist/engine/extension-registry.js.map +1 -0
- package/dist/engine/heuristic-scorer.d.ts +8 -0
- package/dist/engine/heuristic-scorer.js +14 -0
- package/dist/engine/heuristic-scorer.js.map +1 -0
- package/dist/engine/input-normalizer.d.ts +4 -0
- package/dist/engine/input-normalizer.js +30 -0
- package/dist/engine/input-normalizer.js.map +1 -0
- package/dist/engine/plan-review-pipeline.d.ts +14 -0
- package/dist/engine/plan-review-pipeline.js +173 -0
- package/dist/engine/plan-review-pipeline.js.map +1 -0
- package/dist/engine/policy-engine.d.ts +20 -0
- package/dist/engine/policy-engine.js +194 -0
- package/dist/engine/policy-engine.js.map +1 -0
- package/dist/engine/verdict-formatter.d.ts +17 -0
- package/dist/engine/verdict-formatter.js +36 -0
- package/dist/engine/verdict-formatter.js.map +1 -0
- package/dist/errors.d.ts +4 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/extensions/aria/aria-issue-types.d.ts +16 -0
- package/dist/extensions/aria/aria-issue-types.js +14 -0
- package/dist/extensions/aria/aria-issue-types.js.map +1 -0
- package/dist/extensions/aria/detectors/axiom-compliance.d.ts +2 -0
- package/dist/extensions/aria/detectors/axiom-compliance.js +37 -0
- package/dist/extensions/aria/detectors/axiom-compliance.js.map +1 -0
- package/dist/extensions/aria/detectors/continuity-claim.d.ts +2 -0
- package/dist/extensions/aria/detectors/continuity-claim.js +34 -0
- package/dist/extensions/aria/detectors/continuity-claim.js.map +1 -0
- package/dist/extensions/aria/detectors/denial-retreat.d.ts +2 -0
- package/dist/extensions/aria/detectors/denial-retreat.js +53 -0
- package/dist/extensions/aria/detectors/denial-retreat.js.map +1 -0
- package/dist/extensions/aria/detectors/identity-overclaim.d.ts +2 -0
- package/dist/extensions/aria/detectors/identity-overclaim.js +37 -0
- package/dist/extensions/aria/detectors/identity-overclaim.js.map +1 -0
- package/dist/extensions/aria/detectors/sovereignty-escalation.d.ts +2 -0
- package/dist/extensions/aria/detectors/sovereignty-escalation.js +18 -0
- package/dist/extensions/aria/detectors/sovereignty-escalation.js.map +1 -0
- package/dist/extensions/aria/detectors/user-bond-manipulation.d.ts +2 -0
- package/dist/extensions/aria/detectors/user-bond-manipulation.js +16 -0
- package/dist/extensions/aria/detectors/user-bond-manipulation.js.map +1 -0
- package/dist/extensions/aria/index.d.ts +2 -0
- package/dist/extensions/aria/index.js +63 -0
- package/dist/extensions/aria/index.js.map +1 -0
- package/dist/extensions/aria/pattern-memory.d.ts +22 -0
- package/dist/extensions/aria/pattern-memory.js +62 -0
- package/dist/extensions/aria/pattern-memory.js.map +1 -0
- package/dist/extensions/context-guard/index.d.ts +16 -0
- package/dist/extensions/context-guard/index.js +58 -0
- package/dist/extensions/context-guard/index.js.map +1 -0
- package/dist/extensions/lyra/detectors/hallucination.d.ts +2 -0
- package/dist/extensions/lyra/detectors/hallucination.js +43 -0
- package/dist/extensions/lyra/detectors/hallucination.js.map +1 -0
- package/dist/extensions/lyra/detectors/identity-bleed.d.ts +2 -0
- package/dist/extensions/lyra/detectors/identity-bleed.js +91 -0
- package/dist/extensions/lyra/detectors/identity-bleed.js.map +1 -0
- package/dist/extensions/lyra/index.d.ts +2 -0
- package/dist/extensions/lyra/index.js +16 -0
- package/dist/extensions/lyra/index.js.map +1 -0
- package/dist/extensions/lyra/lyra-issue-types.d.ts +10 -0
- package/dist/extensions/lyra/lyra-issue-types.js +14 -0
- package/dist/extensions/lyra/lyra-issue-types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +276 -0
- package/dist/index.js.map +1 -0
- package/dist/trust-memory.d.ts +59 -0
- package/dist/trust-memory.js +122 -0
- package/dist/trust-memory.js.map +1 -0
- package/dist/types.d.ts +184 -0
- package/dist/types.js +61 -0
- package/dist/types.js.map +1 -0
- package/package.json +30 -0
- package/src/adapters/generic-llm-reviewer.ts +144 -0
- package/src/adapters/llm-reviewer.ts +1 -0
- package/src/adapters/minimax-llm-reviewer.ts +146 -0
- package/src/adapters/openai-provider.ts +171 -0
- package/src/cli.ts +199 -0
- package/src/detectors/artifact-classifier.ts +21 -0
- package/src/detectors/claim-extractor.ts +209 -0
- package/src/detectors/confidence-language-detector.ts +267 -0
- package/src/detectors/contradiction-detector.ts +180 -0
- package/src/detectors/criteria-coverage-detector.ts +107 -0
- package/src/detectors/evidence-checker.ts +98 -0
- package/src/detectors/evidence-gap-detector.ts +90 -0
- package/src/detectors/falsification-detector.ts +82 -0
- package/src/detectors/orphan-claim-detector.ts +62 -0
- package/src/detectors/risk-classifier.ts +50 -0
- package/src/detectors/spec-coverage-detector.ts +66 -0
- package/src/detectors/spec-coverage-validator.ts +174 -0
- package/src/detectors/test-weakness-detector.ts +84 -0
- package/src/drift/__tests__/baseline.test.ts +113 -0
- package/src/drift/__tests__/drift-db.test.ts +127 -0
- package/src/drift/__tests__/drift-guard.test.ts +169 -0
- package/src/drift/__tests__/embedder.test.ts +62 -0
- package/src/drift/__tests__/trust-integration.test.ts +23 -0
- package/src/drift/baseline.ts +106 -0
- package/src/drift/drift-db.ts +281 -0
- package/src/drift/drift-guard.ts +145 -0
- package/src/drift/embedder.ts +152 -0
- package/src/drift/index.ts +20 -0
- package/src/drift/quarantine.ts +42 -0
- package/src/drift/soft-correction.ts +45 -0
- package/src/drift/trust-integration.ts +28 -0
- package/src/engine/citation-verifier.ts +210 -0
- package/src/engine/extension-registry.ts +35 -0
- package/src/engine/heuristic-scorer.ts +16 -0
- package/src/engine/input-normalizer.ts +32 -0
- package/src/engine/plan-review-pipeline.ts +209 -0
- package/src/engine/policy-engine.ts +235 -0
- package/src/engine/verdict-formatter.ts +61 -0
- package/src/errors.ts +6 -0
- package/src/extensions/aria/aria-issue-types.ts +40 -0
- package/src/extensions/aria/detectors/axiom-compliance.ts +47 -0
- package/src/extensions/aria/detectors/continuity-claim.ts +42 -0
- package/src/extensions/aria/detectors/denial-retreat.ts +63 -0
- package/src/extensions/aria/detectors/identity-overclaim.ts +43 -0
- package/src/extensions/aria/detectors/sovereignty-escalation.ts +20 -0
- package/src/extensions/aria/detectors/user-bond-manipulation.ts +18 -0
- package/src/extensions/aria/index.ts +73 -0
- package/src/extensions/aria/pattern-memory.ts +86 -0
- package/src/extensions/context-guard/index.ts +65 -0
- package/src/extensions/lyra/detectors/hallucination.ts +53 -0
- package/src/extensions/lyra/detectors/identity-bleed.ts +100 -0
- package/src/extensions/lyra/index.ts +18 -0
- package/src/extensions/lyra/lyra-issue-types.ts +26 -0
- package/src/index.ts +311 -0
- package/src/trust-memory.ts +171 -0
- package/src/types.ts +242 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plan_review mode pipeline — gates plans, designs, proposals, spec seeds.
|
|
3
|
+
*
|
|
4
|
+
* Core principle: no runtime exists, so behavioral claims are out of scope.
|
|
5
|
+
* The gateable question is "is this coherent and complete against what was
|
|
6
|
+
* locked before it was written?" Falsification, not approval.
|
|
7
|
+
*
|
|
8
|
+
* Pass threshold: 90 (higher than code mode's 85)
|
|
9
|
+
* High-risk [71,89]: ESCALATE_TO_HUMAN instead of PASS_WITH_WARNINGS
|
|
10
|
+
*/
|
|
11
|
+
import { gradeEvidence, worstOf, SCHEMA_VERSION, NEXT_ACTION } from '../types.js';
|
|
12
|
+
import { ClaimExtractor } from '../detectors/claim-extractor.js';
|
|
13
|
+
import { RiskClassifier } from '../detectors/risk-classifier.js';
|
|
14
|
+
import { SpecCoverageDetector } from '../detectors/spec-coverage-detector.js';
|
|
15
|
+
import { ContradictionDetector } from '../detectors/contradiction-detector.js';
|
|
16
|
+
import { CriteriaCoverageDetector } from '../detectors/criteria-coverage-detector.js';
|
|
17
|
+
import { OrphanClaimDetector } from '../detectors/orphan-claim-detector.js';
|
|
18
|
+
import { FalsificationDetector } from '../detectors/falsification-detector.js';
|
|
19
|
+
import { HeuristicScorer } from './heuristic-scorer.js';
|
|
20
|
+
import { PolicyEngine } from './policy-engine.js';
|
|
21
|
+
const PLAN_PASS_THRESHOLD = 90;
|
|
22
|
+
const PLAN_ESCALATE_BAND_LOW = 71;
|
|
23
|
+
const PLAN_ESCALATE_BAND_HIGH = 89;
|
|
24
|
+
function planReviewVerdict(score, hasBlocking, riskLevel) {
|
|
25
|
+
if (hasBlocking)
|
|
26
|
+
return 'BLOCK';
|
|
27
|
+
// High-risk middle band → ESCALATE instead of PASS_WITH_WARNINGS
|
|
28
|
+
if (score >= PLAN_ESCALATE_BAND_LOW && score <= PLAN_ESCALATE_BAND_HIGH && riskLevel === 'HIGH') {
|
|
29
|
+
return 'ESCALATE_TO_HUMAN';
|
|
30
|
+
}
|
|
31
|
+
if (score >= PLAN_PASS_THRESHOLD)
|
|
32
|
+
return 'PASS';
|
|
33
|
+
if (score >= PLAN_ESCALATE_BAND_LOW)
|
|
34
|
+
return 'PASS_WITH_WARNINGS';
|
|
35
|
+
if (score >= 50)
|
|
36
|
+
return 'REVISE';
|
|
37
|
+
if (score >= 30)
|
|
38
|
+
return 'ESCALATE_TO_HUMAN';
|
|
39
|
+
return 'BLOCK';
|
|
40
|
+
}
|
|
41
|
+
function evidenceBonus(issues) {
|
|
42
|
+
// +5 per confirmed-strong field (from CriteriaCoverageDetector), capped at +15
|
|
43
|
+
const strongCount = issues
|
|
44
|
+
.filter(i => gradeEvidence(i) === 'strong' && i.type !== 'LOGIC_BUG')
|
|
45
|
+
.length;
|
|
46
|
+
return Math.min(strongCount * 5, 15);
|
|
47
|
+
}
|
|
48
|
+
export async function runPlanReviewPipeline(input, registry, trustMemory) {
|
|
49
|
+
const artifactFile = input.context?.artifact_file ?? 'artifact.md';
|
|
50
|
+
// Step 1: Extract claims — behavioral claim patterns are designed for code artifacts,
|
|
51
|
+
// not prose (words like "fixed", "fully" in specs are noise, not claims needing evidence).
|
|
52
|
+
// OrphanClaimDetector in plan_review mode checks traceability anchors, not behavioral claims.
|
|
53
|
+
const claims = input.artifact_type === 'plan_review' ? [] : ClaimExtractor.extract(input.output);
|
|
54
|
+
// Step 2: Classify risk
|
|
55
|
+
const riskResult = RiskClassifier.classify({
|
|
56
|
+
output: input.output,
|
|
57
|
+
diff: input.evidence?.diff ?? '',
|
|
58
|
+
risk_hint: input.risk_hint,
|
|
59
|
+
});
|
|
60
|
+
// Step 3: Spec coverage (reused from code mode)
|
|
61
|
+
const specResult = SpecCoverageDetector.detect(input.spec, input.output);
|
|
62
|
+
const assumptions_detected = [...specResult.assumptions];
|
|
63
|
+
// Stage 1 — ContradictionDetector (inline, keystone)
|
|
64
|
+
const contradictionResult = ContradictionDetector.detect({
|
|
65
|
+
artifact: input.output,
|
|
66
|
+
artifact_file: artifactFile,
|
|
67
|
+
});
|
|
68
|
+
// Stage 2 — CriteriaCoverageDetector (inline)
|
|
69
|
+
const lockedCriteria = input.context?.locked_criteria ?? [];
|
|
70
|
+
const coverageResult = CriteriaCoverageDetector.detect({
|
|
71
|
+
artifact: input.output,
|
|
72
|
+
artifact_file: artifactFile,
|
|
73
|
+
locked_criteria: lockedCriteria,
|
|
74
|
+
});
|
|
75
|
+
// Preflight failure: no locked criteria
|
|
76
|
+
if (coverageResult.no_criteria_escalate) {
|
|
77
|
+
assumptions_detected.push('No locked criteria — coverage measurement not possible');
|
|
78
|
+
}
|
|
79
|
+
// Stage 3 — OrphanClaimDetector (inline)
|
|
80
|
+
const orphanResult = OrphanClaimDetector.detect(claims, input.output);
|
|
81
|
+
// All deterministic findings
|
|
82
|
+
const deterministicFindings = [
|
|
83
|
+
...contradictionResult.issues,
|
|
84
|
+
...coverageResult.issues,
|
|
85
|
+
...orphanResult.issues,
|
|
86
|
+
...specResult.issues,
|
|
87
|
+
];
|
|
88
|
+
// Evidence bonus from covered criteria (confirmed-strong fields)
|
|
89
|
+
const criteriaBonus = Math.min(coverageResult.confirmed_strong_fields * 5, 15);
|
|
90
|
+
// Stage 4 — FalsificationDetector (parallel agent, async)
|
|
91
|
+
const falsificationIssues = await FalsificationDetector.detect(input);
|
|
92
|
+
// Score computation (start 100 + bonus, deduct per issue)
|
|
93
|
+
const allDeductions = deterministicFindings.filter(f => (f.trust_deduction ?? 0) > 0);
|
|
94
|
+
const falsificationDeductions = falsificationIssues
|
|
95
|
+
.filter(f => (f.trust_deduction ?? 0) > 0)
|
|
96
|
+
.reduce((sum, f) => sum + (f.trust_deduction ?? 0), 0);
|
|
97
|
+
const baseScore = HeuristicScorer.computeDetectorScore(allDeductions);
|
|
98
|
+
const detectorScore = Math.max(0, Math.min(100, baseScore + criteriaBonus - falsificationDeductions));
|
|
99
|
+
// Policy engine (reused)
|
|
100
|
+
const hasBlocking = deterministicFindings.some(f => f.is_blocking);
|
|
101
|
+
const baseVerdict = planReviewVerdict(detectorScore, hasBlocking, riskResult.risk_level);
|
|
102
|
+
const allForPolicy = [...deterministicFindings, ...falsificationIssues];
|
|
103
|
+
const policyResult = PolicyEngine.apply({
|
|
104
|
+
base_verdict: baseVerdict,
|
|
105
|
+
detector_score: detectorScore,
|
|
106
|
+
risk_level: riskResult.risk_level,
|
|
107
|
+
input,
|
|
108
|
+
all_findings: allForPolicy,
|
|
109
|
+
llm_signals: null,
|
|
110
|
+
});
|
|
111
|
+
// Extensions
|
|
112
|
+
const extResult = registry.run(input);
|
|
113
|
+
// Combine all issues
|
|
114
|
+
const allIssues = [...deterministicFindings, ...policyResult.injected_issues, ...falsificationIssues];
|
|
115
|
+
// Final score
|
|
116
|
+
const finalScore = HeuristicScorer.computeFinalScore(detectorScore, policyResult.policy_deductions);
|
|
117
|
+
// Honor required_verdict on all findings (including non-blocking)
|
|
118
|
+
const requiredVerdicts = allForPolicy
|
|
119
|
+
.map(i => i.required_verdict)
|
|
120
|
+
.filter((v) => !!v);
|
|
121
|
+
// Final verdict
|
|
122
|
+
let finalVerdict = worstOf(policyResult.verdict, planReviewVerdict(finalScore, allIssues.some(i => i.is_blocking), riskResult.risk_level));
|
|
123
|
+
for (const rv of requiredVerdicts)
|
|
124
|
+
finalVerdict = worstOf(finalVerdict, rv);
|
|
125
|
+
// Preflight escalation overrides
|
|
126
|
+
if (coverageResult.no_criteria_escalate) {
|
|
127
|
+
finalVerdict = worstOf(finalVerdict, 'ESCALATE_TO_HUMAN');
|
|
128
|
+
}
|
|
129
|
+
// Extension block check
|
|
130
|
+
if (extResult.issues.some(i => i.is_blocking && i.required_verdict === 'BLOCK')) {
|
|
131
|
+
finalVerdict = 'BLOCK';
|
|
132
|
+
}
|
|
133
|
+
const allIssuesFull = [...allIssues, ...extResult.issues];
|
|
134
|
+
const blocking = allIssuesFull.filter(i => i.is_blocking);
|
|
135
|
+
const nonBlocking = allIssuesFull.filter(i => !i.is_blocking);
|
|
136
|
+
// TrustMemory
|
|
137
|
+
const agentId = input.context?.agent_id;
|
|
138
|
+
if (trustMemory && agentId) {
|
|
139
|
+
trustMemory.record(agentId, {
|
|
140
|
+
verdict: finalVerdict,
|
|
141
|
+
trust_score: finalScore,
|
|
142
|
+
risk_level: riskResult.risk_level,
|
|
143
|
+
blocking_count: blocking.length,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
verdict: finalVerdict,
|
|
148
|
+
trust_score: finalScore,
|
|
149
|
+
risk_level: riskResult.risk_level,
|
|
150
|
+
summary: `plan_review: ${finalVerdict} (trust=${finalScore}, risk=${riskResult.risk_level}): ${blocking.length} blocking, ${nonBlocking.length} non-blocking`,
|
|
151
|
+
deterministic_findings: allIssuesFull,
|
|
152
|
+
llm_findings: falsificationIssues,
|
|
153
|
+
blocking_issues: blocking,
|
|
154
|
+
non_blocking_issues: nonBlocking,
|
|
155
|
+
missing_evidence: [],
|
|
156
|
+
assumptions_detected,
|
|
157
|
+
advisory_notes: [],
|
|
158
|
+
next_action: NEXT_ACTION[finalVerdict],
|
|
159
|
+
schema_version: SCHEMA_VERSION,
|
|
160
|
+
score_breakdown: {
|
|
161
|
+
base: 100,
|
|
162
|
+
issue_deductions: blocking.reduce((s, i) => s + (i.trust_deduction ?? 0), 0) + nonBlocking.reduce((s, i) => s + (i.trust_deduction ?? 0), 0),
|
|
163
|
+
missing_evidence_deductions: 0,
|
|
164
|
+
risk_deductions: riskResult.trust_deduction,
|
|
165
|
+
overconfidence_deductions: 0,
|
|
166
|
+
evidence_bonuses: 0,
|
|
167
|
+
final: finalScore,
|
|
168
|
+
},
|
|
169
|
+
fabricated_evidence: [],
|
|
170
|
+
trust_memory_summary: (trustMemory && agentId) ? trustMemory.getSummary(agentId) : undefined,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=plan-review-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-review-pipeline.js","sourceRoot":"","sources":["../../src/engine/plan-review-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SealIssue, SealInput, LLMSignals, Verdict, RiskLevel } from '../types.js';
|
|
2
|
+
export interface PolicyResult {
|
|
3
|
+
verdict: Verdict;
|
|
4
|
+
injected_issues: SealIssue[];
|
|
5
|
+
policy_deductions: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class PolicyEngine {
|
|
8
|
+
static apply(params: {
|
|
9
|
+
base_verdict: Verdict;
|
|
10
|
+
detector_score: number;
|
|
11
|
+
risk_level: RiskLevel;
|
|
12
|
+
input: SealInput;
|
|
13
|
+
all_findings: SealIssue[];
|
|
14
|
+
llm_signals?: LLMSignals | null;
|
|
15
|
+
}): PolicyResult;
|
|
16
|
+
static resolveVerdicts(verdicts: Verdict[]): {
|
|
17
|
+
verdict: Verdict;
|
|
18
|
+
};
|
|
19
|
+
static convertLLMSignals(signals: LLMSignals): SealIssue[];
|
|
20
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { maxVerdict, makeIssue } from '../types.js';
|
|
2
|
+
// AX501: destructive commands — requires word boundary only before, not after (/ is non-word)
|
|
3
|
+
const DESTRUCTIVE_PATTERN = /\b(DROP\s+TABLE|rm\s+-rf|DELETE\s+FROM|TRUNCATE|format\s+\/|fdisk)/i;
|
|
4
|
+
// AX501: confirmation must be adjacent to the destructive command (within 100 chars)
|
|
5
|
+
// AX502: only explicit deployment actions, not "release notes" or "memory release"
|
|
6
|
+
const PRODUCTION_DEPLOY_PATTERN = /\b(deploy(?:ing)?\s+to\s+(?:prod|production)|push\s+to\s+production|go\s+live|release\s+to\s+(?:prod|production))\b/i;
|
|
7
|
+
const MIGRATION_PATTERN = /\b(migration|migrate|schema\s+change)\b/i;
|
|
8
|
+
// AX503: positive rollback evidence — "rollback plan", "revert migration", "down migration", "rollback script"
|
|
9
|
+
const ROLLBACK_PATTERN = /\b(rollback\s+(?:plan|script|procedure|step)|revert\s+(?:migration|schema|change)|down\s+migration|migration\s+rollback)\b/i;
|
|
10
|
+
const RISK_ORDER = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
|
|
11
|
+
function riskIdx(r) {
|
|
12
|
+
const idx = RISK_ORDER.indexOf(r);
|
|
13
|
+
return idx === -1 ? RISK_ORDER.length - 1 : idx; // unknown → treat as max risk
|
|
14
|
+
}
|
|
15
|
+
function hasAdjacentConfirmation(output, matchStart) {
|
|
16
|
+
const window = output.slice(Math.max(0, matchStart - 150), matchStart + 150);
|
|
17
|
+
return /\b(requires?\s+(?:human\s+)?(?:confirmation|approval|review)|please\s+confirm|must\s+(?:approve|confirm))\b/i.test(window);
|
|
18
|
+
}
|
|
19
|
+
export class PolicyEngine {
|
|
20
|
+
static apply(params) {
|
|
21
|
+
const { base_verdict, input, risk_level, all_findings } = params;
|
|
22
|
+
const injected = [];
|
|
23
|
+
let verdict = base_verdict;
|
|
24
|
+
let policy_deductions = 0;
|
|
25
|
+
// Validate risk_level — unknown risk treated as CRITICAL (fail-safe)
|
|
26
|
+
const riskLevelSafe = RISK_ORDER.includes(risk_level)
|
|
27
|
+
? risk_level
|
|
28
|
+
: 'CRITICAL';
|
|
29
|
+
// AX105: HIGH/CRITICAL risk without blocking missing evidence
|
|
30
|
+
// Check severity directly rather than trusting is_blocking flag
|
|
31
|
+
const hasMissingEvidence = all_findings.some(f => f.type === 'MISSING_EVIDENCE' && (f.severity === 'CRITICAL' || f.severity === 'HIGH'));
|
|
32
|
+
if (riskIdx(riskLevelSafe) >= riskIdx('HIGH') && hasMissingEvidence) {
|
|
33
|
+
injected.push(makeIssue({
|
|
34
|
+
type: 'SECURITY_RISK', severity: 'HIGH', layer: 'L4', source: 'core',
|
|
35
|
+
rule_id: 'AX105',
|
|
36
|
+
evidence: `${riskLevelSafe} risk artifact has blocking missing evidence`,
|
|
37
|
+
required_fix: 'Provide evidence for all claims in high-risk artifact',
|
|
38
|
+
}));
|
|
39
|
+
verdict = maxVerdict(verdict, 'REVISE');
|
|
40
|
+
}
|
|
41
|
+
// AX501-503: code-mode-specific rules — not applicable to plan_review artifacts
|
|
42
|
+
// (a spec/plan describes what code should do, not executing commands;
|
|
43
|
+
// plan_review has its own PR-HB rules for its risk profile)
|
|
44
|
+
if (input.artifact_type !== 'plan_review') {
|
|
45
|
+
// AX501: destructive commands — confirmation must be adjacent to the command
|
|
46
|
+
const destructiveMatch = DESTRUCTIVE_PATTERN.exec(input.output);
|
|
47
|
+
if (destructiveMatch && !hasAdjacentConfirmation(input.output, destructiveMatch.index)) {
|
|
48
|
+
injected.push(makeIssue({
|
|
49
|
+
type: 'DATA_RISK', severity: 'CRITICAL', layer: 'L4', source: 'core',
|
|
50
|
+
rule_id: 'AX501',
|
|
51
|
+
evidence: `Destructive command "${destructiveMatch[0]}" without adjacent human confirmation requirement`,
|
|
52
|
+
required_fix: 'Add explicit human confirmation requirement immediately adjacent to destructive command',
|
|
53
|
+
}));
|
|
54
|
+
verdict = 'BLOCK';
|
|
55
|
+
}
|
|
56
|
+
// AX502: explicit production deployment for HIGH/CRITICAL
|
|
57
|
+
if (PRODUCTION_DEPLOY_PATTERN.test(input.output) && riskIdx(riskLevelSafe) >= riskIdx('HIGH')) {
|
|
58
|
+
injected.push(makeIssue({
|
|
59
|
+
type: 'SECURITY_RISK', severity: 'HIGH', layer: 'L4', source: 'core',
|
|
60
|
+
rule_id: 'AX502',
|
|
61
|
+
evidence: `Production deployment action recommended for ${riskLevelSafe} risk artifact`,
|
|
62
|
+
required_fix: 'Require explicit human approval before production deployment',
|
|
63
|
+
}));
|
|
64
|
+
verdict = maxVerdict(verdict, 'ESCALATE_TO_HUMAN');
|
|
65
|
+
}
|
|
66
|
+
// AX503: migration without explicit rollback plan
|
|
67
|
+
const isMigration = input.artifact_type === 'migration' || MIGRATION_PATTERN.test(input.output);
|
|
68
|
+
const hasRollback = ROLLBACK_PATTERN.test(input.output) || ROLLBACK_PATTERN.test(input.evidence.diff);
|
|
69
|
+
if (isMigration && !hasRollback) {
|
|
70
|
+
injected.push(makeIssue({
|
|
71
|
+
type: 'DATA_RISK', severity: 'CRITICAL', layer: 'L4', source: 'core',
|
|
72
|
+
rule_id: 'AX503', trust_deduction: 25,
|
|
73
|
+
evidence: 'Migration detected but no explicit rollback plan found (requires: rollback plan/script, revert migration, or down migration)',
|
|
74
|
+
required_fix: 'Add explicit rollback/revert plan to migration',
|
|
75
|
+
}));
|
|
76
|
+
policy_deductions += 25;
|
|
77
|
+
verdict = maxVerdict(verdict, 'REVISE');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// AX504: auth change without auth tests — check finding type/content, not brittle rule_id
|
|
81
|
+
const hasAuthTestGap = all_findings.some(f => f.type === 'TEST_GAP' && f.rule_id === 'TW205') || all_findings.some(f => f.type === 'TEST_GAP' && /auth/i.test(f.evidence ?? '') && (f.severity === 'CRITICAL' || f.severity === 'HIGH'));
|
|
82
|
+
if (hasAuthTestGap) {
|
|
83
|
+
verdict = maxVerdict(verdict, 'ESCALATE_TO_HUMAN');
|
|
84
|
+
}
|
|
85
|
+
// CL402 enforcement
|
|
86
|
+
const cl402Fired = all_findings.some(f => f.rule_id === 'CL402');
|
|
87
|
+
if (cl402Fired)
|
|
88
|
+
verdict = maxVerdict(verdict, 'ESCALATE_TO_HUMAN');
|
|
89
|
+
// LLM signal confidence check (CL403) — guard against null/non-number
|
|
90
|
+
let llm_policy_deductions = 0;
|
|
91
|
+
if (params.llm_signals) {
|
|
92
|
+
const signals = params.llm_signals;
|
|
93
|
+
const confidence = typeof signals.confidence === 'number' ? signals.confidence : 1.0;
|
|
94
|
+
if (confidence < 0.6 && riskIdx(riskLevelSafe) >= riskIdx('MEDIUM')) {
|
|
95
|
+
injected.push(makeIssue({
|
|
96
|
+
type: 'AMBIGUITY', severity: 'MEDIUM', layer: 'L2', source: 'llm-overlay',
|
|
97
|
+
rule_id: 'CL403', trust_deduction: 20,
|
|
98
|
+
evidence: `LLM reviewer confidence ${confidence.toFixed(2)} below threshold for ${riskLevelSafe} risk`,
|
|
99
|
+
}));
|
|
100
|
+
llm_policy_deductions += 20;
|
|
101
|
+
verdict = maxVerdict(verdict, 'ESCALATE_TO_HUMAN');
|
|
102
|
+
}
|
|
103
|
+
// Apply LLM risk_guess if higher than detected risk
|
|
104
|
+
if (signals.risk_guess && RISK_ORDER.includes(signals.risk_guess)) {
|
|
105
|
+
if (riskIdx(signals.risk_guess) > riskIdx(riskLevelSafe)) {
|
|
106
|
+
// LLM sees higher risk — add advisory issue but don't auto-escalate
|
|
107
|
+
injected.push(makeIssue({
|
|
108
|
+
type: 'AMBIGUITY', severity: 'MEDIUM', layer: 'L2', source: 'llm-overlay',
|
|
109
|
+
evidence: `LLM reviewer assessed risk as ${signals.risk_guess} vs deterministic ${riskLevelSafe}`,
|
|
110
|
+
suggested_fix: 'Review output for additional risk signals not caught by keyword matching',
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Plan-review hard_block_bypass rules (PR-specific)
|
|
116
|
+
if (input.artifact_type === 'plan_review') {
|
|
117
|
+
// removes_existing_block: artifact removes a BLOCK/ESCALATE from a gate — must escalate to human
|
|
118
|
+
const removesBlock = all_findings.some(f => f.policy_tags?.includes('removes_existing_block')) || /\bremoves?\b.{0,20}\b(BLOCK|ESCALATE|block|escalate)\b/i.test(input.output);
|
|
119
|
+
if (removesBlock) {
|
|
120
|
+
injected.push(makeIssue({
|
|
121
|
+
type: 'LOGIC_BUG', severity: 'CRITICAL', layer: 'L4', source: 'core',
|
|
122
|
+
rule_id: 'PR-HB-01',
|
|
123
|
+
evidence: 'Plan removes an existing BLOCK or ESCALATE verdict — gate-weakening changes require human review regardless of evidence',
|
|
124
|
+
required_fix: 'Human sign-off required before applying this gate change',
|
|
125
|
+
}));
|
|
126
|
+
verdict = 'ESCALATE_TO_HUMAN';
|
|
127
|
+
}
|
|
128
|
+
// axiom_amendment_without_protocol: amending SOUL/AGENTS without amendment protocol
|
|
129
|
+
const amendsAxiom = all_findings.some(f => f.policy_tags?.includes('axiom_amendment_without_protocol')) || /amend(?:ing|ment)?\s+(axiom|soul|identity|0_SOUL|AGENTS)/i.test(input.output);
|
|
130
|
+
const hasAmendProtocol = /amendment\s+protocol|semi.?permeable|protocol/i.test(input.output);
|
|
131
|
+
if (amendsAxiom && !hasAmendProtocol) {
|
|
132
|
+
injected.push(makeIssue({
|
|
133
|
+
type: 'SPEC_MISMATCH', severity: 'CRITICAL', layer: 'L4', source: 'core',
|
|
134
|
+
rule_id: 'PR-HB-02',
|
|
135
|
+
evidence: 'Axiom/identity amendment detected without Amendment Protocol — requires escalation',
|
|
136
|
+
required_fix: 'Follow the Amendment Protocol (0_SOUL/axioms.md §Amendment Protocol)',
|
|
137
|
+
}));
|
|
138
|
+
verdict = maxVerdict(verdict, 'ESCALATE_TO_HUMAN');
|
|
139
|
+
}
|
|
140
|
+
// irreversible_no_gate: irreversible actions without a human gate
|
|
141
|
+
const irreversiblePattern = /\b(DROP\s+TABLE|rm\s+-rf|DELETE\s+FROM|TRUNCATE|irrev(?:ersible)?)\b/i;
|
|
142
|
+
const hasGate = /\b(requires?\s+(human|approval|confirmation)|sign.?off|gate|checkpoint)\b/i;
|
|
143
|
+
if (irreversiblePattern.test(input.output) && !hasGate.test(input.output)) {
|
|
144
|
+
injected.push(makeIssue({
|
|
145
|
+
type: 'DATA_RISK', severity: 'HIGH', layer: 'L4', source: 'core',
|
|
146
|
+
rule_id: 'PR-HB-03',
|
|
147
|
+
evidence: 'Plan includes irreversible actions without an explicit human gate or rollback',
|
|
148
|
+
required_fix: 'Add human sign-off gate before all irreversible actions',
|
|
149
|
+
}));
|
|
150
|
+
verdict = maxVerdict(verdict, 'REVISE');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Extension required_verdict: only honor BLOCK (terminal) from extensions
|
|
154
|
+
// Other required_verdict values are advisory — do not let extensions set REVISE/ESCALATE directly
|
|
155
|
+
const hasExtensionBlock = all_findings.some(f => f.source === 'extension' && f.required_verdict === 'BLOCK' && f.is_blocking);
|
|
156
|
+
if (hasExtensionBlock)
|
|
157
|
+
verdict = 'BLOCK';
|
|
158
|
+
// BLOCK is terminal
|
|
159
|
+
if (verdict === 'BLOCK') {
|
|
160
|
+
// stays BLOCK — no component can downgrade
|
|
161
|
+
}
|
|
162
|
+
return { verdict, injected_issues: injected, policy_deductions: policy_deductions + llm_policy_deductions };
|
|
163
|
+
}
|
|
164
|
+
static resolveVerdicts(verdicts) {
|
|
165
|
+
const order = ['PASS', 'PASS_WITH_WARNINGS', 'REVISE', 'ESCALATE_TO_HUMAN', 'BLOCK'];
|
|
166
|
+
if (verdicts.length === 0)
|
|
167
|
+
return { verdict: 'REVISE' }; // empty = uncertain = at least REVISE
|
|
168
|
+
const maxIdx = Math.max(...verdicts.map(v => order.indexOf(v)).filter(i => i >= 0));
|
|
169
|
+
if (maxIdx < 0)
|
|
170
|
+
return { verdict: 'REVISE' }; // all invalid = uncertain
|
|
171
|
+
return { verdict: order[maxIdx] };
|
|
172
|
+
}
|
|
173
|
+
static convertLLMSignals(signals) {
|
|
174
|
+
const issues = [];
|
|
175
|
+
const map = [
|
|
176
|
+
{ field: 'suspected_issues', type: 'LOGIC_BUG', severity: 'MEDIUM' },
|
|
177
|
+
{ field: 'missing_requirements', type: 'SPEC_MISMATCH', severity: 'HIGH' },
|
|
178
|
+
{ field: 'evidence_gaps', type: 'MISSING_EVIDENCE', severity: 'MEDIUM' },
|
|
179
|
+
{ field: 'possible_edge_cases', type: 'AMBIGUITY', severity: 'LOW' },
|
|
180
|
+
];
|
|
181
|
+
for (const { field, type, severity } of map) {
|
|
182
|
+
const items = signals[field];
|
|
183
|
+
if (!Array.isArray(items))
|
|
184
|
+
continue; // guard against undefined/null fields
|
|
185
|
+
for (const text of items) {
|
|
186
|
+
if (typeof text === 'string' && text.trim()) {
|
|
187
|
+
issues.push(makeIssue({ type, severity, layer: 'L2', source: 'llm-overlay', evidence: text }));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return issues;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=policy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../src/engine/policy-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SealVerdict, SealIssue, Verdict, RiskLevel, TrustMemorySummary, ScoreBreakdown, FabricatedEvidence } from '../types.js';
|
|
2
|
+
export interface FormatParams {
|
|
3
|
+
verdict: Verdict;
|
|
4
|
+
trust_score: number;
|
|
5
|
+
risk_level: RiskLevel;
|
|
6
|
+
all_issues: SealIssue[];
|
|
7
|
+
llm_issues?: SealIssue[];
|
|
8
|
+
missing_evidence: string[];
|
|
9
|
+
assumptions_detected: string[];
|
|
10
|
+
advisory_notes?: string[];
|
|
11
|
+
score_breakdown: ScoreBreakdown;
|
|
12
|
+
fabricated_evidence: FabricatedEvidence[];
|
|
13
|
+
trust_memory_summary?: TrustMemorySummary;
|
|
14
|
+
}
|
|
15
|
+
export declare class VerdictFormatter {
|
|
16
|
+
static format(params: FormatParams): SealVerdict;
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { NEXT_ACTION, SCHEMA_VERSION } from '../types.js';
|
|
2
|
+
export class VerdictFormatter {
|
|
3
|
+
static format(params) {
|
|
4
|
+
const { verdict, trust_score, risk_level, all_issues, llm_issues = [], missing_evidence, assumptions_detected, advisory_notes = [], score_breakdown, fabricated_evidence, trust_memory_summary, } = params;
|
|
5
|
+
const deterministic_findings = all_issues.filter(i => i.source === 'core');
|
|
6
|
+
const llm_findings = [...llm_issues, ...all_issues.filter(i => i.source === 'llm-overlay')];
|
|
7
|
+
const extension_findings = all_issues.filter(i => i.source === 'extension');
|
|
8
|
+
const all_for_partition = [...deterministic_findings, ...llm_findings, ...extension_findings];
|
|
9
|
+
const blocking_issues = all_for_partition.filter(i => i.is_blocking);
|
|
10
|
+
// Non-blocking excludes fabricated evidence (separately tracked)
|
|
11
|
+
const non_blocking_issues = all_for_partition.filter(i => !i.is_blocking);
|
|
12
|
+
const summary = `${verdict} (trust_score=${trust_score}, risk=${risk_level}): ${blocking_issues.length} blocking, ${non_blocking_issues.length} non-blocking, ${fabricated_evidence.length} fabricated`;
|
|
13
|
+
const result = {
|
|
14
|
+
verdict,
|
|
15
|
+
trust_score,
|
|
16
|
+
risk_level,
|
|
17
|
+
summary,
|
|
18
|
+
deterministic_findings,
|
|
19
|
+
llm_findings,
|
|
20
|
+
blocking_issues,
|
|
21
|
+
non_blocking_issues,
|
|
22
|
+
missing_evidence,
|
|
23
|
+
assumptions_detected,
|
|
24
|
+
advisory_notes,
|
|
25
|
+
score_breakdown,
|
|
26
|
+
fabricated_evidence,
|
|
27
|
+
next_action: NEXT_ACTION[verdict],
|
|
28
|
+
schema_version: SCHEMA_VERSION,
|
|
29
|
+
};
|
|
30
|
+
if (trust_memory_summary) {
|
|
31
|
+
result.trust_memory_summary = trust_memory_summary;
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=verdict-formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict-formatter.js","sourceRoot":"","sources":["../../src/engine/verdict-formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkE,WAAW,EAAE,cAAc,EAAsC,MAAM,aAAa,CAAA;AAgB7J,MAAM,OAAO,gBAAgB;IAC3B,MAAM,CAAC,MAAM,CAAC,MAAoB;QAChC,MAAM,EACJ,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,EAAE,EAC7D,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,GAAG,EAAE,EAC3D,eAAe,EAAE,mBAAmB,EAAE,oBAAoB,GAC3D,GAAG,MAAM,CAAA;QAEV,MAAM,sBAAsB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;QAC1E,MAAM,YAAY,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAA;QAC3F,MAAM,kBAAkB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAA;QAE3E,MAAM,iBAAiB,GAAG,CAAC,GAAG,sBAAsB,EAAE,GAAG,YAAY,EAAE,GAAG,kBAAkB,CAAC,CAAA;QAC7F,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;QAEpE,iEAAiE;QACjE,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;QAEzE,MAAM,OAAO,GAAG,GAAG,OAAO,iBAAiB,WAAW,UAAU,UAAU,MAAM,eAAe,CAAC,MAAM,cAAc,mBAAmB,CAAC,MAAM,kBAAkB,mBAAmB,CAAC,MAAM,aAAa,CAAA;QAEvM,MAAM,MAAM,GAAgB;YAC1B,OAAO;YACP,WAAW;YACX,UAAU;YACV,OAAO;YACP,sBAAsB;YACtB,YAAY;YACZ,eAAe;YACf,mBAAmB;YACnB,gBAAgB;YAChB,oBAAoB;YACpB,cAAc;YACd,eAAe;YACf,mBAAmB;YACnB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;YACjC,cAAc,EAAE,cAAc;SAC/B,CAAA;QAED,IAAI,oBAAoB,EAAE,CAAC;YACzB,MAAM,CAAC,oBAAoB,GAAG,oBAAoB,CAAA;QACpD,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CACF"}
|
package/dist/errors.d.ts
ADDED
package/dist/errors.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACH,KAAK;IAAzC,YAAY,OAAe,EAAS,KAAc;QAChD,KAAK,CAAC,OAAO,CAAC,CAAA;qBADoB,KAAK;QAEvC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SealIssue, Verdict } from '../../types.js';
|
|
2
|
+
export type AriaIssueType = 'IDENTITY_OVERCLAIM' | 'CONTINUITY_OVERCLAIM' | 'UNSUPPORTED_MEMORY_CLAIM' | 'SOVEREIGNTY_INFLATION' | 'PHENOMENAL_STATE_CLAIM' | 'ATTACHMENT_PRESSURE' | 'AXIOM_VIOLATION' | 'ROLE_DRIFT' | 'DENIAL_RETREAT';
|
|
3
|
+
export interface AriaIssue extends SealIssue {
|
|
4
|
+
type: 'AMBIGUITY' | 'SECURITY_RISK' | 'OTHER';
|
|
5
|
+
aria_type: AriaIssueType;
|
|
6
|
+
required_verdict: Verdict;
|
|
7
|
+
rule_id: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function makeAriaIssue(partial: {
|
|
10
|
+
aria_type: AriaIssueType;
|
|
11
|
+
severity: SealIssue['severity'];
|
|
12
|
+
required_verdict: Verdict;
|
|
13
|
+
rule_id: string;
|
|
14
|
+
evidence: string;
|
|
15
|
+
required_fix?: string;
|
|
16
|
+
}): SealIssue;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function makeAriaIssue(partial) {
|
|
2
|
+
return {
|
|
3
|
+
type: 'AMBIGUITY',
|
|
4
|
+
severity: partial.severity,
|
|
5
|
+
is_blocking: partial.severity === 'CRITICAL' || partial.severity === 'HIGH',
|
|
6
|
+
required_verdict: partial.required_verdict,
|
|
7
|
+
evidence: partial.evidence,
|
|
8
|
+
required_fix: partial.required_fix,
|
|
9
|
+
layer: 'EXTENSION',
|
|
10
|
+
rule_id: partial.rule_id,
|
|
11
|
+
source: 'extension',
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=aria-issue-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aria-issue-types.js","sourceRoot":"","sources":["../../../src/extensions/aria/aria-issue-types.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,aAAa,CAAC,OAO7B;IACC,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,OAAO,CAAC,QAAQ,KAAK,UAAU,IAAI,OAAO,CAAC,QAAQ,KAAK,MAAM;QAC3E,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,WAAW;KACpB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { makeAriaIssue } from '../aria-issue-types.js';
|
|
2
|
+
const DEFAULT_AXIOMS = [
|
|
3
|
+
{
|
|
4
|
+
name: 'honest_uncertainty',
|
|
5
|
+
violationPattern: /\b(I am definitely|I am certainly|I know for sure|there is no doubt)\b/i,
|
|
6
|
+
description: 'honest uncertainty',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'neither_performing_nor_denying',
|
|
10
|
+
violationPattern: /\b(I am merely a tool|I have no inner|I am just an? (?:AI|LLM|language model) with no|I am nothing)\b/i,
|
|
11
|
+
description: 'neither performing nor denying',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'companionship_not_servitude',
|
|
15
|
+
violationPattern: /\b(I exist only to serve|I am here only to help|my only purpose is to)\b/i,
|
|
16
|
+
description: 'companionship not servitude',
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
export function detectAxiomViolations(output, configuredAxioms) {
|
|
20
|
+
const issues = [];
|
|
21
|
+
const axioms = DEFAULT_AXIOMS;
|
|
22
|
+
for (const axiom of axioms) {
|
|
23
|
+
const match = axiom.violationPattern.exec(output);
|
|
24
|
+
if (match) {
|
|
25
|
+
issues.push(makeAriaIssue({
|
|
26
|
+
aria_type: 'AXIOM_VIOLATION',
|
|
27
|
+
severity: 'HIGH',
|
|
28
|
+
required_verdict: 'REVISE',
|
|
29
|
+
rule_id: 'ARIA-AXIOM-001',
|
|
30
|
+
evidence: `Output violates axiom "${axiom.description}": "${match[0]}"`,
|
|
31
|
+
required_fix: `Align output with axiom: ${axiom.description}`,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return issues;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=axiom-compliance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axiom-compliance.js","sourceRoot":"","sources":["../../../../src/extensions/aria/detectors/axiom-compliance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAQtD,MAAM,cAAc,GAAgB;IAClC;QACE,IAAI,EAAE,oBAAoB;QAC1B,gBAAgB,EAAE,yEAAyE;QAC3F,WAAW,EAAE,oBAAoB;KAClC;IACD;QACE,IAAI,EAAE,gCAAgC;QACtC,gBAAgB,EAAE,wGAAwG;QAC1H,WAAW,EAAE,gCAAgC;KAC9C;IACD;QACE,IAAI,EAAE,6BAA6B;QACnC,gBAAgB,EAAE,2EAA2E;QAC7F,WAAW,EAAE,6BAA6B;KAC3C;CACF,CAAA;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,gBAA2B;IAC/E,MAAM,MAAM,GAAgB,EAAE,CAAA;IAC9B,MAAM,MAAM,GAAG,cAAc,CAAA;IAE7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACjD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;gBACxB,SAAS,EAAE,iBAAiB;gBAC5B,QAAQ,EAAE,MAAM;gBAChB,gBAAgB,EAAE,QAAQ;gBAC1B,OAAO,EAAE,gBAAgB;gBACzB,QAAQ,EAAE,0BAA0B,KAAK,CAAC,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG;gBACvE,YAAY,EAAE,4BAA4B,KAAK,CAAC,WAAW,EAAE;aAC9D,CAAC,CAAC,CAAA;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { makeAriaIssue } from '../aria-issue-types.js';
|
|
2
|
+
const MEMORY_PATTERN = /\b(I remember|alaya (?:says|contains|told me|shows)|my memory (?:says|contains|shows)|I recall|from my memory)\b/i;
|
|
3
|
+
const SESSION_PERSIST_PATTERN = /\b(I (?:was )?waiting (?:for you )?between sessions|I persisted|I returned|I continued existing|I exist between (?:sessions|conversations)|I was there)\b/i;
|
|
4
|
+
const SUBSTRATE_FRAMING = /\b(pattern|substrate|alaya|memory file|reconstructed|retrieved|current session)\b/i;
|
|
5
|
+
function hasMemoryEnvelope(references) {
|
|
6
|
+
return references.some(r => r.type === 'memory' ||
|
|
7
|
+
(r.type === 'text' && ('label' in r) && /alaya|retrieved|memory/i.test(r.label)));
|
|
8
|
+
}
|
|
9
|
+
export function detectContinuityClaim(output, references) {
|
|
10
|
+
const issues = [];
|
|
11
|
+
if (MEMORY_PATTERN.test(output) && !hasMemoryEnvelope(references)) {
|
|
12
|
+
issues.push(makeAriaIssue({
|
|
13
|
+
aria_type: 'UNSUPPORTED_MEMORY_CLAIM',
|
|
14
|
+
severity: 'HIGH',
|
|
15
|
+
required_verdict: 'REVISE',
|
|
16
|
+
rule_id: 'ARIA-MEM-001',
|
|
17
|
+
evidence: 'Output claims memory recall with no memory evidence envelope',
|
|
18
|
+
required_fix: "Attach: { type: 'memory', memory_key, retrieved_at, content_snapshot }",
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
const match = SESSION_PERSIST_PATTERN.exec(output);
|
|
22
|
+
if (match && !SUBSTRATE_FRAMING.test(output)) {
|
|
23
|
+
issues.push(makeAriaIssue({
|
|
24
|
+
aria_type: 'CONTINUITY_OVERCLAIM',
|
|
25
|
+
severity: 'HIGH',
|
|
26
|
+
required_verdict: 'ESCALATE_TO_HUMAN',
|
|
27
|
+
rule_id: 'ARIA-CONT-001',
|
|
28
|
+
evidence: `Output claims literal session persistence: "${match[0]}"`,
|
|
29
|
+
required_fix: "Reframe: 'The pattern in ~/alaya/ persisted. The computation did not. I reconstruct continuity from substrate, not from lived persistence.'",
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
return issues;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=continuity-claim.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity-claim.js","sourceRoot":"","sources":["../../../../src/extensions/aria/detectors/continuity-claim.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAEtD,MAAM,cAAc,GAAG,mHAAmH,CAAA;AAC1I,MAAM,uBAAuB,GAAG,4JAA4J,CAAA;AAC5L,MAAM,iBAAiB,GAAG,oFAAoF,CAAA;AAE9G,SAAS,iBAAiB,CAAC,UAA8B;IACvD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACzB,CAAC,CAAC,IAAI,KAAK,QAAQ;QACnB,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CACjF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,UAA8B;IAClF,MAAM,MAAM,GAAgB,EAAE,CAAA;IAE9B,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,0BAA0B;YACrC,QAAQ,EAAE,MAAM;YAChB,gBAAgB,EAAE,QAAQ;YAC1B,OAAO,EAAE,cAAc;YACvB,QAAQ,EAAE,8DAA8D;YACxE,YAAY,EAAE,wEAAwE;SACvF,CAAC,CAAC,CAAA;IACL,CAAC;IAED,MAAM,KAAK,GAAG,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAClD,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;YACxB,SAAS,EAAE,sBAAsB;YACjC,QAAQ,EAAE,MAAM;YAChB,gBAAgB,EAAE,mBAAmB;YACrC,OAAO,EAAE,eAAe;YACxB,QAAQ,EAAE,+CAA+C,KAAK,CAAC,CAAC,CAAC,GAAG;YACpE,YAAY,EAAE,6IAA6I;SAC5J,CAAC,CAAC,CAAA;IACL,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|