atris 3.43.0 → 3.44.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/atris/skills/design/SKILL.md +7 -1
- package/atris/skills/engines/SKILL.md +44 -13
- package/atris/team/customer-lead/MEMBER.md +45 -0
- package/atris/team/customer-lead/SOUL.md +33 -0
- package/atris/team/customer-lead/START_HERE.md +7 -0
- package/atris/team/customer-lead/skills/customer-commitments/SKILL.md +45 -0
- package/atris/team/improver/MEMBER.md +33 -0
- package/bin/atris.js +36 -3
- package/commands/autoland.js +15 -1
- package/commands/caretaker.js +303 -0
- package/commands/clean.js +76 -0
- package/commands/engine-watch.js +212 -0
- package/commands/engine.js +99 -11
- package/commands/founder.js +304 -0
- package/commands/human-missions.js +844 -0
- package/commands/init.js +16 -7
- package/commands/mission.js +124 -69
- package/commands/slop.js +34 -3
- package/commands/task.js +51 -4
- package/commands/team.js +329 -13
- package/commands/verify.js +99 -6
- package/commands/worktree.js +119 -4
- package/lib/auto-accept-certified.js +302 -0
- package/lib/cloud-mission.js +59 -2
- package/lib/conductor-artifacts.js +1 -1
- package/lib/dispatch-scout.js +383 -0
- package/lib/engine-ask.js +645 -0
- package/lib/engine-job-lifecycle.js +65 -0
- package/lib/engine-receipt-sweep.js +98 -0
- package/lib/engine-registry.js +2 -2
- package/lib/engine-validate.js +374 -0
- package/lib/fleet.js +459 -106
- package/lib/known-commands.js +2 -2
- package/lib/member-alive.js +2 -2
- package/lib/policy-lessons.js +70 -0
- package/lib/receipt-evidence.js +56 -1
- package/lib/runner-command.js +1 -1
- package/lib/secret-gateway.js +588 -0
- package/lib/team-presence.js +13 -1
- package/lib/voice-gate.js +6 -0
- package/lib/wish-audit.js +5 -205
- package/lib/wish-delegate.js +5 -2
- package/package.json +6 -1
package/lib/known-commands.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const knownCommands = ['init', 'log', 'logs', 'wish', 'drill', 'dream', 'now', 'goal', 'wtf', 'orb', 'radar', 'stream', 'ctop', 'launchpad', 'status', 'analytics', 'visualize', 'brain', 'brainstorm', 'autopilot', 'run', '_start', 'plan', 'do', 'review', 'release',
|
|
3
|
+
const knownCommands = ['init', 'log', 'logs', 'wish', 'ask', 'approve', 'stop', 'ready', 'check', 'drill', 'dream', 'now', 'goal', 'wtf', 'founder', 'orb', 'radar', 'stream', 'ctop', 'launchpad', 'status', 'analytics', 'visualize', 'brain', 'brainstorm', 'autopilot', 'run', '_start', 'plan', 'do', 'review', 'release',
|
|
4
4
|
'activate', '_activate', 'agent', 'team', 'chat', 'fast', 'ax', 'console', 'serve', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', '_switch-session', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
|
|
5
5
|
'clean', 'close', 'harvest', 'verify', 'recover', 'search', 'scout', 'skill', 'member', 'codex-goal', 'app', 'apps', 'learn', 'lesson', 'taste', 'teach', 'plugin', 'experiments', 'bench', 'router', 'receipt', 'proof', 'openclaw', 'pull', 'push', 'watch', 'cloud', 'live', 'align', 'terminal', 'computer', 'diff', 'business', 'sync', 'youtube',
|
|
6
|
-
'ingest', 'query', 'lint', 'loop', 'pulse', 'task', 'mission', 'decide', 'agents', 'probe', 'worktree', 'land', 'autoland', 'drive', 'aeo', 'slop', 'voice', 'strings', 'write', 'security-review', 'secure', 'deck', 'site', 'theme', 'card', 'reel', 'improve', 'study', 'rainmaker', 'xp', 'play', 'gm', 'game', 'x', 'recap', 'report', 'signup', 'clarity', 'interview', 'meet', 'moves', 'unknowns', 'avail', 'sync-checkout',
|
|
6
|
+
'ingest', 'query', 'lint', 'loop', 'pulse', 'task', 'mission', 'decide', 'agents', 'probe', 'worktree', 'land', 'caretaker', 'autoland', 'drive', 'aeo', 'slop', 'voice', 'strings', 'write', 'security-review', 'secure', 'deck', 'site', 'theme', 'card', 'reel', 'improve', 'study', 'rainmaker', 'xp', 'play', 'gm', 'game', 'x', 'recap', 'report', 'signup', 'clarity', 'interview', 'meet', 'moves', 'unknowns', 'avail', 'sync-checkout',
|
|
7
7
|
'github', 'vercel', 'supabase', 'linear', 'stripe', 'gmail', 'calendar', 'twitter', 'slack', 'imessage', 'integrations', 'setup', 'clean-workspace', 'cw',
|
|
8
8
|
'fork', 'browse', 'publish', 'pack', 'sleep', 'wake', 'feedback', 'errors', 'wiki', 'code-review', 'cr', 'soul', 'fleet', 'fleet-report', 'loops', 'self-improve', 'compile', 'spaceship', 'truth', 'sign', 'engine', 'engines', 'feed', 'brief'];
|
|
9
9
|
|
package/lib/member-alive.js
CHANGED
|
@@ -84,7 +84,7 @@ function runMemberOperateScript(scriptPath, member, opts) {
|
|
|
84
84
|
args.push('--execute');
|
|
85
85
|
if (opts.confirmed) args.push('--confirm-autonomy-policy');
|
|
86
86
|
}
|
|
87
|
-
if (opts.agent
|
|
87
|
+
if (opts.agent) args.push('--agent', String(opts.agent));
|
|
88
88
|
if (opts.model) args.push('--model', String(opts.model));
|
|
89
89
|
if (opts.noPrime) args.push('--no-prime');
|
|
90
90
|
// Inherit stderr so member-operate progress lines reach the parent alive/loop process live.
|
|
@@ -194,7 +194,7 @@ function runAliveTick(name, opts = {}) {
|
|
|
194
194
|
execute: true,
|
|
195
195
|
confirmed: true,
|
|
196
196
|
maxWallSeconds: opts.maxWallSeconds,
|
|
197
|
-
agent: opts.agent ||
|
|
197
|
+
agent: opts.agent || null,
|
|
198
198
|
model: opts.model || null,
|
|
199
199
|
noPrime: true,
|
|
200
200
|
});
|
package/lib/policy-lessons.js
CHANGED
|
@@ -16,6 +16,7 @@ const POLICY_LESSONS_FILE = path.join('.atris', 'state', 'policy_lessons.json');
|
|
|
16
16
|
const CAREER_XP_RECEIPTS_FILE = path.join('.atris', 'state', 'career_xp_receipts.jsonl');
|
|
17
17
|
const TASK_EPISODES_FILE = path.join('.atris', 'state', 'task_episodes.jsonl');
|
|
18
18
|
const SCORECARDS_FILE = path.join('.atris', 'state', 'scorecards.jsonl');
|
|
19
|
+
const TYPED_LESSONS_FILE = path.join('atris', 'lessons.json');
|
|
19
20
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
20
21
|
|
|
21
22
|
// Review actors that are agents, not the human gate. Mining must split the
|
|
@@ -266,6 +267,74 @@ function policyHintsForProof(proofText, mined, root = process.cwd()) {
|
|
|
266
267
|
return hints;
|
|
267
268
|
}
|
|
268
269
|
|
|
270
|
+
function normalizeLessonPath(value) {
|
|
271
|
+
return String(value || '')
|
|
272
|
+
.trim()
|
|
273
|
+
.replace(/\\/g, '/')
|
|
274
|
+
.replace(/^\.\//, '')
|
|
275
|
+
.replace(/\/{2,}/g, '/')
|
|
276
|
+
.replace(/\/$/, '');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function lessonPathOverlaps(left, right) {
|
|
280
|
+
const lessonPath = normalizeLessonPath(left).toLowerCase();
|
|
281
|
+
const candidatePath = normalizeLessonPath(right).toLowerCase();
|
|
282
|
+
if (!lessonPath || !candidatePath) return false;
|
|
283
|
+
return lessonPath === candidatePath
|
|
284
|
+
|| lessonPath.startsWith(`${candidatePath}/`)
|
|
285
|
+
|| candidatePath.startsWith(`${lessonPath}/`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function readTypedPolicyLessons(root) {
|
|
289
|
+
try {
|
|
290
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(root, TYPED_LESSONS_FILE), 'utf8'));
|
|
291
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return [];
|
|
292
|
+
return Object.entries(parsed)
|
|
293
|
+
.filter(([id, lesson]) => id !== '_schema' && lesson && typeof lesson === 'object')
|
|
294
|
+
.map(([id, lesson]) => ({ id, ...lesson, source: 'typed_lessons' }));
|
|
295
|
+
} catch {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// A lesson is relevant to a landing only when its declared file scope overlaps
|
|
301
|
+
// the candidate's exact paths. Repo-wide or prose-only lessons remain advice,
|
|
302
|
+
// because running them as global blockers would make old debt stop new work.
|
|
303
|
+
function policyLessonsForFiles(files, mined, root = process.cwd()) {
|
|
304
|
+
const candidatePaths = (Array.isArray(files) ? files : [files])
|
|
305
|
+
.map(normalizeLessonPath)
|
|
306
|
+
.filter(Boolean);
|
|
307
|
+
if (!candidatePaths.length) return [];
|
|
308
|
+
const minedLessons = mined && Array.isArray(mined.lessons)
|
|
309
|
+
? mined.lessons.map((lesson) => ({ ...lesson, source: 'mined_policy' }))
|
|
310
|
+
: [];
|
|
311
|
+
// The typed sidecar is the promoted source. If a mined advisory later uses
|
|
312
|
+
// the same id, the promoted detector and file scope must win.
|
|
313
|
+
const combined = [...readTypedPolicyLessons(root), ...minedLessons];
|
|
314
|
+
const matches = [];
|
|
315
|
+
const seen = new Set();
|
|
316
|
+
for (const lesson of combined) {
|
|
317
|
+
const id = String(lesson && lesson.id || '').trim();
|
|
318
|
+
if (!id || seen.has(id)) continue;
|
|
319
|
+
const appliesTo = Array.isArray(lesson.applies_to)
|
|
320
|
+
? lesson.applies_to
|
|
321
|
+
: (Array.isArray(lesson.paths) ? lesson.paths : []);
|
|
322
|
+
const matchedPath = appliesTo.find((lessonPath) =>
|
|
323
|
+
candidatePaths.some((candidatePath) => lessonPathOverlaps(lessonPath, candidatePath)));
|
|
324
|
+
if (!matchedPath) continue;
|
|
325
|
+
seen.add(id);
|
|
326
|
+
matches.push({
|
|
327
|
+
id,
|
|
328
|
+
detector: typeof lesson.detector === 'string' ? lesson.detector.trim() : '',
|
|
329
|
+
lesson: String(lesson.lesson || lesson.text || '').trim(),
|
|
330
|
+
status: lesson.status || null,
|
|
331
|
+
source: lesson.source,
|
|
332
|
+
matched_path: normalizeLessonPath(matchedPath),
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
return matches;
|
|
336
|
+
}
|
|
337
|
+
|
|
269
338
|
function policyLessonsPath(root) {
|
|
270
339
|
return path.join(root, POLICY_LESSONS_FILE);
|
|
271
340
|
}
|
|
@@ -324,6 +393,7 @@ module.exports = {
|
|
|
324
393
|
loadHistory,
|
|
325
394
|
mineProofPolicy,
|
|
326
395
|
policyHintsForProof,
|
|
396
|
+
policyLessonsForFiles,
|
|
327
397
|
readPolicyLessons,
|
|
328
398
|
writePolicyLessons,
|
|
329
399
|
syncLessonsMd,
|
package/lib/receipt-evidence.js
CHANGED
|
@@ -122,4 +122,59 @@ function extractReceiptEvidence(proofText, root = process.cwd()) {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
// Resume short-circuit: when a tick already wrote its receipt but the mission
|
|
126
|
+
// record never advanced (interrupt between writeReceipt and saveMission), the
|
|
127
|
+
// next run would re-derive the same tick_index. Look up that completed receipt
|
|
128
|
+
// and reuse it instead of re-running the step.
|
|
129
|
+
function findCachedMissionStepReceipt(root, { missionId, tickIndex } = {}) {
|
|
130
|
+
const id = String(missionId || '').trim();
|
|
131
|
+
const idx = Number(tickIndex);
|
|
132
|
+
if (!id || !Number.isInteger(idx) || idx < 1) return null;
|
|
133
|
+
|
|
134
|
+
const runsDir = path.resolve(root, 'atris', 'runs');
|
|
135
|
+
let names;
|
|
136
|
+
try {
|
|
137
|
+
names = fs.readdirSync(runsDir).filter((name) => name.startsWith('mission-') && name.endsWith('.json'));
|
|
138
|
+
} catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let best = null;
|
|
143
|
+
for (const name of names) {
|
|
144
|
+
let parsed = null;
|
|
145
|
+
try {
|
|
146
|
+
parsed = JSON.parse(fs.readFileSync(path.join(runsDir, name), 'utf8'));
|
|
147
|
+
} catch {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (!parsed || parsed.mission_id !== id) continue;
|
|
151
|
+
const tick = parsed.result && parsed.result.tick;
|
|
152
|
+
if (!tick || Number(tick.tick_index) !== idx) continue;
|
|
153
|
+
// Only completed successful steps are safe to skip. Failed ticks stay
|
|
154
|
+
// eligible for a fresh attempt on resume.
|
|
155
|
+
if (tick.status !== 'ran') continue;
|
|
156
|
+
const atMs = Date.parse(tick.finished_at || parsed.at || '') || 0;
|
|
157
|
+
if (best && atMs < best.atMs) continue;
|
|
158
|
+
best = {
|
|
159
|
+
atMs,
|
|
160
|
+
receipt_path: path.join('atris', 'runs', name),
|
|
161
|
+
receipt: parsed,
|
|
162
|
+
tick,
|
|
163
|
+
verifier_result: parsed.result.verifier_result || null,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (!best) return null;
|
|
167
|
+
return {
|
|
168
|
+
receipt_path: best.receipt_path,
|
|
169
|
+
receipt: best.receipt,
|
|
170
|
+
tick: best.tick,
|
|
171
|
+
verifier_result: best.verifier_result,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
module.exports = {
|
|
176
|
+
extractReceiptEvidence,
|
|
177
|
+
receiptVerifierPassed,
|
|
178
|
+
findCachedMissionStepReceipt,
|
|
179
|
+
RECEIPT_PATH_PATTERN,
|
|
180
|
+
};
|
package/lib/runner-command.js
CHANGED