atris 3.30.12 → 3.32.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.
Files changed (64) hide show
  1. package/AGENTS.md +16 -3
  2. package/FOR_AGENTS.md +81 -0
  3. package/README.md +6 -4
  4. package/atris/CLAUDE.md +8 -0
  5. package/atris/atris.md +51 -19
  6. package/atris/skills/README.md +1 -0
  7. package/atris/skills/blocks/SKILL.md +134 -0
  8. package/atris/skills/clawhub/philosophy-of-work/SKILL.md +56 -0
  9. package/atris/skills/youtube/SKILL.md +31 -11
  10. package/atris.md +15 -0
  11. package/ax +189 -7
  12. package/bin/atris.js +273 -225
  13. package/commands/autoland.js +379 -0
  14. package/commands/autopilot-front.js +273 -0
  15. package/commands/autopilot.js +94 -4
  16. package/commands/business.js +1 -1
  17. package/commands/clean.js +72 -9
  18. package/commands/codex-goal.js +72 -22
  19. package/commands/computer.js +48 -3
  20. package/commands/gm.js +1 -1
  21. package/commands/harvest.js +179 -0
  22. package/commands/init.js +22 -1
  23. package/commands/land.js +442 -0
  24. package/commands/loop-front.js +122 -4
  25. package/commands/member.js +551 -19
  26. package/commands/mission.js +3674 -278
  27. package/commands/play.js +1 -1
  28. package/commands/pulse.js +65 -7
  29. package/commands/run-front.js +144 -0
  30. package/commands/run.js +10 -7
  31. package/commands/sign.js +90 -0
  32. package/commands/strings.js +301 -0
  33. package/commands/task.js +782 -108
  34. package/commands/truth.js +171 -0
  35. package/commands/xp.js +32 -8
  36. package/commands/youtube.js +72 -5
  37. package/decks/README.md +6 -12
  38. package/lib/auto-accept-certified.js +10 -0
  39. package/lib/autoland.js +391 -0
  40. package/lib/context-gatherer.js +0 -8
  41. package/lib/mission-artifact.js +504 -0
  42. package/lib/mission-room.js +846 -0
  43. package/lib/next-moves.js +212 -6
  44. package/lib/operator-next.js +7 -0
  45. package/lib/pulse.js +78 -4
  46. package/lib/runner-command.js +51 -20
  47. package/lib/runs-prune.js +242 -0
  48. package/lib/task-db.js +19 -2
  49. package/lib/task-proof.js +1 -1
  50. package/package.json +4 -4
  51. package/decks/atris-seed-pitch-v3.json +0 -118
  52. package/decks/atris-seed-pitch-v4-skeleton.json +0 -106
  53. package/decks/atris-seed-pitch-v5.json +0 -109
  54. package/decks/atris-seed-pitch-v6.json +0 -137
  55. package/decks/atris-seed-pitch-v7.json +0 -133
  56. package/decks/mark-pincus-narrative.json +0 -102
  57. package/decks/mark-pincus-sourcery.json +0 -94
  58. package/decks/yash-applied-compute-detailed.json +0 -150
  59. package/decks/yash-applied-compute-generalist.json +0 -82
  60. package/decks/yash-applied-compute-narrative.json +0 -54
  61. package/lib/ax-chat-input.js +0 -164
  62. package/lib/ax-goal.js +0 -307
  63. package/lib/ax-prefs.js +0 -63
  64. package/lib/ax-shimmer.js +0 -63
@@ -14,6 +14,7 @@
14
14
  // atris loop status liveness, last tick, reward -> pulse.js
15
15
  // atris loop stop remove the durable heartbeat -> pulse.js
16
16
  // atris loop wiki wiki upkeep (the old `loop`) -> loop.js
17
+ // atris loop create-next create + claim the suggested task
17
18
  //
18
19
  // The loop reads ROADMAP.md for what to pursue.
19
20
 
@@ -21,6 +22,13 @@ function isFlag(arg) {
21
22
  return typeof arg === 'string' && arg.startsWith('-');
22
23
  }
23
24
 
25
+ function flagValue(argv, name) {
26
+ const index = argv.indexOf(name);
27
+ if (index === -1) return null;
28
+ const value = argv[index + 1];
29
+ return value && !isFlag(value) ? value : true;
30
+ }
31
+
24
32
  // Pure router: decide what `atris loop ...` means without executing anything.
25
33
  // Kept side-effect-free so it is trivially testable.
