atris 3.30.0 → 3.30.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.
Files changed (69) hide show
  1. package/AGENTS.md +6 -0
  2. package/atris/AGENTS.md +11 -0
  3. package/atris/CLAUDE.md +5 -0
  4. package/atris/atris.md +19 -4
  5. package/atris/policies/atris-design.md +71 -0
  6. package/atris/policies/design-seed.md +187 -0
  7. package/atris/skills/atris/SKILL.md +26 -3
  8. package/atris/skills/design/SKILL.md +3 -2
  9. package/atris/skills/loop/SKILL.md +5 -3
  10. package/atris/team/_template/MEMBER.md +19 -0
  11. package/atris.md +63 -23
  12. package/ax +1434 -1698
  13. package/bin/atris.js +5 -1
  14. package/commands/agent-spawn.js +2 -2
  15. package/commands/brain.js +92 -7
  16. package/commands/brainstorm.js +62 -22
  17. package/commands/business-sync.js +92 -8
  18. package/commands/business.js +13 -7
  19. package/commands/chat-scan.js +102 -0
  20. package/commands/computer.js +758 -15
  21. package/commands/deck.js +505 -105
  22. package/commands/init.js +6 -1
  23. package/commands/launchpad.js +638 -0
  24. package/commands/log-sync.js +44 -13
  25. package/commands/loop-front.js +290 -0
  26. package/commands/member.js +124 -3
  27. package/commands/mission.js +653 -30
  28. package/commands/pull.js +37 -28
  29. package/commands/pulse.js +11 -8
  30. package/commands/run.js +79 -39
  31. package/commands/sync.js +36 -17
  32. package/commands/task.js +1072 -89
  33. package/commands/workflow.js +6 -6
  34. package/commands/xp.js +13 -1
  35. package/commands/youtube.js +221 -7
  36. package/decks/README.md +89 -0
  37. package/decks/archetype-catalog.json +180 -0
  38. package/decks/atris-antislop-pitch.json +48 -0
  39. package/decks/atris-archetypes-v2.json +83 -0
  40. package/decks/atris-one-loop-pitch.json +80 -0
  41. package/decks/atris-seed-pitch-v3.json +118 -0
  42. package/decks/atris-seed-pitch-v4-skeleton.json +106 -0
  43. package/decks/atris-seed-pitch-v5.json +109 -0
  44. package/decks/atris-seed-pitch-v6.json +137 -0
  45. package/decks/atris-seed-pitch-v7.json +133 -0
  46. package/decks/atris-single-shot-proof.json +74 -0
  47. package/decks/mark-pincus-narrative.json +102 -0
  48. package/decks/mark-pincus-sourcery.json +94 -0
  49. package/decks/yash-applied-compute-detailed.json +150 -0
  50. package/decks/yash-applied-compute-generalist.json +82 -0
  51. package/decks/yash-applied-compute-narrative.json +54 -0
  52. package/lib/ax-prefs.js +5 -12
  53. package/lib/chat-log-scan.js +377 -0
  54. package/lib/context-gatherer.js +35 -1
  55. package/lib/deck-compose.js +145 -0
  56. package/lib/deck-history.js +64 -0
  57. package/lib/deck-layout.js +169 -0
  58. package/lib/deck-review.js +431 -0
  59. package/lib/deck-schema.js +154 -0
  60. package/lib/file-ops.js +3 -3
  61. package/lib/functional-owner.js +189 -0
  62. package/lib/journal.js +7 -73
  63. package/lib/slides-deck.js +512 -58
  64. package/lib/task-db.js +128 -11
  65. package/package.json +2 -1
  66. package/templates/business-starter/team/START_HERE.md +12 -8
  67. package/utils/auth.js +4 -0
  68. package/utils/config.js +4 -0
  69. package/atris/atrisDev.md +0 -717
package/lib/task-db.js CHANGED
@@ -501,7 +501,12 @@ function doneTask(db, { id, status, actor, allowReview = false, action, proof }
501
501
  return { updated: false };
502
502
  }
503
503
 
