agentskeptic 0.1.1 → 0.1.3
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/LICENSE +21 -21
- package/README.md +342 -342
- package/dist/cli.js +157 -157
- package/dist/debug-ui/app.css +188 -188
- package/dist/debug-ui/app.js +245 -245
- package/dist/debug-ui/index.html +79 -79
- package/dist/enforceCli.js +11 -11
- package/dist/planTransition.test.js +235 -235
- package/dist/planTransitionPathHarvest.test.js +116 -116
- package/dist/quickVerify/postgresCatalog.js +53 -53
- package/package.json +1 -1
- package/schemas/agent-run-record-v1.schema.json +51 -51
- package/schemas/agent-run-record-v2.schema.json +61 -61
- package/schemas/assurance-manifest-v1.schema.json +28 -28
- package/schemas/assurance-run-report-v1.schema.json +28 -28
- package/schemas/ci-lock-v1.schema.json +163 -163
- package/schemas/cli-error-envelope.schema.json +48 -48
- package/schemas/event.schema.json +111 -111
- package/schemas/execution-trace-view.schema.json +122 -122
- package/schemas/plan-validation-core.schema.json +95 -95
- package/schemas/quick-verify-report.schema.json +251 -251
- package/schemas/registry-validation-result.schema.json +99 -99
- package/schemas/run-comparison-report.schema.json +513 -513
- package/schemas/tools-registry-export.schema.json +9 -9
- package/schemas/tools-registry.schema.json +284 -284
- package/schemas/workflow-engine-result.schema.json +591 -591
- package/schemas/workflow-result-compare-input.schema.json +15 -15
- package/schemas/workflow-result-signature.schema.json +20 -20
- package/schemas/workflow-result-v9.schema.json +85 -85
- package/schemas/workflow-result.schema.json +80 -80
- package/schemas/workflow-truth-report.schema.json +761 -761
- package/dist/failureOriginSchemaEnum.test.d.ts +0 -2
- package/dist/failureOriginSchemaEnum.test.d.ts.map +0 -1
- package/dist/failureOriginSchemaEnum.test.js +0 -21
- package/dist/failureOriginSchemaEnum.test.js.map +0 -1
- package/dist/failureOriginSchemaParity.test.d.ts +0 -2
- package/dist/failureOriginSchemaParity.test.d.ts.map +0 -1
- package/dist/failureOriginSchemaParity.test.js +0 -33
- package/dist/failureOriginSchemaParity.test.js.map +0 -1
- package/dist/slice6.compare.ac.test.d.ts +0 -2
- package/dist/slice6.compare.ac.test.d.ts.map +0 -1
- package/dist/slice6.compare.ac.test.js +0 -81
- package/dist/slice6.compare.ac.test.js.map +0 -1
|
@@ -52,179 +52,179 @@ describe("harvestQualifyingPathsFromPlan", () => {
|
|
|
52
52
|
expect(result).not.toContain("src/runComparison.ts");
|
|
53
53
|
});
|
|
54
54
|
it("ISO-LINK: strong-action required for links in obligation section", () => {
|
|
55
|
-
const md = `---
|
|
56
|
-
name: x
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Implementation
|
|
60
|
-
|
|
61
|
-
Add [x](src/a.ts) and update [y](./schemas/b.json).
|
|
55
|
+
const md = `---
|
|
56
|
+
name: x
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Implementation
|
|
60
|
+
|
|
61
|
+
Add [x](src/a.ts) and update [y](./schemas/b.json).
|
|
62
62
|
`;
|
|
63
63
|
expect(harvestQualifyingPathsFromPlan(md, {})).toEqual(["schemas/b.json", "src/a.ts"]);
|
|
64
64
|
});
|
|
65
65
|
it("ISO-TICK: strong-action required for docs/ and examples/ backticks", () => {
|
|
66
|
-
const md = `---
|
|
67
|
-
name: x
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Implementation
|
|
71
|
-
|
|
72
|
-
Add \`docs/x.md\` and extend \`examples/y.sql\`.
|
|
66
|
+
const md = `---
|
|
67
|
+
name: x
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Implementation
|
|
71
|
+
|
|
72
|
+
Add \`docs/x.md\` and extend \`examples/y.sql\`.
|
|
73
73
|
`;
|
|
74
74
|
expect(harvestQualifyingPathsFromPlan(md, {})).toEqual(["docs/x.md", "examples/y.sql"]);
|
|
75
75
|
});
|
|
76
76
|
it("DELIVERABLES: harvests from ## Deliverables section", () => {
|
|
77
|
-
const md = `---
|
|
78
|
-
name: x
|
|
79
|
-
todos: []
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## Deliverables
|
|
83
|
-
|
|
84
|
-
Touch \`src/from-deliverables.ts\`.
|
|
77
|
+
const md = `---
|
|
78
|
+
name: x
|
|
79
|
+
todos: []
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Deliverables
|
|
83
|
+
|
|
84
|
+
Touch \`src/from-deliverables.ts\`.
|
|
85
85
|
`;
|
|
86
86
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual(["src/from-deliverables.ts"]);
|
|
87
87
|
});
|
|
88
88
|
it("ISO-TODO: extracts from todos[].content via link parser", () => {
|
|
89
|
-
const md = `---
|
|
90
|
-
name: x
|
|
91
|
-
---
|
|
92
|
-
|
|
89
|
+
const md = `---
|
|
90
|
+
name: x
|
|
91
|
+
---
|
|
92
|
+
|
|
93
93
|
`;
|
|
94
94
|
const fm = { todos: [{ id: "t", content: "Touch [legacy](C:/fake/prefix/src/z.ts)" }] };
|
|
95
95
|
expect(harvestQualifyingPathsFromPlan(md, fm)).toEqual(["src/z.ts"]);
|
|
96
96
|
});
|
|
97
97
|
it("TODO-REF: semicolon segments; reference-only segment does not harvest", () => {
|
|
98
|
-
const md = `---
|
|
99
|
-
name: x
|
|
100
|
-
todos:
|
|
101
|
-
- id: t
|
|
102
|
-
content: 'Add [a](src/a.ts); same shape as [x](src/b.ts)'
|
|
103
|
-
---
|
|
104
|
-
|
|
98
|
+
const md = `---
|
|
99
|
+
name: x
|
|
100
|
+
todos:
|
|
101
|
+
- id: t
|
|
102
|
+
content: 'Add [a](src/a.ts); same shape as [x](src/b.ts)'
|
|
103
|
+
---
|
|
104
|
+
|
|
105
105
|
`;
|
|
106
106
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual(["src/a.ts"]);
|
|
107
107
|
});
|
|
108
108
|
it("does not harvest paths that appear only inside fenced code blocks in obligation section", () => {
|
|
109
|
-
const md = `---
|
|
110
|
-
name: x
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## Implementation
|
|
114
|
-
|
|
115
|
-
\`\`\`text
|
|
116
|
-
src/hidden.ts
|
|
117
|
-
\`\`\`
|
|
118
|
-
|
|
119
|
-
Touch \`src/visible.ts\`.
|
|
109
|
+
const md = `---
|
|
110
|
+
name: x
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Implementation
|
|
114
|
+
|
|
115
|
+
\`\`\`text
|
|
116
|
+
src/hidden.ts
|
|
117
|
+
\`\`\`
|
|
118
|
+
|
|
119
|
+
Touch \`src/visible.ts\`.
|
|
120
120
|
`;
|
|
121
121
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual(["src/visible.ts"]);
|
|
122
122
|
});
|
|
123
123
|
it("rejects backtick candidates with .. in path", () => {
|
|
124
|
-
const md = `---
|
|
125
|
-
name: x
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## Implementation
|
|
129
|
-
|
|
130
|
-
\`src/../x.ts\`
|
|
124
|
+
const md = `---
|
|
125
|
+
name: x
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Implementation
|
|
129
|
+
|
|
130
|
+
\`src/../x.ts\`
|
|
131
131
|
`;
|
|
132
132
|
expect(harvestQualifyingPathsFromPlan(md, {})).toEqual([]);
|
|
133
133
|
});
|
|
134
134
|
it("does not harvest from non-obligation sections when todos empty", () => {
|
|
135
|
-
const md = `---
|
|
136
|
-
name: x
|
|
137
|
-
todos: []
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## Analysis
|
|
141
|
-
|
|
142
|
-
Touch [orphan](src/orphan.ts).
|
|
135
|
+
const md = `---
|
|
136
|
+
name: x
|
|
137
|
+
todos: []
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Analysis
|
|
141
|
+
|
|
142
|
+
Touch [orphan](src/orphan.ts).
|
|
143
143
|
`;
|
|
144
144
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual([]);
|
|
145
145
|
});
|
|
146
146
|
it("skips reference-only lines in obligation sections", () => {
|
|
147
|
-
const md = `---
|
|
148
|
-
name: x
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Testing
|
|
152
|
-
|
|
153
|
-
Like (same shape as [\`test/ref.mjs\`](c:/x/y/test/ref.mjs)) for comparison.
|
|
147
|
+
const md = `---
|
|
148
|
+
name: x
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Testing
|
|
152
|
+
|
|
153
|
+
Like (same shape as [\`test/ref.mjs\`](c:/x/y/test/ref.mjs)) for comparison.
|
|
154
154
|
`;
|
|
155
155
|
expect(harvestQualifyingPathsFromPlan(md, {})).toEqual([]);
|
|
156
156
|
});
|
|
157
157
|
it("EG_BACKTICK: e.g. before backtick path skips harvest on that line", () => {
|
|
158
|
-
const md = `---
|
|
159
|
-
name: x
|
|
160
|
-
todos: []
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Testing
|
|
164
|
-
|
|
165
|
-
Illustrative only e.g. \`src/only-example.ts\`
|
|
158
|
+
const md = `---
|
|
159
|
+
name: x
|
|
160
|
+
todos: []
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Testing
|
|
164
|
+
|
|
165
|
+
Illustrative only e.g. \`src/only-example.ts\`
|
|
166
166
|
`;
|
|
167
167
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual([]);
|
|
168
168
|
});
|
|
169
169
|
it("FIXTURE_PHRASE: chosen in fixture skips harvest on that line", () => {
|
|
170
|
-
const md = `---
|
|
171
|
-
name: x
|
|
172
|
-
todos: []
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## Testing
|
|
176
|
-
|
|
177
|
-
Old/new paths chosen in fixture, see \`src/fixture-example.ts\`.
|
|
170
|
+
const md = `---
|
|
171
|
+
name: x
|
|
172
|
+
todos: []
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Testing
|
|
176
|
+
|
|
177
|
+
Old/new paths chosen in fixture, see \`src/fixture-example.ts\`.
|
|
178
178
|
`;
|
|
179
179
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual([]);
|
|
180
180
|
});
|
|
181
181
|
it("ISO-IMPL: implementation line without reference-only markers still harvests", () => {
|
|
182
|
-
const md = `---
|
|
183
|
-
name: x
|
|
184
|
-
todos: []
|
|
185
|
-
---
|
|
186
|
-
|
|
187
|
-
## Implementation
|
|
188
|
-
|
|
189
|
-
Touch \`src/required.ts\`.
|
|
182
|
+
const md = `---
|
|
183
|
+
name: x
|
|
184
|
+
todos: []
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Implementation
|
|
188
|
+
|
|
189
|
+
Touch \`src/required.ts\`.
|
|
190
190
|
`;
|
|
191
191
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual(["src/required.ts"]);
|
|
192
192
|
});
|
|
193
193
|
it("ADV-REF: seeded-from line yields no paths", () => {
|
|
194
|
-
const md = `---
|
|
195
|
-
name: x
|
|
196
|
-
todos: []
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Implementation
|
|
200
|
-
|
|
201
|
-
seeded from examples/seed.sql
|
|
194
|
+
const md = `---
|
|
195
|
+
name: x
|
|
196
|
+
todos: []
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Implementation
|
|
200
|
+
|
|
201
|
+
seeded from examples/seed.sql
|
|
202
202
|
`;
|
|
203
203
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual([]);
|
|
204
204
|
});
|
|
205
205
|
it("ADV-EXPECT: Testing section line containing Expect: yields no paths", () => {
|
|
206
|
-
const md = `---
|
|
207
|
-
name: x
|
|
208
|
-
todos: []
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## Testing
|
|
212
|
-
|
|
213
|
-
**Expect:** load from \`src/x.ts\` for the check.
|
|
206
|
+
const md = `---
|
|
207
|
+
name: x
|
|
208
|
+
todos: []
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Testing
|
|
212
|
+
|
|
213
|
+
**Expect:** load from \`src/x.ts\` for the check.
|
|
214
214
|
`;
|
|
215
215
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual([]);
|
|
216
216
|
});
|
|
217
217
|
it("ADV-FRAG: reference-only line after obligation line does not harvest second path", () => {
|
|
218
|
-
const md = `---
|
|
219
|
-
name: x
|
|
220
|
-
todos: []
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## Implementation
|
|
224
|
-
|
|
225
|
-
Improve \`src/a.ts\`.
|
|
226
|
-
|
|
227
|
-
Same pattern as \`src/b.ts\`.
|
|
218
|
+
const md = `---
|
|
219
|
+
name: x
|
|
220
|
+
todos: []
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Implementation
|
|
224
|
+
|
|
225
|
+
Improve \`src/a.ts\`.
|
|
226
|
+
|
|
227
|
+
Same pattern as \`src/b.ts\`.
|
|
228
228
|
`;
|
|
229
229
|
expect(harvestQualifyingPathsFromPlan(md, fmFromPlanMarkdown(md))).toEqual(["src/a.ts"]);
|
|
230
230
|
});
|
|
@@ -11,53 +11,53 @@ export class PostgresSchemaCatalog {
|
|
|
11
11
|
this.client = client;
|
|
12
12
|
}
|
|
13
13
|
async listTables() {
|
|
14
|
-
const r = await this.client.query(`SELECT c.relname AS table_name
|
|
15
|
-
FROM pg_catalog.pg_class c
|
|
16
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
17
|
-
WHERE n.nspname = 'public'
|
|
18
|
-
AND c.relkind = 'r'
|
|
19
|
-
AND NOT c.relispartition
|
|
20
|
-
AND pg_catalog.has_table_privilege(c.oid, 'SELECT')
|
|
14
|
+
const r = await this.client.query(`SELECT c.relname AS table_name
|
|
15
|
+
FROM pg_catalog.pg_class c
|
|
16
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
17
|
+
WHERE n.nspname = 'public'
|
|
18
|
+
AND c.relkind = 'r'
|
|
19
|
+
AND NOT c.relispartition
|
|
20
|
+
AND pg_catalog.has_table_privilege(c.oid, 'SELECT')
|
|
21
21
|
ORDER BY c.relname`);
|
|
22
22
|
return r.rows.map((x) => x.table_name);
|
|
23
23
|
}
|
|
24
24
|
async listColumns(table) {
|
|
25
|
-
const r = await this.client.query(`SELECT a.attname AS column_name
|
|
26
|
-
FROM pg_catalog.pg_attribute a
|
|
27
|
-
JOIN pg_catalog.pg_class c ON c.oid = a.attrelid
|
|
28
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
29
|
-
WHERE n.nspname = 'public'
|
|
30
|
-
AND c.relname = $1
|
|
31
|
-
AND c.relkind = 'r'
|
|
32
|
-
AND a.attnum > 0
|
|
33
|
-
AND NOT a.attisdropped
|
|
25
|
+
const r = await this.client.query(`SELECT a.attname AS column_name
|
|
26
|
+
FROM pg_catalog.pg_attribute a
|
|
27
|
+
JOIN pg_catalog.pg_class c ON c.oid = a.attrelid
|
|
28
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
29
|
+
WHERE n.nspname = 'public'
|
|
30
|
+
AND c.relname = $1
|
|
31
|
+
AND c.relkind = 'r'
|
|
32
|
+
AND a.attnum > 0
|
|
33
|
+
AND NOT a.attisdropped
|
|
34
34
|
ORDER BY a.attnum`, [table]);
|
|
35
35
|
return r.rows.map((x) => ({ name: x.column_name }));
|
|
36
36
|
}
|
|
37
37
|
async primaryKeyColumns(table) {
|
|
38
|
-
const r = await this.client.query(`SELECT a.attname AS column_name
|
|
39
|
-
FROM pg_catalog.pg_class c
|
|
40
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
41
|
-
JOIN pg_catalog.pg_index i ON i.indrelid = c.oid AND i.indisprimary
|
|
42
|
-
JOIN pg_catalog.pg_attribute a
|
|
43
|
-
ON a.attrelid = c.oid AND a.attnum = ANY (i.indkey) AND a.attnum > 0 AND NOT a.attisdropped
|
|
44
|
-
WHERE n.nspname = 'public'
|
|
45
|
-
AND c.relname = $1
|
|
38
|
+
const r = await this.client.query(`SELECT a.attname AS column_name
|
|
39
|
+
FROM pg_catalog.pg_class c
|
|
40
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
41
|
+
JOIN pg_catalog.pg_index i ON i.indrelid = c.oid AND i.indisprimary
|
|
42
|
+
JOIN pg_catalog.pg_attribute a
|
|
43
|
+
ON a.attrelid = c.oid AND a.attnum = ANY (i.indkey) AND a.attnum > 0 AND NOT a.attisdropped
|
|
44
|
+
WHERE n.nspname = 'public'
|
|
45
|
+
AND c.relname = $1
|
|
46
46
|
AND c.relkind = 'r'`, [table]);
|
|
47
47
|
return r.rows.map((x) => x.column_name);
|
|
48
48
|
}
|
|
49
49
|
async listUniqueConstraints(table) {
|
|
50
|
-
const r = await this.client.query(`SELECT cn.conname, a.attname, u.ord
|
|
51
|
-
FROM pg_catalog.pg_constraint cn
|
|
52
|
-
JOIN pg_catalog.pg_class c ON c.oid = cn.conrelid
|
|
53
|
-
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
54
|
-
JOIN LATERAL unnest(cn.conkey) WITH ORDINALITY AS u(attnum, ord) ON true
|
|
55
|
-
JOIN pg_catalog.pg_attribute a
|
|
56
|
-
ON a.attrelid = c.oid AND a.attnum = u.attnum AND NOT a.attisdropped
|
|
57
|
-
WHERE n.nspname = 'public'
|
|
58
|
-
AND c.relname = $1
|
|
59
|
-
AND c.relkind = 'r'
|
|
60
|
-
AND cn.contype = 'u'
|
|
50
|
+
const r = await this.client.query(`SELECT cn.conname, a.attname, u.ord
|
|
51
|
+
FROM pg_catalog.pg_constraint cn
|
|
52
|
+
JOIN pg_catalog.pg_class c ON c.oid = cn.conrelid
|
|
53
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
54
|
+
JOIN LATERAL unnest(cn.conkey) WITH ORDINALITY AS u(attnum, ord) ON true
|
|
55
|
+
JOIN pg_catalog.pg_attribute a
|
|
56
|
+
ON a.attrelid = c.oid AND a.attnum = u.attnum AND NOT a.attisdropped
|
|
57
|
+
WHERE n.nspname = 'public'
|
|
58
|
+
AND c.relname = $1
|
|
59
|
+
AND c.relkind = 'r'
|
|
60
|
+
AND cn.contype = 'u'
|
|
61
61
|
ORDER BY cn.conname, u.ord`, [table]);
|
|
62
62
|
const byName = new Map();
|
|
63
63
|
for (const row of r.rows) {
|
|
@@ -68,24 +68,24 @@ export class PostgresSchemaCatalog {
|
|
|
68
68
|
return [...byName.values()].map((columns) => ({ columns }));
|
|
69
69
|
}
|
|
70
70
|
async listFkEdges() {
|
|
71
|
-
const r = await this.client.query(`SELECT
|
|
72
|
-
cl.relname AS child_table,
|
|
73
|
-
a.attname AS child_column,
|
|
74
|
-
pr.relname AS parent_table,
|
|
75
|
-
pa.attname AS parent_column
|
|
76
|
-
FROM pg_catalog.pg_constraint cn
|
|
77
|
-
JOIN pg_catalog.pg_class cl ON cl.oid = cn.conrelid
|
|
78
|
-
JOIN pg_catalog.pg_namespace ns ON ns.oid = cl.relnamespace
|
|
79
|
-
JOIN pg_catalog.pg_class pr ON pr.oid = cn.confrelid AND pr.relkind = 'r'
|
|
80
|
-
JOIN LATERAL unnest(cn.conkey, cn.confkey) AS u(att_child, att_parent) ON true
|
|
81
|
-
JOIN pg_catalog.pg_attribute a
|
|
82
|
-
ON a.attrelid = cl.oid AND a.attnum = u.att_child AND NOT a.attisdropped
|
|
83
|
-
JOIN pg_catalog.pg_attribute pa
|
|
84
|
-
ON pa.attrelid = pr.oid AND pa.attnum = u.att_parent AND NOT pa.attisdropped
|
|
85
|
-
WHERE cn.contype = 'f'
|
|
86
|
-
AND ns.nspname = 'public'
|
|
87
|
-
AND pg_catalog.has_table_privilege(cl.oid, 'SELECT')
|
|
88
|
-
AND pg_catalog.has_table_privilege(pr.oid, 'SELECT')
|
|
71
|
+
const r = await this.client.query(`SELECT
|
|
72
|
+
cl.relname AS child_table,
|
|
73
|
+
a.attname AS child_column,
|
|
74
|
+
pr.relname AS parent_table,
|
|
75
|
+
pa.attname AS parent_column
|
|
76
|
+
FROM pg_catalog.pg_constraint cn
|
|
77
|
+
JOIN pg_catalog.pg_class cl ON cl.oid = cn.conrelid
|
|
78
|
+
JOIN pg_catalog.pg_namespace ns ON ns.oid = cl.relnamespace
|
|
79
|
+
JOIN pg_catalog.pg_class pr ON pr.oid = cn.confrelid AND pr.relkind = 'r'
|
|
80
|
+
JOIN LATERAL unnest(cn.conkey, cn.confkey) AS u(att_child, att_parent) ON true
|
|
81
|
+
JOIN pg_catalog.pg_attribute a
|
|
82
|
+
ON a.attrelid = cl.oid AND a.attnum = u.att_child AND NOT a.attisdropped
|
|
83
|
+
JOIN pg_catalog.pg_attribute pa
|
|
84
|
+
ON pa.attrelid = pr.oid AND pa.attnum = u.att_parent AND NOT pa.attisdropped
|
|
85
|
+
WHERE cn.contype = 'f'
|
|
86
|
+
AND ns.nspname = 'public'
|
|
87
|
+
AND pg_catalog.has_table_privilege(cl.oid, 'SELECT')
|
|
88
|
+
AND pg_catalog.has_table_privilege(pr.oid, 'SELECT')
|
|
89
89
|
ORDER BY cl.relname, a.attname, pr.relname, pa.attname`);
|
|
90
90
|
const out = [];
|
|
91
91
|
const seen = new Set();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentskeptic",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Green agent traces and tool success flags often hide missing or wrong database rows. AgentSkeptic runs read-only SQL at verification time against persisted state vs structured tool activity—not chat narratives.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$id": "https://agentskeptic.com/schemas/agent-run-record-v1.schema.json",
|
|
3
|
-
"title": "AgentRunRecordV1",
|
|
4
|
-
"type": "object",
|
|
5
|
-
"additionalProperties": false,
|
|
6
|
-
"required": ["schemaVersion", "runId", "workflowId", "producer", "verifiedAt", "artifacts"],
|
|
7
|
-
"properties": {
|
|
8
|
-
"schemaVersion": { "const": 1 },
|
|
9
|
-
"runId": { "type": "string", "minLength": 1 },
|
|
10
|
-
"workflowId": { "type": "string", "minLength": 1 },
|
|
11
|
-
"producer": {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"additionalProperties": false,
|
|
14
|
-
"required": ["name", "version"],
|
|
15
|
-
"properties": {
|
|
16
|
-
"name": { "type": "string", "minLength": 1 },
|
|
17
|
-
"version": { "type": "string", "minLength": 1 }
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"verifiedAt": { "type": "string", "format": "date-time" },
|
|
21
|
-
"customerId": { "type": "string" },
|
|
22
|
-
"capturedAt": { "type": "string", "format": "date-time" },
|
|
23
|
-
"artifacts": {
|
|
24
|
-
"type": "object",
|
|
25
|
-
"additionalProperties": false,
|
|
26
|
-
"required": ["workflowResult", "events"],
|
|
27
|
-
"properties": {
|
|
28
|
-
"workflowResult": {
|
|
29
|
-
"type": "object",
|
|
30
|
-
"additionalProperties": false,
|
|
31
|
-
"required": ["relativePath", "sha256", "byteLength"],
|
|
32
|
-
"properties": {
|
|
33
|
-
"relativePath": { "const": "workflow-result.json" },
|
|
34
|
-
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
35
|
-
"byteLength": { "type": "integer", "minimum": 0 }
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"events": {
|
|
39
|
-
"type": "object",
|
|
40
|
-
"additionalProperties": false,
|
|
41
|
-
"required": ["relativePath", "sha256", "byteLength"],
|
|
42
|
-
"properties": {
|
|
43
|
-
"relativePath": { "const": "events.ndjson" },
|
|
44
|
-
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
45
|
-
"byteLength": { "type": "integer", "minimum": 0 }
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$id": "https://agentskeptic.com/schemas/agent-run-record-v1.schema.json",
|
|
3
|
+
"title": "AgentRunRecordV1",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"additionalProperties": false,
|
|
6
|
+
"required": ["schemaVersion", "runId", "workflowId", "producer", "verifiedAt", "artifacts"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": { "const": 1 },
|
|
9
|
+
"runId": { "type": "string", "minLength": 1 },
|
|
10
|
+
"workflowId": { "type": "string", "minLength": 1 },
|
|
11
|
+
"producer": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"required": ["name", "version"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"name": { "type": "string", "minLength": 1 },
|
|
17
|
+
"version": { "type": "string", "minLength": 1 }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"verifiedAt": { "type": "string", "format": "date-time" },
|
|
21
|
+
"customerId": { "type": "string" },
|
|
22
|
+
"capturedAt": { "type": "string", "format": "date-time" },
|
|
23
|
+
"artifacts": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"required": ["workflowResult", "events"],
|
|
27
|
+
"properties": {
|
|
28
|
+
"workflowResult": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"required": ["relativePath", "sha256", "byteLength"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"relativePath": { "const": "workflow-result.json" },
|
|
34
|
+
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
35
|
+
"byteLength": { "type": "integer", "minimum": 0 }
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"events": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": false,
|
|
41
|
+
"required": ["relativePath", "sha256", "byteLength"],
|
|
42
|
+
"properties": {
|
|
43
|
+
"relativePath": { "const": "events.ndjson" },
|
|
44
|
+
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
45
|
+
"byteLength": { "type": "integer", "minimum": 0 }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$id": "https://agentskeptic.com/schemas/agent-run-record-v2.schema.json",
|
|
3
|
-
"title": "AgentRunRecordV2",
|
|
4
|
-
"type": "object",
|
|
5
|
-
"additionalProperties": false,
|
|
6
|
-
"required": ["schemaVersion", "runId", "workflowId", "producer", "verifiedAt", "artifacts"],
|
|
7
|
-
"properties": {
|
|
8
|
-
"schemaVersion": { "const": 2 },
|
|
9
|
-
"runId": { "type": "string", "minLength": 1 },
|
|
10
|
-
"workflowId": { "type": "string", "minLength": 1 },
|
|
11
|
-
"producer": {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"additionalProperties": false,
|
|
14
|
-
"required": ["name", "version"],
|
|
15
|
-
"properties": {
|
|
16
|
-
"name": { "type": "string", "minLength": 1 },
|
|
17
|
-
"version": { "type": "string", "minLength": 1 }
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"verifiedAt": { "type": "string", "format": "date-time" },
|
|
21
|
-
"customerId": { "type": "string" },
|
|
22
|
-
"capturedAt": { "type": "string", "format": "date-time" },
|
|
23
|
-
"artifacts": {
|
|
24
|
-
"type": "object",
|
|
25
|
-
"additionalProperties": false,
|
|
26
|
-
"required": ["workflowResult", "events", "workflowResultSignature"],
|
|
27
|
-
"properties": {
|
|
28
|
-
"workflowResult": {
|
|
29
|
-
"type": "object",
|
|
30
|
-
"additionalProperties": false,
|
|
31
|
-
"required": ["relativePath", "sha256", "byteLength"],
|
|
32
|
-
"properties": {
|
|
33
|
-
"relativePath": { "const": "workflow-result.json" },
|
|
34
|
-
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
35
|
-
"byteLength": { "type": "integer", "minimum": 0 }
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
"events": {
|
|
39
|
-
"type": "object",
|
|
40
|
-
"additionalProperties": false,
|
|
41
|
-
"required": ["relativePath", "sha256", "byteLength"],
|
|
42
|
-
"properties": {
|
|
43
|
-
"relativePath": { "const": "events.ndjson" },
|
|
44
|
-
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
45
|
-
"byteLength": { "type": "integer", "minimum": 0 }
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
"workflowResultSignature": {
|
|
49
|
-
"type": "object",
|
|
50
|
-
"additionalProperties": false,
|
|
51
|
-
"required": ["relativePath", "sha256", "byteLength"],
|
|
52
|
-
"properties": {
|
|
53
|
-
"relativePath": { "const": "workflow-result.sig.json" },
|
|
54
|
-
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
55
|
-
"byteLength": { "type": "integer", "minimum": 0 }
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$id": "https://agentskeptic.com/schemas/agent-run-record-v2.schema.json",
|
|
3
|
+
"title": "AgentRunRecordV2",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"additionalProperties": false,
|
|
6
|
+
"required": ["schemaVersion", "runId", "workflowId", "producer", "verifiedAt", "artifacts"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schemaVersion": { "const": 2 },
|
|
9
|
+
"runId": { "type": "string", "minLength": 1 },
|
|
10
|
+
"workflowId": { "type": "string", "minLength": 1 },
|
|
11
|
+
"producer": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"required": ["name", "version"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"name": { "type": "string", "minLength": 1 },
|
|
17
|
+
"version": { "type": "string", "minLength": 1 }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"verifiedAt": { "type": "string", "format": "date-time" },
|
|
21
|
+
"customerId": { "type": "string" },
|
|
22
|
+
"capturedAt": { "type": "string", "format": "date-time" },
|
|
23
|
+
"artifacts": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"required": ["workflowResult", "events", "workflowResultSignature"],
|
|
27
|
+
"properties": {
|
|
28
|
+
"workflowResult": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"required": ["relativePath", "sha256", "byteLength"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"relativePath": { "const": "workflow-result.json" },
|
|
34
|
+
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
35
|
+
"byteLength": { "type": "integer", "minimum": 0 }
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"events": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": false,
|
|
41
|
+
"required": ["relativePath", "sha256", "byteLength"],
|
|
42
|
+
"properties": {
|
|
43
|
+
"relativePath": { "const": "events.ndjson" },
|
|
44
|
+
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
45
|
+
"byteLength": { "type": "integer", "minimum": 0 }
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"workflowResultSignature": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"required": ["relativePath", "sha256", "byteLength"],
|
|
52
|
+
"properties": {
|
|
53
|
+
"relativePath": { "const": "workflow-result.sig.json" },
|
|
54
|
+
"sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
55
|
+
"byteLength": { "type": "integer", "minimum": 0 }
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|