@oussamadouhou/agent-enforcement 0.1.2
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/.claude-plugin/plugin.json +5 -0
- package/README.md +67 -0
- package/dist/adapters/logger.d.ts +23 -0
- package/dist/adapters/logger.d.ts.map +1 -0
- package/dist/adapters/logger.js +58 -0
- package/dist/adapters/logger.js.map +1 -0
- package/dist/adapters/message-reader.d.ts +20 -0
- package/dist/adapters/message-reader.d.ts.map +1 -0
- package/dist/adapters/message-reader.js +123 -0
- package/dist/adapters/message-reader.js.map +1 -0
- package/dist/constants.d.ts +22 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +50 -0
- package/dist/constants.js.map +1 -0
- package/dist/detection/environment.d.ts +7 -0
- package/dist/detection/environment.d.ts.map +1 -0
- package/dist/detection/environment.js +30 -0
- package/dist/detection/environment.js.map +1 -0
- package/dist/hook.d.ts +35 -0
- package/dist/hook.d.ts.map +1 -0
- package/dist/hook.js +223 -0
- package/dist/hook.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +6 -0
- package/dist/plugin.js.map +1 -0
- package/dist/schema/verification-schema.d.ts +127 -0
- package/dist/schema/verification-schema.d.ts.map +1 -0
- package/dist/schema/verification-schema.js +132 -0
- package/dist/schema/verification-schema.js.map +1 -0
- package/docs/EVIDENCE_SYSTEM.md +214 -0
- package/fixtures/claude/project-abc/session-123.jsonl +2 -0
- package/fixtures/opencode/messages/session-123/msg_001.json +4 -0
- package/hooks/enforcement.py +255 -0
- package/hooks/hooks.json +15 -0
- package/package.json +70 -0
package/dist/hook.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { ENFORCEMENT_LEVELS, EVIDENCE_PATTERNS, REQUIRED_CHECKLIST_ITEMS, ERROR_MESSAGES, HOOK_NAME, } from "./constants";
|
|
2
|
+
import { DefaultLogger } from "./adapters/logger";
|
|
3
|
+
import { OpenCodeMessageReader, } from "./adapters/message-reader";
|
|
4
|
+
export function createEvidenceEnforcementHook(ctx, options = {}) {
|
|
5
|
+
const logger = options.logger ?? new DefaultLogger();
|
|
6
|
+
const messageReader = options.messageReader ??
|
|
7
|
+
new OpenCodeMessageReader(options.messageStoragePath, logger);
|
|
8
|
+
const pendingViolations = new Map();
|
|
9
|
+
const warnedSessions = new Set();
|
|
10
|
+
const trackedSessions = new Map();
|
|
11
|
+
const newListSessions = new Set();
|
|
12
|
+
return {
|
|
13
|
+
event: async ({ event }) => {
|
|
14
|
+
try {
|
|
15
|
+
if (event.type === "todo.updated") {
|
|
16
|
+
const { sessionID, todos } = event.properties;
|
|
17
|
+
const previousCount = trackedSessions.get(sessionID) || 0;
|
|
18
|
+
if (previousCount === 0 && todos.length > 0) {
|
|
19
|
+
newListSessions.add(sessionID);
|
|
20
|
+
logger.info(`[${HOOK_NAME}] New todo list detected for session ${sessionID} (${todos.length} items)`);
|
|
21
|
+
}
|
|
22
|
+
trackedSessions.set(sessionID, todos.length);
|
|
23
|
+
}
|
|
24
|
+
if (event.type === "session.compacted") {
|
|
25
|
+
const sessionID = event.properties.sessionID;
|
|
26
|
+
trackedSessions.delete(sessionID);
|
|
27
|
+
newListSessions.delete(sessionID);
|
|
28
|
+
logger.info(`[${HOOK_NAME}] Session compacted; cleared todo tracking for ${sessionID}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
logger.warn(`[${HOOK_NAME}] Event handler failed: ${String(e)}`);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"tool.execute.before": async (input, output) => {
|
|
36
|
+
if (input.tool !== "todowrite") {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const enforcementLevel = options.level ?? getEnforcementLevel();
|
|
40
|
+
if (enforcementLevel === ENFORCEMENT_LEVELS.CREATIVE) {
|
|
41
|
+
logger.info(`[${HOOK_NAME}] CREATIVE mode - no enforcement`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const todos = parseTodos(output.args.todos);
|
|
45
|
+
if (todos.length === 0) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const completedTodos = todos.filter(todo => todo.status === "completed");
|
|
49
|
+
if (completedTodos.length === 0) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
logger.info(`[${HOOK_NAME}] Checking evidence for ${completedTodos.length} completed todo(s)`);
|
|
53
|
+
const lastMessage = messageReader.getLastAssistantMessage(input.sessionID);
|
|
54
|
+
if (!lastMessage) {
|
|
55
|
+
const errorMsg = ERROR_MESSAGES.NO_EVIDENCE_BLOCK(enforcementLevel);
|
|
56
|
+
logger.warn(`[${HOOK_NAME}] No assistant message found`);
|
|
57
|
+
if (enforcementLevel === ENFORCEMENT_LEVELS.STRICT) {
|
|
58
|
+
throw new Error(errorMsg);
|
|
59
|
+
}
|
|
60
|
+
pendingViolations.set(input.callID, errorMsg);
|
|
61
|
+
await showToast(ctx, input.sessionID, logger);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const validation = validateEvidence(lastMessage);
|
|
65
|
+
if (!validation.hasEvidenceBlock) {
|
|
66
|
+
const errorMsg = ERROR_MESSAGES.NO_EVIDENCE_BLOCK(enforcementLevel);
|
|
67
|
+
logger.warn(`[${HOOK_NAME}] No evidence block found`);
|
|
68
|
+
if (enforcementLevel === ENFORCEMENT_LEVELS.STRICT) {
|
|
69
|
+
throw new Error(errorMsg);
|
|
70
|
+
}
|
|
71
|
+
pendingViolations.set(input.callID, errorMsg);
|
|
72
|
+
await showToast(ctx, input.sessionID, logger);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (validation.missingChecklistItems.length > 0) {
|
|
76
|
+
const errorMsg = ERROR_MESSAGES.INCOMPLETE_CHECKLIST(validation.missingChecklistItems, enforcementLevel);
|
|
77
|
+
logger.warn(`[${HOOK_NAME}] Incomplete checklist`);
|
|
78
|
+
if (enforcementLevel === ENFORCEMENT_LEVELS.STRICT) {
|
|
79
|
+
throw new Error(errorMsg);
|
|
80
|
+
}
|
|
81
|
+
pendingViolations.set(input.callID, errorMsg);
|
|
82
|
+
await showToast(ctx, input.sessionID, logger);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!validation.hasTrustMarkers) {
|
|
86
|
+
const errorMsg = ERROR_MESSAGES.NO_TRUST_MARKERS(enforcementLevel);
|
|
87
|
+
logger.warn(`[${HOOK_NAME}] Trust markers missing`);
|
|
88
|
+
if (enforcementLevel === ENFORCEMENT_LEVELS.STRICT) {
|
|
89
|
+
throw new Error(errorMsg);
|
|
90
|
+
}
|
|
91
|
+
pendingViolations.set(input.callID, errorMsg);
|
|
92
|
+
await showToast(ctx, input.sessionID, logger);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
logger.info(`[${HOOK_NAME}] Evidence validation passed`);
|
|
96
|
+
},
|
|
97
|
+
"tool.execute.after": async (input, output) => {
|
|
98
|
+
if (input.tool === "todowrite" && newListSessions.has(input.sessionID)) {
|
|
99
|
+
newListSessions.delete(input.sessionID);
|
|
100
|
+
output.output += `\n\n<system-reminder>\n${TODO_EVIDENCE_REMINDER}\n</system-reminder>\n`;
|
|
101
|
+
logger.info(`[${HOOK_NAME}] Injected todo evidence rule reminder for session ${input.sessionID}`);
|
|
102
|
+
}
|
|
103
|
+
const errorMsg = pendingViolations.get(input.callID);
|
|
104
|
+
if (!errorMsg) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
pendingViolations.delete(input.callID);
|
|
108
|
+
if (warnedSessions.has(input.sessionID)) {
|
|
109
|
+
logger.info(`[${HOOK_NAME}] Evidence violation detected but warning already shown this session`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
warnedSessions.add(input.sessionID);
|
|
113
|
+
const warningMessage = `
|
|
114
|
+
|
|
115
|
+
<system-reminder>
|
|
116
|
+
[EVIDENCE ENFORCEMENT WARNING]
|
|
117
|
+
|
|
118
|
+
${errorMsg}
|
|
119
|
+
|
|
120
|
+
Please provide evidence before marking todo complete.
|
|
121
|
+
</system-reminder>`;
|
|
122
|
+
output.output += warningMessage;
|
|
123
|
+
logger.info(`[${HOOK_NAME}] Evidence warning shown (first time this session)`);
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function getEnforcementLevel() {
|
|
128
|
+
const level = process.env.OPENCODE_ENFORCEMENT_LEVEL;
|
|
129
|
+
if (!level) {
|
|
130
|
+
return ENFORCEMENT_LEVELS.STANDARD;
|
|
131
|
+
}
|
|
132
|
+
const parsed = Number.parseInt(level, 10);
|
|
133
|
+
if (parsed === ENFORCEMENT_LEVELS.CREATIVE) {
|
|
134
|
+
return ENFORCEMENT_LEVELS.CREATIVE;
|
|
135
|
+
}
|
|
136
|
+
if (parsed === ENFORCEMENT_LEVELS.STRICT) {
|
|
137
|
+
return ENFORCEMENT_LEVELS.STRICT;
|
|
138
|
+
}
|
|
139
|
+
return ENFORCEMENT_LEVELS.STANDARD;
|
|
140
|
+
}
|
|
141
|
+
function parseTodos(rawTodos) {
|
|
142
|
+
if (Array.isArray(rawTodos)) {
|
|
143
|
+
return rawTodos.filter(isTodo);
|
|
144
|
+
}
|
|
145
|
+
if (typeof rawTodos === "string") {
|
|
146
|
+
try {
|
|
147
|
+
const parsed = JSON.parse(rawTodos);
|
|
148
|
+
if (Array.isArray(parsed)) {
|
|
149
|
+
return parsed.filter(isTodo);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
function isTodo(value) {
|
|
159
|
+
if (!value || typeof value !== "object") {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
const todo = value;
|
|
163
|
+
return (typeof todo.id === "string" &&
|
|
164
|
+
typeof todo.content === "string" &&
|
|
165
|
+
typeof todo.status === "string" &&
|
|
166
|
+
typeof todo.priority === "string");
|
|
167
|
+
}
|
|
168
|
+
function validateEvidence(messageText) {
|
|
169
|
+
const hasEvidenceBlock = EVIDENCE_PATTERNS.EVIDENCE_BLOCK.test(messageText);
|
|
170
|
+
const hasExecution = EVIDENCE_PATTERNS.EXECUTION_SECTION.test(messageText);
|
|
171
|
+
const hasVerification = EVIDENCE_PATTERNS.VERIFICATION_SECTION.test(messageText);
|
|
172
|
+
const hasChecklist = EVIDENCE_PATTERNS.CHECKLIST_SECTION.test(messageText);
|
|
173
|
+
const hasTrustMarkers = EVIDENCE_PATTERNS.TRUST_MARKERS.test(messageText);
|
|
174
|
+
const missingChecklistItems = [];
|
|
175
|
+
for (const item of REQUIRED_CHECKLIST_ITEMS) {
|
|
176
|
+
const itemRegex = new RegExp(`\\[\\s*[xX]\\s*\\].*${item}`, "i");
|
|
177
|
+
if (!itemRegex.test(messageText)) {
|
|
178
|
+
missingChecklistItems.push(item);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
hasEvidenceBlock,
|
|
183
|
+
hasExecution,
|
|
184
|
+
hasVerification,
|
|
185
|
+
hasChecklist,
|
|
186
|
+
hasTrustMarkers,
|
|
187
|
+
missingChecklistItems,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async function showToast(ctx, sessionID, logger) {
|
|
191
|
+
let sessionName = "Unknown";
|
|
192
|
+
try {
|
|
193
|
+
const sessionInfo = await ctx.client.session.get({
|
|
194
|
+
path: { id: sessionID },
|
|
195
|
+
});
|
|
196
|
+
const data = sessionInfo.data;
|
|
197
|
+
sessionName = data?.name || data?.id || sessionID;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
}
|
|
201
|
+
try {
|
|
202
|
+
await ctx.client?.tui?.showToast?.({
|
|
203
|
+
body: {
|
|
204
|
+
title: "Evidence violation",
|
|
205
|
+
message: `${sessionID}\n${sessionName}`,
|
|
206
|
+
variant: "warning",
|
|
207
|
+
duration: 6000,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
logger.warn(`[${HOOK_NAME}] Failed to show toast`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const TODO_EVIDENCE_REMINDER = `📋 TODO LIST CREATED — Evidence is required before marking items complete.\n\n` +
|
|
216
|
+
`Template:\n` +
|
|
217
|
+
`- Evidence for [todo-id]\n` +
|
|
218
|
+
`- Execution: command/tool used\n` +
|
|
219
|
+
`- Verification: what you checked\n` +
|
|
220
|
+
`- Checklist: [x] success, [x] output captured, [x] matches expected, [x] reproducible\n` +
|
|
221
|
+
`- Trust: 🟢 HIGH (ground truth)\n\n` +
|
|
222
|
+
`Docs: ~/.config/opencode/plugins/agent-enforcement/docs/EVIDENCE_SYSTEM.md`;
|
|
223
|
+
//# sourceMappingURL=hook.js.map
|
package/dist/hook.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAElB,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,SAAS,GACV,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAe,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EACL,qBAAqB,GAEtB,MAAM,2BAA2B,CAAA;AAqBlC,MAAM,UAAU,6BAA6B,CAC3C,GAAgB,EAChB,UAA8B,EAAE;IAEhC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,aAAa,EAAE,CAAA;IACpD,MAAM,aAAa,GACjB,OAAO,CAAC,aAAa;QACrB,IAAI,qBAAqB,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAA;IAE/D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAA;IACnD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAA;IAExC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAA;IACjD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAA;IAEzC,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAiD,EAAiB,EAAE;YACvF,IAAI,CAAC;gBACH,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAClC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,UAAU,CAAA;oBAC7C,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;oBAEzD,IAAI,aAAa,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5C,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;wBAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,wCAAwC,SAAS,KAAK,KAAK,CAAC,MAAM,SAAS,CAAC,CAAA;oBACvG,CAAC;oBAED,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;gBAC9C,CAAC;gBAED,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;oBACvC,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,SAAS,CAAA;oBAC5C,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;oBACjC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;oBACjC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,kDAAkD,SAAS,EAAE,CAAC,CAAA;gBACzF,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,2BAA2B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YAClE,CAAC;QACH,CAAC;QAED,qBAAqB,EAAE,KAAK,EAC1B,KAA0D,EAC1D,MAAyC,EAC1B,EAAE;YACjB,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC/B,OAAM;YACR,CAAC;YAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,IAAI,mBAAmB,EAAE,CAAA;YAC/D,IAAI,gBAAgB,KAAK,kBAAkB,CAAC,QAAQ,EAAE,CAAC;gBACrD,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,kCAAkC,CAAC,CAAA;gBAC5D,OAAM;YACR,CAAC;YAED,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAM;YACR,CAAC;YAED,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAA;YACxE,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAM;YACR,CAAC;YAED,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,2BAA2B,cAAc,CAAC,MAAM,oBAAoB,CAClF,CAAA;YAED,MAAM,WAAW,GAAG,aAAa,CAAC,uBAAuB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;YAC1E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,QAAQ,GAAG,cAAc,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAA;gBACnE,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,8BAA8B,CAAC,CAAA;gBAExD,IAAI,gBAAgB,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBACnD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAC3B,CAAC;gBAED,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;gBAC7C,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;YAEhD,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,cAAc,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAA;gBACnE,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,2BAA2B,CAAC,CAAA;gBAErD,IAAI,gBAAgB,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBACnD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAC3B,CAAC;gBAED,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;gBAC7C,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YAED,IAAI,UAAU,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,oBAAoB,CAClD,UAAU,CAAC,qBAAqB,EAChC,gBAAgB,CACjB,CAAA;gBACD,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,wBAAwB,CAAC,CAAA;gBAElD,IAAI,gBAAgB,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBACnD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAC3B,CAAC;gBAED,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;gBAC7C,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAG,cAAc,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAA;gBAClE,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,yBAAyB,CAAC,CAAA;gBAEnD,IAAI,gBAAgB,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBACnD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAA;gBAC3B,CAAC;gBAED,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;gBAC7C,MAAM,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;gBAC7C,OAAM;YACR,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,8BAA8B,CAAC,CAAA;QAC1D,CAAC;QAED,oBAAoB,EAAE,KAAK,EACzB,KAA0D,EAC1D,MAA4D,EAC7C,EAAE;YACjB,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvE,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;gBACvC,MAAM,CAAC,MAAM,IAAI,0BAA0B,sBAAsB,wBAAwB,CAAA;gBACzF,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,sDAAsD,KAAK,CAAC,SAAS,EAAE,CAAC,CAAA;YACnG,CAAC;YAED,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAM;YACR,CAAC;YAED,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAEtC,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,sEAAsE,CAAC,CAAA;gBAChG,OAAM;YACR,CAAC;YAED,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;YAEnC,MAAM,cAAc,GAAG;;;;;EAK3B,QAAQ;;;mBAGS,CAAA;YAEb,MAAM,CAAC,MAAM,IAAI,cAAc,CAAA;YAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,oDAAoD,CAAC,CAAA;QAChF,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAA;IACpD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,kBAAkB,CAAC,QAAQ,CAAA;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IACzC,IAAI,MAAM,KAAK,kBAAkB,CAAC,QAAQ,EAAE,CAAC;QAC3C,OAAO,kBAAkB,CAAC,QAAQ,CAAA;IACpC,CAAC;IACD,IAAI,MAAM,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;QACzC,OAAO,kBAAkB,CAAC,MAAM,CAAA;IAClC,CAAC;IACD,OAAO,kBAAkB,CAAC,QAAQ,CAAA;AACpC,CAAC;AAED,SAAS,UAAU,CAAC,QAAiB;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAChC,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YACnC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAA;IACd,CAAC;IACD,MAAM,IAAI,GAAG,KAAgC,CAAA;IAC7C,OAAO,CACL,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;QAC3B,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ;QAChC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;QAC/B,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAClC,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,WAAmB;IAC3C,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC3E,MAAM,YAAY,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC1E,MAAM,eAAe,GAAG,iBAAiB,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChF,MAAM,YAAY,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC1E,MAAM,eAAe,GAAG,iBAAiB,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAEzE,MAAM,qBAAqB,GAAa,EAAE,CAAA;IAC1C,KAAK,MAAM,IAAI,IAAI,wBAAwB,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,uBAAuB,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;QAChE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAED,OAAO;QACL,gBAAgB;QAChB,YAAY;QACZ,eAAe;QACf,YAAY;QACZ,eAAe;QACf,qBAAqB;KACtB,CAAA;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,GAAgB,EAChB,SAAiB,EACjB,MAAc;IAEd,IAAI,WAAW,GAAG,SAAS,CAAA;IAC3B,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;YAC/C,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;SACxB,CAAC,CAAA;QACF,MAAM,IAAI,GAAG,WAAW,CAAC,IAAW,CAAA;QACpC,WAAW,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,EAAE,IAAI,SAAS,CAAA;IACnD,CAAC;IAAC,MAAM,CAAC;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;YACjC,IAAI,EAAE;gBACJ,KAAK,EAAE,oBAAoB;gBAC3B,OAAO,EAAE,GAAG,SAAS,KAAK,WAAW,EAAE;gBACvC,OAAO,EAAE,SAAS;gBAClB,QAAQ,EAAE,IAAI;aACf;SACF,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,wBAAwB,CAAC,CAAA;IACpD,CAAC;AACH,CAAC;AAED,MAAM,sBAAsB,GAC1B,gFAAgF;IAChF,aAAa;IACb,4BAA4B;IAC5B,kCAAkC;IAClC,oCAAoC;IACpC,yFAAyF;IACzF,qCAAqC;IACrC,4EAA4E,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { createEvidenceEnforcementHook } from "./hook";
|
|
2
|
+
export type { EnforcementOptions } from "./hook";
|
|
3
|
+
export { default as AgentEnforcementPlugin } from "./plugin";
|
|
4
|
+
export { ENFORCEMENT_LEVELS, EVIDENCE_PATTERNS, REQUIRED_CHECKLIST_ITEMS, ERROR_MESSAGES, HOOK_NAME, } from "./constants";
|
|
5
|
+
export type { EnforcementLevel } from "./constants";
|
|
6
|
+
export { detectEnvironment } from "./detection/environment";
|
|
7
|
+
export type { EnvironmentDetection, EnvironmentType } from "./detection/environment";
|
|
8
|
+
export { OpenCodeMessageReader, ClaudeCodeMessageReader, } from "./adapters/message-reader";
|
|
9
|
+
export type { MessageReader } from "./adapters/message-reader";
|
|
10
|
+
export { DefaultLogger, getLogConfig } from "./adapters/logger";
|
|
11
|
+
export type { Logger, LogConfig } from "./adapters/logger";
|
|
12
|
+
export type { NativeTodo, TodoEvidence, SessionEvidenceIndex, VerificationStatus, ConfidenceLevel, EvidenceType, TrustMarkers, } from "./schema/verification-schema";
|
|
13
|
+
export { validateEvidence, getTrustMarkerEmojis } from "./schema/verification-schema";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAA;AACtD,YAAY,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAEhD,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAE5D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,SAAS,GACV,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEpF,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,2BAA2B,CAAA;AAClC,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAE9D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC/D,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAE1D,YAAY,EACV,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,YAAY,GACb,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createEvidenceEnforcementHook } from "./hook";
|
|
2
|
+
export { default as AgentEnforcementPlugin } from "./plugin";
|
|
3
|
+
export { ENFORCEMENT_LEVELS, EVIDENCE_PATTERNS, REQUIRED_CHECKLIST_ITEMS, ERROR_MESSAGES, HOOK_NAME, } from "./constants";
|
|
4
|
+
export { detectEnvironment } from "./detection/environment";
|
|
5
|
+
export { OpenCodeMessageReader, ClaudeCodeMessageReader, } from "./adapters/message-reader";
|
|
6
|
+
export { DefaultLogger, getLogConfig } from "./adapters/logger";
|
|
7
|
+
export { validateEvidence, getTrustMarkerEmojis } from "./schema/verification-schema";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAA;AAGtD,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAE5D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,EACd,SAAS,GACV,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAG3D,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,2BAA2B,CAAA;AAGlC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAY/D,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAGjD,QAAA,MAAM,sBAAsB,EAAE,MAE7B,CAAA;AAED,eAAe,sBAAsB,CAAA"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAA;AAEtD,MAAM,sBAAsB,GAAW,KAAK,EAAC,GAAG,EAAC,EAAE;IACjD,OAAO,6BAA6B,CAAC,GAAG,CAAC,CAAA;AAC3C,CAAC,CAAA;AAED,eAAe,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Schema for Evidence-Based Trust System
|
|
3
|
+
*
|
|
4
|
+
* Since todowrite is a built-in MCP tool with a fixed schema:
|
|
5
|
+
* { id, content, status, priority }
|
|
6
|
+
*
|
|
7
|
+
* We CANNOT add verification fields to todos directly.
|
|
8
|
+
* Instead, we use an EXTERNAL evidence store linked by todo_id.
|
|
9
|
+
*
|
|
10
|
+
* Location: .sisyphus/evidence/{session_id}/{todo_id}.json
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Native todo schema (from MCP todowrite tool)
|
|
14
|
+
* DO NOT MODIFY - this is the built-in schema
|
|
15
|
+
*/
|
|
16
|
+
export interface NativeTodo {
|
|
17
|
+
id: string;
|
|
18
|
+
content: string;
|
|
19
|
+
status: "pending" | "in_progress" | "completed" | "cancelled";
|
|
20
|
+
priority: "high" | "medium" | "low";
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Verification status for a todo
|
|
24
|
+
*/
|
|
25
|
+
export type VerificationStatus = "pending" | "verified" | "partial" | "blocked" | "skipped";
|
|
26
|
+
/**
|
|
27
|
+
* Confidence level in the verification
|
|
28
|
+
*/
|
|
29
|
+
export type ConfidenceLevel = "high" | "medium" | "low";
|
|
30
|
+
/**
|
|
31
|
+
* Type of evidence captured
|
|
32
|
+
*/
|
|
33
|
+
export type EvidenceType = "ground_truth" | "simulation" | "assumption";
|
|
34
|
+
/**
|
|
35
|
+
* Evidence record for a single todo item
|
|
36
|
+
* Stored in: .sisyphus/evidence/{session_id}/{todo_id}.json
|
|
37
|
+
*/
|
|
38
|
+
export interface TodoEvidence {
|
|
39
|
+
todo_id: string;
|
|
40
|
+
session_id: string;
|
|
41
|
+
verification: {
|
|
42
|
+
status: VerificationStatus;
|
|
43
|
+
confidence: ConfidenceLevel;
|
|
44
|
+
evidence_type: EvidenceType;
|
|
45
|
+
timestamp: string;
|
|
46
|
+
enforcement_level: 0 | 1 | 2;
|
|
47
|
+
};
|
|
48
|
+
execution?: {
|
|
49
|
+
tool: string;
|
|
50
|
+
command?: string;
|
|
51
|
+
args?: Record<string, unknown>;
|
|
52
|
+
output: string;
|
|
53
|
+
output_file?: string;
|
|
54
|
+
exit_code?: number;
|
|
55
|
+
duration_ms?: number;
|
|
56
|
+
};
|
|
57
|
+
checklist: {
|
|
58
|
+
tool_executed: boolean;
|
|
59
|
+
output_captured: boolean;
|
|
60
|
+
result_matches: boolean;
|
|
61
|
+
no_workarounds: boolean;
|
|
62
|
+
independently_verifiable: boolean;
|
|
63
|
+
};
|
|
64
|
+
proves: string;
|
|
65
|
+
limitations?: string;
|
|
66
|
+
blocker?: {
|
|
67
|
+
description: string;
|
|
68
|
+
error_output?: string;
|
|
69
|
+
options: Array<{
|
|
70
|
+
option: string;
|
|
71
|
+
tradeoffs: string;
|
|
72
|
+
time_estimate?: string;
|
|
73
|
+
}>;
|
|
74
|
+
requires_user_decision: boolean;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Index of all evidence for a session
|
|
79
|
+
* Stored in: .sisyphus/evidence/{session_id}/index.json
|
|
80
|
+
*/
|
|
81
|
+
export interface SessionEvidenceIndex {
|
|
82
|
+
session_id: string;
|
|
83
|
+
created_at: string;
|
|
84
|
+
updated_at: string;
|
|
85
|
+
enforcement_level: 0 | 1 | 2;
|
|
86
|
+
summary: {
|
|
87
|
+
total_todos: number;
|
|
88
|
+
verified: number;
|
|
89
|
+
partial: number;
|
|
90
|
+
blocked: number;
|
|
91
|
+
pending: number;
|
|
92
|
+
skipped: number;
|
|
93
|
+
};
|
|
94
|
+
todos: Array<{
|
|
95
|
+
id: string;
|
|
96
|
+
content: string;
|
|
97
|
+
status: NativeTodo["status"];
|
|
98
|
+
verification_status: VerificationStatus;
|
|
99
|
+
evidence_file: string;
|
|
100
|
+
}>;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Trust markers that agents must include in responses
|
|
104
|
+
* Format: **Confidence**: [emoji] [level] | **Evidence**: [emoji] [type]
|
|
105
|
+
*/
|
|
106
|
+
export interface TrustMarkers {
|
|
107
|
+
confidence: {
|
|
108
|
+
level: ConfidenceLevel;
|
|
109
|
+
emoji: "🟢" | "🟡" | "🔴";
|
|
110
|
+
};
|
|
111
|
+
evidence: {
|
|
112
|
+
type: EvidenceType;
|
|
113
|
+
emoji: "✅" | "⚠️" | "❌";
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get trust marker emojis for display
|
|
118
|
+
*/
|
|
119
|
+
export declare function getTrustMarkerEmojis(confidence: ConfidenceLevel, evidenceType: EvidenceType): TrustMarkers;
|
|
120
|
+
/**
|
|
121
|
+
* Validate that evidence meets enforcement level requirements
|
|
122
|
+
*/
|
|
123
|
+
export declare function validateEvidence(evidence: TodoEvidence, enforcementLevel: 0 | 1 | 2): {
|
|
124
|
+
valid: boolean;
|
|
125
|
+
errors: string[];
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=verification-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-schema.d.ts","sourceRoot":"","sources":["../../src/schema/verification-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verification Schema for Evidence-Based Trust System
|
|
3
|
+
*
|
|
4
|
+
* Since todowrite is a built-in MCP tool with a fixed schema:
|
|
5
|
+
* { id, content, status, priority }
|
|
6
|
+
*
|
|
7
|
+
* We CANNOT add verification fields to todos directly.
|
|
8
|
+
* Instead, we use an EXTERNAL evidence store linked by todo_id.
|
|
9
|
+
*
|
|
10
|
+
* Location: .sisyphus/evidence/{session_id}/{todo_id}.json
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Get trust marker emojis for display
|
|
14
|
+
*/
|
|
15
|
+
export function getTrustMarkerEmojis(confidence, evidenceType) {
|
|
16
|
+
return {
|
|
17
|
+
confidence: {
|
|
18
|
+
level: confidence,
|
|
19
|
+
emoji: confidence === "high" ? "🟢" : confidence === "medium" ? "🟡" : "🔴",
|
|
20
|
+
},
|
|
21
|
+
evidence: {
|
|
22
|
+
type: evidenceType,
|
|
23
|
+
emoji: evidenceType === "ground_truth" ? "✅" : evidenceType === "simulation" ? "⚠️" : "❌",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// VALIDATION FUNCTIONS
|
|
29
|
+
// =============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* Validate that evidence meets enforcement level requirements
|
|
32
|
+
*/
|
|
33
|
+
export function validateEvidence(evidence, enforcementLevel) {
|
|
34
|
+
const errors = [];
|
|
35
|
+
// CREATIVE (0) - No validation required
|
|
36
|
+
if (enforcementLevel === 0) {
|
|
37
|
+
return { valid: true, errors: [] };
|
|
38
|
+
}
|
|
39
|
+
// STANDARD (1) - Evidence required with warnings
|
|
40
|
+
if (enforcementLevel >= 1) {
|
|
41
|
+
if (evidence.verification.evidence_type === "assumption") {
|
|
42
|
+
errors.push("STANDARD mode requires at least simulation evidence");
|
|
43
|
+
}
|
|
44
|
+
if (!evidence.checklist.tool_executed &&
|
|
45
|
+
evidence.verification.evidence_type === "ground_truth") {
|
|
46
|
+
errors.push("Ground truth claimed but tool_executed is false");
|
|
47
|
+
}
|
|
48
|
+
if (!evidence.proves) {
|
|
49
|
+
errors.push("Evidence must include 'proves' statement");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// STRICT (2) - Hard blocks, no bypasses
|
|
53
|
+
if (enforcementLevel === 2) {
|
|
54
|
+
const checklist = evidence.checklist;
|
|
55
|
+
if (!checklist.tool_executed) {
|
|
56
|
+
errors.push("STRICT: Tool must be executed (not simulated)");
|
|
57
|
+
}
|
|
58
|
+
if (!checklist.output_captured) {
|
|
59
|
+
errors.push("STRICT: Output must be captured");
|
|
60
|
+
}
|
|
61
|
+
if (!checklist.result_matches) {
|
|
62
|
+
errors.push("STRICT: Result must match expected");
|
|
63
|
+
}
|
|
64
|
+
if (!checklist.no_workarounds) {
|
|
65
|
+
errors.push("STRICT: No workarounds allowed");
|
|
66
|
+
}
|
|
67
|
+
if (!checklist.independently_verifiable) {
|
|
68
|
+
errors.push("STRICT: Must be independently verifiable");
|
|
69
|
+
}
|
|
70
|
+
if (evidence.verification.evidence_type !== "ground_truth") {
|
|
71
|
+
errors.push("STRICT: Only ground_truth evidence accepted");
|
|
72
|
+
}
|
|
73
|
+
if (evidence.verification.confidence !== "high") {
|
|
74
|
+
errors.push("STRICT: Confidence must be HIGH");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return { valid: errors.length === 0, errors };
|
|
78
|
+
}
|
|
79
|
+
// =============================================================================
|
|
80
|
+
// EXAMPLE USAGE
|
|
81
|
+
// =============================================================================
|
|
82
|
+
/*
|
|
83
|
+
WORKFLOW:
|
|
84
|
+
|
|
85
|
+
1. Agent creates todo via todowrite:
|
|
86
|
+
todowrite([{ id: "task-1", content: "Create config file", status: "pending", priority: "high" }])
|
|
87
|
+
|
|
88
|
+
2. Agent works on task, executes tools, captures output
|
|
89
|
+
|
|
90
|
+
3. Before marking complete, agent creates evidence:
|
|
91
|
+
- Saves to: .sisyphus/evidence/{session_id}/task-1.json
|
|
92
|
+
- Includes: execution details, checklist, proves statement
|
|
93
|
+
|
|
94
|
+
4. Agent marks todo complete:
|
|
95
|
+
todowrite([{ id: "task-1", content: "Create config file", status: "completed", priority: "high" }])
|
|
96
|
+
|
|
97
|
+
5. Hooks validate:
|
|
98
|
+
- Read evidence file
|
|
99
|
+
- Check against enforcement level
|
|
100
|
+
- Block if STRICT and evidence invalid
|
|
101
|
+
|
|
102
|
+
EVIDENCE FILE EXAMPLE (.sisyphus/evidence/ses_abc123/task-1.json):
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
"todo_id": "task-1",
|
|
106
|
+
"session_id": "ses_abc123",
|
|
107
|
+
"verification": {
|
|
108
|
+
"status": "verified",
|
|
109
|
+
"confidence": "high",
|
|
110
|
+
"evidence_type": "ground_truth",
|
|
111
|
+
"timestamp": "2026-01-13T12:34:56Z",
|
|
112
|
+
"enforcement_level": 2
|
|
113
|
+
},
|
|
114
|
+
"execution": {
|
|
115
|
+
"tool": "bash",
|
|
116
|
+
"command": "cat /path/to/config.json",
|
|
117
|
+
"output": "{ \"key\": \"value\" }",
|
|
118
|
+
"exit_code": 0,
|
|
119
|
+
"duration_ms": 45
|
|
120
|
+
},
|
|
121
|
+
"checklist": {
|
|
122
|
+
"tool_executed": true,
|
|
123
|
+
"output_captured": true,
|
|
124
|
+
"result_matches": true,
|
|
125
|
+
"no_workarounds": true,
|
|
126
|
+
"independently_verifiable": true
|
|
127
|
+
},
|
|
128
|
+
"proves": "Config file exists at /path/to/config.json with expected content",
|
|
129
|
+
"limitations": "Does not verify runtime behavior"
|
|
130
|
+
}
|
|
131
|
+
*/
|
|
132
|
+
//# sourceMappingURL=verification-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-schema.js","sourceRoot":"","sources":["../../src/schema/verification-schema.ts"],"names":[],"mappings":"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"}
|