504
- function readyTask(db, { id, actor, proof, lesson, nextTask }) {
504
+ function cleanLandingText(value) {
505
+ const text = String(value || '').replace(/\s+/g, ' ').trim();
506
+ return text || null;
507
+ }
508
+
509
+ function readyTask(db, { id, actor, proof, lesson, nextTask, landing = {}, resultTrace }) {
505
510
  if (!id) throw new Error('id required');
506
511
  const text = String(proof || '').trim();
507
512
  if (!text) throw new Error('proof required');
@@ -520,6 +525,11 @@ function readyTask(db, { id, actor, proof, lesson, nextTask }) {
520
525
  metadata.latest_agent_proof = text;
521
526
  metadata.latest_agent_lesson = String(lesson || '').trim() || null;
522
527
  metadata.latest_agent_next_task = String(nextTask || '').trim() || null;
528
+ const landingInput = landing && typeof landing === 'object' ? landing : {};
529
+ for (const key of ['happened', 'checked', 'tested', 'decision']) {
530
+ const cleaned = cleanLandingText(landingInput[key]);
531
+ if (cleaned) metadata[`landing_${key}`] = cleaned;
532
+ }
523
533
  if (reviewPassCount >= AGENT_CERTIFICATION_REVIEW_PASSES) {
524
534
  metadata.agent_certified = true;
525
535
  metadata.agent_certified_at = new Date(now).toISOString();
@@ -537,20 +547,31 @@ function readyTask(db, { id, actor, proof, lesson, nextTask }) {
537
547
  `).run(now, JSON.stringify(metadata), id));
538
548
  if (result.changes !== 1) return { ready: false, reason: 'not_open_claimed_or_review' };
539
549
  const updated = getTask(db, id);
550
+ const payload = {
551
+ proof: text,
552
+ lesson: metadata.latest_agent_lesson,
553
+ next_task: metadata.latest_agent_next_task,
554
+ approval_status: 'pending',
555
+ review_pass_count: reviewPassCount,
556
+ agent_certified: metadata.agent_certified === true,
557
+ agent_certification_policy: metadata.agent_certification_policy || null,
558
+ };
559
+ if (resultTrace && typeof resultTrace === 'object') {
560
+ payload.result_trace = resultTrace;
561
+ payload.result_packet = `TASK_RESULT_TRACE ${JSON.stringify(resultTrace)}`;
562
+ }
563
+ payload.landing = {
564
+ happened: metadata.landing_happened || null,
565
+ checked: metadata.landing_checked || null,
566
+ tested: metadata.landing_tested || null,
567
+ decision: metadata.landing_decision || null,
568
+ };
540
569
  const event = appendTaskEvent(db, {
541
570
  taskId: id,
542
571
  workspaceRoot: updated.workspace_root,
543
572
  actor: actor || null,
544
573
  eventType: 'proof_ready',
545
- payload: {
546
- proof: text,
547
- lesson: metadata.latest_agent_lesson,
548
- next_task: metadata.latest_agent_next_task,
549
- approval_status: 'pending',
550
- review_pass_count: reviewPassCount,
551
- agent_certified: metadata.agent_certified === true,
552
- agent_certification_policy: metadata.agent_certification_policy || null,
553
- },
574
+ payload,
554
575
  });
555
576
  return { ready: true, event, row: updated };
556
577
  }
@@ -609,7 +630,9 @@ function reviseTask(db, { id, actor, note }) {
609
630
  revision_count: revisionCount,
610
631
  },
611
632
  });
612
- return { revised: true, event, row: updated };
633
+ const episode = taskEpisodeFromRevision(updated, event, event.payload);
634
+ appendTaskEpisode(updated.workspace_root, episode);
635
+ return { revised: true, event, row: updated, episode };
613
636
  }
614
637
 
615
638
  function cleanStageText(value) {
@@ -770,6 +793,9 @@ function stagePacketFromPayload(payload) {
770
793
  if (data.proof_needed) lines.push(`proof_needed: ${data.proof_needed}`);
771
794
  if (data.first_move) lines.push(`first_move: ${data.first_move}`);
772
795
  if (data.next_button) lines.push(`next_button: ${data.next_button}`);
796
+ if (data.plan_trace && typeof data.plan_trace === 'object') {
797
+ lines.push(`TASK_PLAN_TRACE ${JSON.stringify(data.plan_trace)}`);
798
+ }
773
799
  return lines.filter(Boolean).join('\n');
774
800
  }
775
801
 
@@ -797,6 +823,7 @@ function stageTask(db, {
797
823
  firstMove,
798
824
  nextButton,
799
825
  confidence,
826
+ planTrace,
800
827
  }) {
801
828
  if (!id) throw new Error('id required');
802
829
  const targetStage = cleanStageText(stage).toLowerCase();
@@ -1015,6 +1042,7 @@ function stageTask(db, {
1015
1042
  first_move: cleanStageText(firstMove) || null,
1016
1043
  next_button: metadata.next_button || null,
1017
1044
  confidence: Number.isFinite(confidenceValue) ? metadata.stage_confidence : null,
1045
+ plan_trace: targetStage === 'plan' && planTrace && typeof planTrace === 'object' ? planTrace : null,
1018
1046
  };
1019
1047
  payload.stage_packet = stagePacketFromPayload(payload);
1020
1048
  const updated = getTask(db, id);
@@ -1283,12 +1311,44 @@ function reviewOutcomeLabel(reward) {
1283
1311
  return 'revised';
1284
1312
  }
1285
1313
 
1314
+ function reviewLandingSignal(metadata) {
1315
+ const landing = {
1316
+ happened: compactEpisodeText(metadata.landing_happened, 220),
1317
+ checked: compactEpisodeText(metadata.landing_checked, 220),
1318
+ tested: compactEpisodeText(metadata.landing_tested, 260),
1319
+ decision: compactEpisodeText(metadata.landing_decision, 220),
1320
+ };
1321
+ const present = Object.entries(landing)
1322
+ .filter(([, value]) => Boolean(value))
1323
+ .map(([key]) => key);
1324
+ const missing = Object.keys(landing).filter(key => !landing[key]);
1325
+ return {
1326
+ landing: present.length ? landing : null,
1327
+ quality: {
1328
+ present,
1329
+ missing,
1330
+ completeness: present.length / Object.keys(landing).length,
1331
+ has_decision: Boolean(landing.decision),
1332
+ },
1333
+ };
1334
+ }
1335
+
1336
+ function humanFeedbackFromMetadata(metadata, label, payload = {}) {
1337
+ return {
1338
+ approval_status: metadata.approval_status || (label === 'accepted' ? 'accepted' : label),
1339
+ human_revision_count: Number(metadata.human_revision_count || 0),
1340
+ human_revision_note: metadata.human_revision_note || payload.note || null,
1341
+ };
1342
+ }
1343
+
1286
1344
  function taskEpisodeFromReview(row, event, payload) {
1287
1345
  const metadata = row.metadata || {};
1288
1346
  const rewardValue = Number(payload.reward);
1289
1347
  const hasProof = Boolean(String(payload.proof || '').trim());
1290
1348
  const label = reviewOutcomeLabel(payload.reward);
1291
1349
  const doneForXp = row.status === 'done';
1350
+ const landingSignal = reviewLandingSignal(metadata);
1351
+ const humanFeedback = humanFeedbackFromMetadata(metadata, label, payload);
1292
1352
  return {
1293
1353
  schema: 'atris.task_episode.v1',
1294
1354
  episode_id: event.event_id,
@@ -1315,6 +1375,9 @@ function taskEpisodeFromReview(row, event, payload) {
1315
1375
  proof: payload.proof,
1316
1376
  next_task_suggestion: payload.next_task,
1317
1377
  goal: goalSignalFromTaskMetadata(metadata),
1378
+ review_landing: landingSignal.landing,
1379
+ landing_quality: landingSignal.quality,
1380
+ human_feedback: humanFeedback,
1318
1381
  career_xp: {
1319
1382
  eligible: payload.career_xp_eligible === true && label === 'accepted' && hasProof && doneForXp,
1320
1383
  source: 'task_review',
@@ -1328,6 +1391,60 @@ function taskEpisodeFromReview(row, event, payload) {
1328
1391
  has_proof: hasProof,
1329
1392
  has_lesson: Boolean(String(payload.lesson || '').trim()),
1330
1393
  has_next_task: Boolean(String(payload.next_task || '').trim()),
1394
+ landing_completeness: landingSignal.quality.completeness,
1395
+ approval_status: humanFeedback.approval_status,
1396
+ },
1397
+ };
1398
+ }
1399
+
1400
+ function taskEpisodeFromRevision(row, event, payload) {
1401
+ const metadata = row.metadata || {};
1402
+ const landingSignal = reviewLandingSignal(metadata);
1403
+ const humanFeedback = humanFeedbackFromMetadata(metadata, 'revise', payload);
1404
+ return {
1405
+ schema: 'atris.task_episode.v1',
1406
+ episode_id: event.event_id,
1407
+ task_id: row.id,
1408
+ workspace_root: row.workspace_root,
1409
+ created_at: new Date(event.created_at).toISOString(),
1410
+ state: {
1411
+ title: row.title,
1412
+ status: row.status,
1413
+ tag: row.tag,
1414
+ claimed_by: row.claimed_by,
1415
+ metadata,
1416
+ },
1417
+ action: {
1418
+ event_type: 'revision_requested',
1419
+ actor: event.actor || null,
1420
+ version: event.version,
1421
+ },
1422
+ reward: {
1423
+ value: 0,
1424
+ source: 'task_revision',
1425
+ },
1426
+ lesson: '',
1427
+ proof: null,
1428
+ next_task_suggestion: null,
1429
+ goal: goalSignalFromTaskMetadata(metadata),
1430
+ review_landing: landingSignal.landing,
1431
+ landing_quality: landingSignal.quality,
1432
+ human_feedback: humanFeedback,
1433
+ career_xp: {
1434
+ eligible: false,
1435
+ source: 'task_revision',
1436
+ reward: 0,
1437
+ proof_required: true,
1438
+ },
1439
+ rl: {
1440
+ label: 'rework_requested',
1441
+ source: 'task_revision',
1442
+ reward: 0,
1443
+ has_proof: false,
1444
+ has_lesson: false,
1445
+ has_next_task: false,
1446
+ landing_completeness: landingSignal.quality.completeness,
1447
+ approval_status: humanFeedback.approval_status,
1331
1448
  },
1332
1449
  };
1333
1450
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atris",
3
- "version": "3.30.0",
3
+ "version": "3.30.2",
4
4
  "main": "bin/atris.js",
5
5
  "bin": {
6
6
  "atris": "bin/atris.js",
@@ -11,6 +11,7 @@
11
11
  "bin/",
12
12
  "cli/*.py",
13
13
  "commands/",
14
+ "decks/",
14
15
  "utils/",
15
16
  "lib/",
16
17
  "templates/",
@@ -4,14 +4,15 @@ Use this when a collaborator opens the shared business workspace for the first t
4
4
 
5
5
  ## Default Path
6
6
 
7
- 1. Run `atris business start` from the workspace root.
8
- 2. Run `atris radar` to see agents, tasks, missions, XP, team lanes, and proof state.
9
- 3. Claim the seeded first task with `atris task next`.
10
- 4. Wake `operator` with `atris member activate operator`.
11
- 5. Resume an active mission, or start the first bounded loop if none exists.
12
- 6. Execute the loop with `atris do`.
13
- 7. Use `ops`, `research`, or `comms` only when the next loop needs that lens.
14
- 8. Ask `validator` to check proof before reward, launch, external send, or spend.
7
+ 1. Run `atris sync --dry-run` if this workspace has cloud IDs.
8
+ 2. Run `atris business start` from the workspace root.
9
+ 3. Run `atris radar` to see agents, tasks, missions, XP, team lanes, and proof state.
10
+ 4. Claim the seeded first task with `atris task next`.
11
+ 5. Wake `operator` with `atris member activate operator`.
12
+ 6. Resume an active mission, or start the first bounded loop if none exists.
13
+ 7. Execute the loop with `atris do`.
14
+ 8. Use `ops`, `research`, or `comms` only when the next loop needs that lens.
15
+ 9. Ask `validator` to check proof before reward, launch, external send, or spend.
15
16
 
16
17
  ## Mission Loop
17
18
 
@@ -40,6 +41,9 @@ Record the first real run with:
40
41
  ```bash
41
42
  atris business record atris/reports/<recap>.md --outcome mixed --metric "operator speed"
42
43
  atris business share --write
44
+ atris sync
43
45
  ```
44
46
 
47
+ Use `atris sync --watch` while actively collaborating in a cloud-backed workspace.
48
+
45
49
  No XP or external action until a human approves the proof.
package/utils/auth.js CHANGED
@@ -46,6 +46,10 @@ function promptUser(question) {
46
46
  let data = '';
47
47
  process.stdin.setEncoding('utf8');
48
48
  process.stdin.on('data', chunk => data += chunk);
49
+ process.stdin.on('error', () => {
50
+ inputLines = [];
51
+ resolve('');
52
+ });
49
53
  process.stdin.on('end', () => {
50
54
  inputLines = data.trim().split('\n');
51
55
  process.stdout.write(question);
package/utils/config.js CHANGED
@@ -77,6 +77,10 @@ function loadLogSyncState() {
77
77
  */
78
78
  function saveLogSyncState(state) {
79
79
  const statePath = getLogSyncStatePath();
80
+ const targetDir = path.dirname(statePath);
81
+ if (!fs.existsSync(targetDir)) {
82
+ fs.mkdirSync(targetDir, { recursive: true });
83
+ }
80
84
  fs.writeFileSync(statePath, JSON.stringify(state, null, 2));
81
85
  }
82
86