crewly 1.20.377 → 1.20.379
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/config/hooks/destructive-git-guard/guard.mjs +33 -4
- package/config/hooks/destructive-git-guard/local-gates.json +3 -2
- package/config/skills/agent/core/record-tl-verification/SKILL.md +39 -0
- package/config/skills/agent/core/record-tl-verification/execute.sh +71 -0
- package/config/skills/agent/core/record-tl-verification/execute.test.sh +56 -0
- package/dist/backend/backend/src/constants.d.ts +60 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +60 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.d.ts +17 -0
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.js +49 -0
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.routes.d.ts +2 -0
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.routes.js +5 -1
- package/dist/backend/backend/src/controllers/owner-receipt/owner-receipt.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js +3 -0
- package/dist/backend/backend/src/controllers/project-tickets/project-tickets.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +23 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +5 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts +22 -0
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js +64 -3
- package/dist/backend/backend/src/services/project-tickets/project-ticket-workflow.service.js.map +1 -1
- package/dist/backend/backend/src/services/project-tickets/ticket-routine-nudge.d.ts +59 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-routine-nudge.d.ts.map +1 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-routine-nudge.js +123 -0
- package/dist/backend/backend/src/services/project-tickets/ticket-routine-nudge.js.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.d.ts +173 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.js +263 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.js.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.loader.d.ts +35 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.loader.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.loader.js +47 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.loader.js.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.d.ts +39 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.js +93 -2
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.types.d.ts +2 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/owner-receipt/owner-receipt.types.js.map +1 -1
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.d.ts +110 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.js +243 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.js.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.loader.d.ts +27 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.loader.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.loader.js +45 -0
- package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.loader.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +60 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +60 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +5 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/frontend/dist/assets/{index-b4db6abe.js → index-19c47468.js} +76 -76
- package/frontend/dist/index.html +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verified-work spot-check (#1315, phase 1) — once a day, pick a few WorkItems
|
|
3
|
+
* that were verified in the last 24 hours and re-check that every file
|
|
4
|
+
* artifact recorded as their evidence still exists.
|
|
5
|
+
*
|
|
6
|
+
* Read-only: it never changes a WorkItem and never re-runs a command (that is
|
|
7
|
+
* a later phase). Evidence that is not a local file (URLs, commands, blocked
|
|
8
|
+
* reports) is counted as skipped, not as a pass or a failure. Pure apart from
|
|
9
|
+
* the injected file check and random source, so a day's sample is repeatable.
|
|
10
|
+
*
|
|
11
|
+
* @module services/v3/owner-receipt/verified-spot-check
|
|
12
|
+
*/
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
import { OWNER_RECEIPT_CONSTANTS, WORKTREE_CONSTANTS } from '../../../constants.js';
|
|
16
|
+
import { artifactBaseDirs } from '../../task-pool/completion-evidence.service.js';
|
|
17
|
+
/**
|
|
18
|
+
* Deterministic random source (mulberry32).
|
|
19
|
+
*
|
|
20
|
+
* @param seed - Any integer
|
|
21
|
+
* @returns Generator of numbers in [0, 1)
|
|
22
|
+
*/
|
|
23
|
+
export function seededRandom(seed) {
|
|
24
|
+
let a = seed >>> 0;
|
|
25
|
+
return () => {
|
|
26
|
+
a = (a + 0x6d2b79f5) >>> 0;
|
|
27
|
+
let t = a;
|
|
28
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
29
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
30
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Seed for a calendar day, so a second run on the same day picks the same items.
|
|
35
|
+
*
|
|
36
|
+
* @param now - The run time
|
|
37
|
+
* @returns Integer seed
|
|
38
|
+
*/
|
|
39
|
+
export function daySeed(now) {
|
|
40
|
+
const day = now.toISOString().slice(0, 10);
|
|
41
|
+
let h = 2166136261;
|
|
42
|
+
for (let i = 0; i < day.length; i++)
|
|
43
|
+
h = Math.imul(h ^ day.charCodeAt(i), 16777619);
|
|
44
|
+
return h >>> 0;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Split a WorkItem's recorded evidence into file artifacts to look at and a
|
|
48
|
+
* count of entries that are not checked.
|
|
49
|
+
*
|
|
50
|
+
* @param wi - WorkItem
|
|
51
|
+
* @param homeDir - Home directory for `~/`
|
|
52
|
+
* @returns Targets and the skipped count
|
|
53
|
+
*/
|
|
54
|
+
export function fileTargetsOf(wi, homeDir) {
|
|
55
|
+
const evidence = wi.output?.['evidence'];
|
|
56
|
+
const targets = [];
|
|
57
|
+
let skipped = 0;
|
|
58
|
+
if (!Array.isArray(evidence))
|
|
59
|
+
return { targets, skipped };
|
|
60
|
+
const bases = artifactBaseDirs(wi);
|
|
61
|
+
for (const entry of evidence) {
|
|
62
|
+
const e = (typeof entry === 'object' && entry !== null ? entry : {});
|
|
63
|
+
const raw = e['type'] === 'artifact' && typeof e['path'] === 'string' ? e['path'].trim() : '';
|
|
64
|
+
if (!raw) {
|
|
65
|
+
skipped += 1; // a command or a blocked report
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const scheme = /^([a-z][a-z0-9+.-]*:)\/\//i.exec(raw)?.[1]?.toLowerCase();
|
|
69
|
+
let local = raw;
|
|
70
|
+
if (scheme === 'file:') {
|
|
71
|
+
try {
|
|
72
|
+
local = fileURLToPath(raw);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
skipped += 1;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (scheme) {
|
|
80
|
+
skipped += 1; // http(s) or another URL: not a file on this machine
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
else if (raw === '~' || raw.startsWith('~/')) {
|
|
84
|
+
local = path.join(homeDir, raw.slice(1));
|
|
85
|
+
}
|
|
86
|
+
targets.push({ raw, candidates: path.isAbsolute(local) ? [local] : bases.map((b) => path.resolve(b, local)) });
|
|
87
|
+
}
|
|
88
|
+
return { targets, skipped };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The worktree root an absolute path lies in: the WorkItem's recorded
|
|
92
|
+
* worktree, else the directory after a known worktree marker.
|
|
93
|
+
*
|
|
94
|
+
* @param abs - Absolute artifact path
|
|
95
|
+
* @param wi - The WorkItem
|
|
96
|
+
* @returns The worktree root, or null when the path is outside any worktree
|
|
97
|
+
*/
|
|
98
|
+
export function worktreeRootOf(abs, wi) {
|
|
99
|
+
for (const base of artifactBaseDirsOfWorktree(wi)) {
|
|
100
|
+
if (abs === base || abs.startsWith(base + path.sep))
|
|
101
|
+
return base;
|
|
102
|
+
}
|
|
103
|
+
const norm = abs.split(path.sep).join('/');
|
|
104
|
+
for (const marker of OWNER_RECEIPT_CONSTANTS.VERIFIED_SPOT_CHECK.WORKTREE_MARKERS) {
|
|
105
|
+
const needle = `/${marker}/`;
|
|
106
|
+
const at = norm.indexOf(needle);
|
|
107
|
+
if (at < 0)
|
|
108
|
+
continue;
|
|
109
|
+
const rest = norm.slice(at + needle.length).split('/')[0];
|
|
110
|
+
if (rest)
|
|
111
|
+
return norm.slice(0, at + needle.length) + rest;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Recorded worktree paths of a WorkItem (`metadata.worktree.path` / `workdir`).
|
|
117
|
+
*
|
|
118
|
+
* @param wi - The WorkItem
|
|
119
|
+
* @returns Absolute paths
|
|
120
|
+
*/
|
|
121
|
+
function artifactBaseDirsOfWorktree(wi) {
|
|
122
|
+
const wt = (wi.metadata ?? {})[WORKTREE_CONSTANTS.METADATA_KEY];
|
|
123
|
+
if (typeof wt !== 'object' || wt === null)
|
|
124
|
+
return [];
|
|
125
|
+
const rec = wt;
|
|
126
|
+
return ['path', 'workdir'].map((k) => rec[k]).filter((v) => typeof v === 'string' && path.isAbsolute(v));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Run the spot-check.
|
|
130
|
+
*
|
|
131
|
+
* @param input - WorkItems, clock, team lookup, file check
|
|
132
|
+
* @returns What was sampled and what is missing
|
|
133
|
+
*/
|
|
134
|
+
export async function runSpotCheck(input) {
|
|
135
|
+
const C = OWNER_RECEIPT_CONSTANTS.VERIFIED_SPOT_CHECK;
|
|
136
|
+
const to = input.now.getTime();
|
|
137
|
+
const from = to - C.WINDOW_MS;
|
|
138
|
+
const homeDir = input.homeDir ?? '';
|
|
139
|
+
const eligible = [];
|
|
140
|
+
for (const wi of input.workItems) {
|
|
141
|
+
if (wi.status !== 'verified' || !wi.completedAt)
|
|
142
|
+
continue;
|
|
143
|
+
const t = Date.parse(wi.completedAt);
|
|
144
|
+
if (!Number.isFinite(t) || t < from || t > to)
|
|
145
|
+
continue;
|
|
146
|
+
const { targets, skipped } = fileTargetsOf(wi, homeDir);
|
|
147
|
+
if (targets.length === 0)
|
|
148
|
+
continue;
|
|
149
|
+
eligible.push({ wi, targets, skipped });
|
|
150
|
+
}
|
|
151
|
+
// Stable order first, so the same seed picks the same items.
|
|
152
|
+
eligible.sort((a, b) => a.wi.id.localeCompare(b.wi.id));
|
|
153
|
+
const rand = input.random ?? seededRandom(daySeed(input.now));
|
|
154
|
+
const picked = [...eligible];
|
|
155
|
+
for (let i = picked.length - 1; i > 0; i--) {
|
|
156
|
+
const j = Math.floor(rand() * (i + 1));
|
|
157
|
+
[picked[i], picked[j]] = [picked[j], picked[i]];
|
|
158
|
+
}
|
|
159
|
+
const sample = picked.slice(0, Math.max(0, input.sampleSize ?? C.SAMPLE_SIZE));
|
|
160
|
+
const result = {
|
|
161
|
+
at: input.now.toISOString(),
|
|
162
|
+
eligible: eligible.length,
|
|
163
|
+
sampled: sample.length,
|
|
164
|
+
artifactsChecked: 0,
|
|
165
|
+
skipped: 0,
|
|
166
|
+
worktreeCleaned: 0,
|
|
167
|
+
discrepancies: [],
|
|
168
|
+
};
|
|
169
|
+
for (const { wi, targets, skipped } of sample) {
|
|
170
|
+
result.skipped += skipped;
|
|
171
|
+
const team = (wi.target ? input.teamOf(wi.target) : null) ?? OWNER_RECEIPT_CONSTANTS.UNASSIGNED_TEAM;
|
|
172
|
+
for (const target of targets) {
|
|
173
|
+
if (target.candidates.length === 0) {
|
|
174
|
+
result.skipped += 1; // relative path and no project or worktree to resolve it against
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
result.artifactsChecked += 1;
|
|
178
|
+
let found = false;
|
|
179
|
+
for (const c of target.candidates) {
|
|
180
|
+
try {
|
|
181
|
+
if (await input.exists(c)) {
|
|
182
|
+
found = true;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// an unreadable path counts as not found
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (!found) {
|
|
191
|
+
// The janitor removes worktrees after merge: a file inside a worktree
|
|
192
|
+
// that is itself gone was cleaned, not lost.
|
|
193
|
+
let cleaned = true;
|
|
194
|
+
for (const c of target.candidates) {
|
|
195
|
+
const root = worktreeRootOf(c, wi);
|
|
196
|
+
let rootGone = false;
|
|
197
|
+
if (root) {
|
|
198
|
+
try {
|
|
199
|
+
rootGone = !(await input.exists(root));
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
rootGone = false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (!rootGone) {
|
|
206
|
+
cleaned = false; // outside any worktree, or its worktree still exists: really missing
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (cleaned) {
|
|
211
|
+
result.artifactsChecked -= 1;
|
|
212
|
+
result.skipped += 1;
|
|
213
|
+
result.worktreeCleaned += 1;
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (!found)
|
|
218
|
+
result.discrepancies.push({ workItemId: wi.id, team, artifactPath: target.raw });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* The owner line: always present, zero is said out loud. No WorkItem ids.
|
|
225
|
+
*
|
|
226
|
+
* @param r - The run
|
|
227
|
+
* @returns Slack mrkdwn, one to five lines
|
|
228
|
+
*/
|
|
229
|
+
export function renderSpotCheck(r) {
|
|
230
|
+
const d = r.discrepancies.length;
|
|
231
|
+
const noun = d === 1 ? 'discrepancy' : 'discrepancies';
|
|
232
|
+
const head = `*Spot-check of verified work:* ${r.sampled} sampled, ${d} ${noun}`;
|
|
233
|
+
if (r.sampled === 0)
|
|
234
|
+
return `${head} (nothing verified in the last day had a file to look at)`;
|
|
235
|
+
if (d === 0)
|
|
236
|
+
return head;
|
|
237
|
+
const max = OWNER_RECEIPT_CONSTANTS.VERIFIED_SPOT_CHECK.MAX_LISTED;
|
|
238
|
+
const lines = r.discrepancies.slice(0, max).map((x) => `• ${x.team}: \`${x.artifactPath}\` is gone`);
|
|
239
|
+
if (d > max)
|
|
240
|
+
lines.push(`• +${d - max} more`);
|
|
241
|
+
return [head, ...lines].join('\n');
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=verified-spot-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verified-spot-check.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/v3/owner-receipt/verified-spot-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loader for the verified-work spot-check (#1315): reads the WorkItems and the
|
|
3
|
+
* team index, checks files on the real disk, and hands them to the pure
|
|
4
|
+
* {@link runSpotCheck}.
|
|
5
|
+
*
|
|
6
|
+
* @module services/v3/owner-receipt/verified-spot-check.loader
|
|
7
|
+
*/
|
|
8
|
+
import type { WorkItem } from '../../../types/v2/work-item.types.js';
|
|
9
|
+
import { type SpotCheckResult } from './verified-spot-check.js';
|
|
10
|
+
/** Where the loader reads from. */
|
|
11
|
+
export interface SpotCheckLoaderDeps {
|
|
12
|
+
listWorkItems: () => Promise<WorkItem[]>;
|
|
13
|
+
/** session → team name */
|
|
14
|
+
loadTeamIndex: () => Promise<Map<string, string>>;
|
|
15
|
+
/** File check, injectable for tests; default is `fs.stat` */
|
|
16
|
+
exists?: (absolutePath: string) => Promise<boolean>;
|
|
17
|
+
/** Random source, injectable for tests */
|
|
18
|
+
random?: () => number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build the `loadSpotCheck` dependency of the owner receipt service.
|
|
22
|
+
*
|
|
23
|
+
* @param deps - Data sources
|
|
24
|
+
* @returns Function that runs the spot-check as of `now`
|
|
25
|
+
*/
|
|
26
|
+
export declare function createSpotCheckLoader(deps: SpotCheckLoaderDeps): (now: Date) => Promise<SpotCheckResult>;
|
|
27
|
+
//# sourceMappingURL=verified-spot-check.loader.d.ts.map
|
package/dist/backend/backend/src/services/v3/owner-receipt/verified-spot-check.loader.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verified-spot-check.loader.d.ts","sourceRoot":"","sources":["../../../../../../../backend/src/services/v3/owner-receipt/verified-spot-check.loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE9E,mCAAmC;AACnC,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACzC,0BAA0B;IAC1B,aAAa,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAiBD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,GAAG,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,eAAe,CAAC,CAYxG"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loader for the verified-work spot-check (#1315): reads the WorkItems and the
|
|
3
|
+
* team index, checks files on the real disk, and hands them to the pure
|
|
4
|
+
* {@link runSpotCheck}.
|
|
5
|
+
*
|
|
6
|
+
* @module services/v3/owner-receipt/verified-spot-check.loader
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'fs/promises';
|
|
9
|
+
import * as os from 'os';
|
|
10
|
+
import { runSpotCheck } from './verified-spot-check.js';
|
|
11
|
+
/**
|
|
12
|
+
* Whether anything exists at a path.
|
|
13
|
+
*
|
|
14
|
+
* @param p - Absolute path
|
|
15
|
+
* @returns True when `fs.stat` succeeds
|
|
16
|
+
*/
|
|
17
|
+
async function statExists(p) {
|
|
18
|
+
try {
|
|
19
|
+
await fs.stat(p);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the `loadSpotCheck` dependency of the owner receipt service.
|
|
28
|
+
*
|
|
29
|
+
* @param deps - Data sources
|
|
30
|
+
* @returns Function that runs the spot-check as of `now`
|
|
31
|
+
*/
|
|
32
|
+
export function createSpotCheckLoader(deps) {
|
|
33
|
+
return async (now) => {
|
|
34
|
+
const [workItems, teams] = await Promise.all([deps.listWorkItems(), deps.loadTeamIndex()]);
|
|
35
|
+
return runSpotCheck({
|
|
36
|
+
workItems,
|
|
37
|
+
now,
|
|
38
|
+
teamOf: (session) => teams.get(session) ?? null,
|
|
39
|
+
exists: deps.exists ?? statExists,
|
|
40
|
+
homeDir: os.homedir(),
|
|
41
|
+
...(deps.random ? { random: deps.random } : {}),
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=verified-spot-check.loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verified-spot-check.loader.js","sourceRoot":"","sources":["../../../../../../../backend/src/services/v3/owner-receipt/verified-spot-check.loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAwB,MAAM,0BAA0B,CAAC;AAa9E;;;;;GAKG;AACH,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,OAAO,KAAK,EAAE,GAAS,EAA4B,EAAE;QACnD,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QAC3F,OAAO,YAAY,CAAC;YAClB,SAAS;YACT,GAAG;YACH,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI;YAC/C,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,UAAU;YACjC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE;YACrB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -6176,6 +6176,45 @@ export declare const OWNER_RECEIPT_CONSTANTS: {
|
|
|
6176
6176
|
readonly OPTION_ON: "Turn on nightly — this format";
|
|
6177
6177
|
readonly OPTION_PER_ASK: "Keep per-ask format — every ask, one line each";
|
|
6178
6178
|
};
|
|
6179
|
+
/**
|
|
6180
|
+
* The weekly "how often agents pulled the owner in" line (#1387, first
|
|
6181
|
+
* slice). Specs: specs/owner-pulls-weekly.md.
|
|
6182
|
+
*/
|
|
6183
|
+
readonly PULLS_WEEKLY: {
|
|
6184
|
+
/** Local weekday it goes out with the receipt (0 = Sunday) */
|
|
6185
|
+
readonly REPORT_WEEKDAY: 0;
|
|
6186
|
+
/** The week counted: the 7 days before the report; compared with the 7 before that (ms) */
|
|
6187
|
+
readonly WINDOW_MS: number;
|
|
6188
|
+
/** Teams named on the line before "+N more" */
|
|
6189
|
+
readonly MAX_TEAMS: 3;
|
|
6190
|
+
/** Traces read for the owner-touch count (most recent first) */
|
|
6191
|
+
readonly MAX_TRACES: 500;
|
|
6192
|
+
};
|
|
6193
|
+
/**
|
|
6194
|
+
* Daily spot-check of verified WorkItems (#1315, phase 1): re-check that the
|
|
6195
|
+
* file artifacts recorded as evidence still exist. Never changes a WorkItem.
|
|
6196
|
+
*/
|
|
6197
|
+
readonly VERIFIED_SPOT_CHECK: {
|
|
6198
|
+
/** WorkItems sampled per day */
|
|
6199
|
+
readonly SAMPLE_SIZE: 5;
|
|
6200
|
+
/** Only items completed this recently are eligible (ms) */
|
|
6201
|
+
readonly WINDOW_MS: number;
|
|
6202
|
+
/** Discrepancies named on the owner line before "+N more" */
|
|
6203
|
+
readonly MAX_LISTED: 3;
|
|
6204
|
+
/**
|
|
6205
|
+
* Directory markers of agent worktrees the disk janitor removes after merge
|
|
6206
|
+
* (the segment after a marker is the worktree root). A missing file inside
|
|
6207
|
+
* a worktree that is gone is "worktree cleaned", not a discrepancy.
|
|
6208
|
+
*/
|
|
6209
|
+
readonly WORKTREE_MARKERS: readonly string[];
|
|
6210
|
+
};
|
|
6211
|
+
};
|
|
6212
|
+
/** How each pull kind reads on the owner's weekly line (#1387). */
|
|
6213
|
+
export declare const PULLS_WEEKLY_KIND_LABELS: {
|
|
6214
|
+
readonly decision: "decision needed";
|
|
6215
|
+
readonly review: "review or approval";
|
|
6216
|
+
readonly fyi: "FYI that did not need an answer";
|
|
6217
|
+
readonly stuck: "agent stuck or error";
|
|
6179
6218
|
};
|
|
6180
6219
|
/**
|
|
6181
6220
|
* Hours a ticket waits in 待验收 with no objection before silence accepts it
|
|
@@ -8843,6 +8882,27 @@ export declare const TICKET_HYGIENE_CONSTANTS: {
|
|
|
8843
8882
|
/** Entries in the per-ticket "already sent" memory are dropped after this long (days) */
|
|
8844
8883
|
readonly STATE_RETENTION_DAYS: 30;
|
|
8845
8884
|
};
|
|
8885
|
+
/**
|
|
8886
|
+
* Routine nudge (crewly#1034): when a ticket is verified done and its result
|
|
8887
|
+
* describes recurring work, the verifying lead gets ONE internal WorkItem
|
|
8888
|
+
* telling it to set a routine or say why not. Never creates the cron itself.
|
|
8889
|
+
*/
|
|
8890
|
+
export declare const TICKET_ROUTINE_NUDGE_CONSTANTS: {
|
|
8891
|
+
/** Kill switch: `0` turns the nudge off */
|
|
8892
|
+
readonly ENV_SWITCH: "CREWLY_TICKET_ROUTINE_NUDGE";
|
|
8893
|
+
/** `metadata.kind` of the nudge WorkItem */
|
|
8894
|
+
readonly METADATA_KIND: "ticket_routine_nudge";
|
|
8895
|
+
/** Prefix of the ticket Log line that marks the nudge as sent (also the dedupe key) */
|
|
8896
|
+
readonly LOG_MARKER: "routine nudge sent to";
|
|
8897
|
+
/** Actor written in the ticket Log */
|
|
8898
|
+
readonly ACTOR: "crewly-routine-nudge";
|
|
8899
|
+
/** Max characters of the result text scanned for a cadence */
|
|
8900
|
+
readonly MAX_SCAN_CHARS: 6000;
|
|
8901
|
+
/** Max characters of the matched sentence quoted in the nudge */
|
|
8902
|
+
readonly MAX_QUOTE_CHARS: 240;
|
|
8903
|
+
/** Max characters of the ticket title in the nudge */
|
|
8904
|
+
readonly TITLE_MAX_CHARS: 120;
|
|
8905
|
+
};
|
|
8846
8906
|
/**
|
|
8847
8907
|
* Drive mode v3 status briefing (specs/2026-10-09-drive-mode-v3.md §1): the
|
|
8848
8908
|
* compact per-team / per-agent snapshot this machine keeps up to date and
|