26
34
  function routeLoop(argv = []) {
@@ -36,6 +44,10 @@ function routeLoop(argv = []) {
36
44
  return { action: 'status' };
37
45
  case 'stop':
38
46
  return { action: 'stop' };
47
+ case 'create-next':
48
+ case 'claim-next':
49
+ case 'take-next':
50
+ return { action: 'create-next' };
39
51
  case 'wiki':
40
52
  // Forward the remaining args (e.g. --json, --limit=) to wiki upkeep.
41
53
  return { action: 'wiki', rest: argv.filter((a) => a.toLowerCase() !== 'wiki') };
@@ -57,7 +69,7 @@ function routeLoop(argv = []) {
57
69
  }
58
70
  }
59
71
 
60
- function renderLoopHome(route = { action: 'home' }) {
72
+ function renderLoopHome(route = { action: 'home' }, moves = []) {
61
73
  const lines = [
62
74
  '',
63
75
  'atris loop: the self-improvement loop',
@@ -73,6 +85,7 @@ function renderLoopHome(route = { action: 'home' }) {
73
85
  ' atris loop start run it now, here (local)',
74
86
  ' atris loop start --once one cycle, then stop',
75
87
  ' atris loop start --overnight install the durable heartbeat (~15m)',
88
+ ' atris loop start --overnight --hours 6',
76
89
  '',
77
90
  ' watch it',
78
91
  ' atris loop status liveness, last tick, reward',
@@ -85,6 +98,16 @@ function renderLoopHome(route = { action: 'home' }) {
85
98
  ' wiki upkeep is at: atris loop wiki',
86
99
  '',
87
100
  ];
101
+ if (Array.isArray(moves) && moves.length) {
102
+ lines.splice(lines.length - 2, 0, ' ranked next moves');
103
+ moves.slice(0, 3).forEach((move) => {
104
+ lines.splice(lines.length - 2, 0, ` [${move.source}] ${move.title}`);
105
+ });
106
+ lines.splice(lines.length - 2, 0, '');
107
+ }
108
+ lines.splice(lines.length - 2, 0, ' act on it');
109
+ lines.splice(lines.length - 2, 0, ' atris loop create-next create + claim the suggested task');
110
+ lines.splice(lines.length - 2, 0, '');
88
111
  if (route && route.unknown) {
89
112
  lines.splice(1, 0, ` (unknown: "${route.unknown}". here is the loop:)`);
90
113
  }
@@ -95,7 +118,11 @@ function renderLoopHome(route = { action: 'home' }) {
95
118
  }
96
119
 
97
120
  function printLoopHome(route) {
98
- console.log(renderLoopHome(route));
121
+ let moves = [];
122
+ try {
123
+ moves = require('../lib/next-moves').nextMoves(process.cwd(), 3);
124
+ } catch { /* next moves are optional on a fresh checkout */ }
125
+ console.log(renderLoopHome(route, moves));
99
126
  }
100
127
 
101
128
  // Parse the handful of local-run flags `atris loop start` forwards to run.js.
@@ -148,7 +175,7 @@ function printLocalRunSummary() {
148
175
  // Combined machine-readable status: the overnight pulse heartbeat and the local
149
176
  // runs in one object. Best-effort per engine so a missing one does not fail it.
150
177
  function loopStatusJson(root = process.cwd()) {
151
- const out = { ok: true, action: 'loop_status', pulse: null, local_runs: { count: 0, latest: null } };
178
+ const out = { ok: true, action: 'loop_status', pulse: null, local_runs: { count: 0, latest: null }, next_moves: [] };
152
179
  try {
153
180
  const lp = require('../lib/pulse');
154
181
  const { cronInstalled } = require('./pulse');
@@ -158,9 +185,88 @@ function loopStatusJson(root = process.cwd()) {
158
185
  try {
159
186
  out.local_runs = localRunSummary(require('./run').getRunLogDir());
160
187
  } catch { /* runs optional */ }
188
+ try {
189
+ out.next_moves = require('../lib/next-moves').nextMoves(root, 5);
190
+ } catch { /* next moves optional */ }
161
191
  return out;
162
192
  }
163
193
 
194
+ function loopSeedMove(root = process.cwd()) {
195
+ const moves = require('../lib/next-moves').nextMoves(root, 5);
196
+ const activeTask = moves.find((move) => move && move.source === 'task');
197
+ if (activeTask) return { ok: false, reason: 'active_task', move: activeTask, moves };
198
+ const seed = moves.find((move) => (
199
+ move
200
+ && move.source === 'mission'
201
+ && (
202
+ move.why === 'active mission has no concrete task queued'
203
+ || move.why === 'latest proof timeline suggested this self-improvement target'
204
+ )
205
+ ));
206
+ if (!seed) return { ok: false, reason: 'no_seed', moves };
207
+ return { ok: true, move: seed, moves };
208
+ }
209
+
210
+ function createNextLoopTask(argv = [], root = process.cwd(), options = {}) {
211
+ const shouldPrint = options.print !== false;
212
+ const json = argv.includes('--json');
213
+ const owner = flagValue(argv, '--as') || flagValue(argv, '--owner') || process.env.ATRIS_AGENT_ID || 'auto-improver';
214
+ const seed = loopSeedMove(root);
215
+ if (!seed.ok) {
216
+ const payload = { ok: false, action: 'create_next_skipped', reason: seed.reason, move: seed.move || null };
217
+ if (shouldPrint) {
218
+ if (json) console.log(JSON.stringify(payload, null, 2));
219
+ else if (seed.reason === 'active_task') console.log(`not created: active task already exists (${seed.move.ref || seed.move.title})`);
220
+ else console.log('not created: no loop seed is available');
221
+ }
222
+ return payload;
223
+ }
224
+
225
+ const note = `Goal: ${seed.move.title}. Files: inspect atris/MAP.md first, then the relevant code. Done: one bounded proof-backed self-improvement task is moved to Review. Check: focused verifier; git diff --check; atris clean --dry-run --json; atris brain compile --root . --verify.`;
226
+ const taskArgs = [
227
+ 'task',
228
+ 'delegate',
229
+ seed.move.title,
230
+ '--tag', 'loop',
231
+ '--claim',
232
+ '--as', String(owner),
233
+ '--note', note,
234
+ '--json',
235
+ ];
236
+ const { spawnSync } = require('child_process');
237
+ const path = require('path');
238
+ const cli = path.join(__dirname, '..', 'bin', 'atris.js');
239
+ const child = spawnSync(process.execPath, [cli, ...taskArgs], {
240
+ cwd: root,
241
+ encoding: 'utf8',
242
+ timeout: 20000,
243
+ env: { ...process.env, ATRIS_SKIP_UPDATE_CHECK: '1' },
244
+ });
245
+ if (child.status !== 0) {
246
+ const payload = { ok: false, action: 'create_next_failed', reason: 'task_delegate_failed', stderr: child.stderr, stdout: child.stdout };
247
+ if (shouldPrint) {
248
+ if (json) console.log(JSON.stringify(payload, null, 2));
249
+ else console.error(child.stderr || child.stdout || 'task creation failed');
250
+ }
251
+ return payload;
252
+ }
253
+ let delegated = null;
254
+ try { delegated = JSON.parse(child.stdout); } catch { delegated = null; }
255
+ const task = delegated && delegated.task ? delegated.task : null;
256
+ const payload = { ok: true, action: 'created_next', owner: String(owner), move: seed.move, task, delegated };
257
+ if (shouldPrint) {
258
+ if (json) {
259
+ console.log(JSON.stringify(payload, null, 2));
260
+ } else {
261
+ const ref = task?.display_id || task?.id || 'task';
262
+ console.log(`created next loop task: ${ref} ${seed.move.title}`);
263
+ console.log(`claimed by: ${owner}`);
264
+ console.log(`next: atris task show ${ref}`);
265
+ }
266
+ }
267
+ return payload;
268
+ }
269
+
164
270
  // The evidence that the loop is improving things: ROADMAP items it has handled,
165
271
  // what is in flight and queued, and the heartbeat's reward/verify trend. Pure of
166
272
  // console so it is testable.
@@ -170,7 +276,7 @@ function loopReport(root = process.cwd()) {
170
276
  try {
171
277
  roadmap = require('../lib/next-moves').roadmapItemsByState(root);
172
278
  } catch { /* roadmap optional */ }
173
- return { ok: true, action: 'loop_report', roadmap, pulse: status.pulse, local_runs: status.local_runs };
279
+ return { ok: true, action: 'loop_report', roadmap, next_moves: status.next_moves, pulse: status.pulse, local_runs: status.local_runs };
174
280
  }
175
281
 
176
282
  function renderLoopReport(rep) {
@@ -193,6 +299,11 @@ function renderLoopReport(rep) {
193
299
  lines.push(' next up:');
194
300
  r.open.slice(0, 4).forEach((t) => lines.push(` [ ] ${t}`));
195
301
  }
302
+ if (Array.isArray(rep.next_moves) && rep.next_moves.length) {
303
+ lines.push('');
304
+ lines.push(' ranked next:');
305
+ rep.next_moves.slice(0, 5).forEach((move) => lines.push(` [${move.source}] ${move.title}`));
306
+ }
196
307
  if (rep.pulse) {
197
308
  lines.push('');
198
309
  lines.push(` heartbeat: ${rep.pulse.total_ticks} ticks, reward ${rep.pulse.reward_sum}, verify ${rep.pulse.verify_pass}/${rep.pulse.verify_fail}`);
@@ -236,6 +347,11 @@ function loopFront(argv = []) {
236
347
  return Promise.resolve(0);
237
348
  }
238
349
 
350
+ case 'create-next': {
351
+ const result = createNextLoopTask(argv, process.cwd());
352
+ return Promise.resolve(result.ok ? 0 : 1);
353
+ }
354
+
239
355
  case 'status': {
240
356
  if (jsonFlag.length) {
241
357
  // One machine-readable object covering BOTH engines (overnight pulse
@@ -284,6 +400,8 @@ module.exports = {
284
400
  startLocalOptions,
285
401
  localRunSummary,
286
402
  loopStatusJson,
403
+ loopSeedMove,
404
+ createNextLoopTask,
287
405
  loopReport,
288
406
  renderLoopReport,
289
407
  loopFront,