atris 3.30.1 → 3.30.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.
Files changed (67) 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 +717 -32
  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 +342 -66
  33. package/commands/xp.js +3 -0
  34. package/commands/youtube.js +221 -7
  35. package/decks/README.md +89 -0
  36. package/decks/archetype-catalog.json +180 -0
  37. package/decks/atris-antislop-pitch.json +48 -0
  38. package/decks/atris-archetypes-v2.json +83 -0
  39. package/decks/atris-one-loop-pitch.json +80 -0
  40. package/decks/atris-seed-pitch-v3.json +118 -0
  41. package/decks/atris-seed-pitch-v4-skeleton.json +106 -0
  42. package/decks/atris-seed-pitch-v5.json +109 -0
  43. package/decks/atris-seed-pitch-v6.json +137 -0
  44. package/decks/atris-seed-pitch-v7.json +133 -0
  45. package/decks/atris-single-shot-proof.json +74 -0
  46. package/decks/mark-pincus-narrative.json +102 -0
  47. package/decks/mark-pincus-sourcery.json +94 -0
  48. package/decks/yash-applied-compute-detailed.json +150 -0
  49. package/decks/yash-applied-compute-generalist.json +82 -0
  50. package/decks/yash-applied-compute-narrative.json +54 -0
  51. package/lib/ax-prefs.js +5 -12
  52. package/lib/chat-log-scan.js +377 -0
  53. package/lib/context-gatherer.js +35 -1
  54. package/lib/deck-compose.js +145 -0
  55. package/lib/deck-history.js +64 -0
  56. package/lib/deck-layout.js +169 -0
  57. package/lib/deck-review.js +431 -0
  58. package/lib/deck-schema.js +154 -0
  59. package/lib/file-ops.js +2 -2
  60. package/lib/functional-owner.js +189 -0
  61. package/lib/slides-deck.js +512 -58
  62. package/lib/task-db.js +109 -2
  63. package/package.json +2 -1
  64. package/templates/business-starter/team/START_HERE.md +12 -8
  65. package/utils/auth.js +4 -0
  66. package/utils/config.js +4 -0
  67. 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, resultTrace }) {
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, resultTrace }) {
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();
@@ -550,6 +560,12 @@ function readyTask(db, { id, actor, proof, lesson, nextTask, resultTrace }) {
550
560
  payload.result_trace = resultTrace;
551
561
  payload.result_packet = `TASK_RESULT_TRACE ${JSON.stringify(resultTrace)}`;
552
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
+ };
553
569
  const event = appendTaskEvent(db, {
554
570
  taskId: id,
555
571
  workspaceRoot: updated.workspace_root,
@@ -614,7 +630,9 @@ function reviseTask(db, { id, actor, note }) {
614
630
  revision_count: revisionCount,
615
631
  },
616
632
  });
617
- 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 };
618
636
  }
619
637
 
620
638
  function cleanStageText(value) {
@@ -1293,12 +1311,44 @@ function reviewOutcomeLabel(reward) {
1293
1311
  return 'revised';
1294
1312
  }
1295
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
+
1296
1344
  function taskEpisodeFromReview(row, event, payload) {
1297
1345
  const metadata = row.metadata || {};
1298
1346
  const rewardValue = Number(payload.reward);
1299
1347
  const hasProof = Boolean(String(payload.proof || '').trim());
1300
1348
  const label = reviewOutcomeLabel(payload.reward);
1301
1349
  const doneForXp = row.status === 'done';
1350
+ const landingSignal = reviewLandingSignal(metadata);
1351
+ const humanFeedback = humanFeedbackFromMetadata(metadata, label, payload);
1302
1352
  return {
1303
1353
  schema: 'atris.task_episode.v1',
1304
1354
  episode_id: event.event_id,
@@ -1325,6 +1375,9 @@ function taskEpisodeFromReview(row, event, payload) {
1325
1375
  proof: payload.proof,
1326
1376
  next_task_suggestion: payload.next_task,
1327
1377
  goal: goalSignalFromTaskMetadata(metadata),
1378
+ review_landing: landingSignal.landing,
1379
+ landing_quality: landingSignal.quality,
1380
+ human_feedback: humanFeedback,
1328
1381
  career_xp: {
1329
1382
  eligible: payload.career_xp_eligible === true && label === 'accepted' && hasProof && doneForXp,
1330
1383
  source: 'task_review',
@@ -1338,6 +1391,60 @@ function taskEpisodeFromReview(row, event, payload) {
1338
1391
  has_proof: hasProof,
1339
1392
  has_lesson: Boolean(String(payload.lesson || '').trim()),
1340
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,
1341
1448
  },
1342
1449
  };
1343
1450
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atris",
3
- "version": "3.30.1",
3
+ "version": "3.30.3",
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