atris 3.15.46 → 3.15.48
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/AGENTS.md +2 -2
- package/atris/skills/atris/SKILL.md +1 -1
- package/bin/atris.js +10 -4
- package/commands/business.js +574 -21
- package/commands/mission.js +16 -1
- package/commands/radar.js +546 -0
- package/commands/sync.js +101 -1
- package/lib/task-db.js +29 -3
- package/package.json +2 -1
- package/templates/business-starter/MAP.md +1 -0
- package/templates/business-starter/team/README.md +3 -0
- package/templates/business-starter/team/START_HERE.md +45 -0
package/commands/sync.js
CHANGED
|
@@ -172,6 +172,85 @@ function ensureWorkspaceStateFiles(targetRoot, params, options = {}) {
|
|
|
172
172
|
return created;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
function renderBusinessAgentAdapter(bizMeta = {}, targetRoot = '.') {
|
|
176
|
+
const name = bizMeta.name || bizMeta.slug || 'this business';
|
|
177
|
+
const slug = bizMeta.slug || 'business';
|
|
178
|
+
const rootHint = targetRoot || '.';
|
|
179
|
+
return [
|
|
180
|
+
`# AGENTS.md - ${name} Atris Workspace`,
|
|
181
|
+
'',
|
|
182
|
+
`You are operating inside the shared Atris workspace for ${name} (${slug}).`,
|
|
183
|
+
'',
|
|
184
|
+
'## Start Here',
|
|
185
|
+
'',
|
|
186
|
+
'Run these first from the workspace root:',
|
|
187
|
+
'',
|
|
188
|
+
'```bash',
|
|
189
|
+
'atris',
|
|
190
|
+
'atris business start',
|
|
191
|
+
'atris radar',
|
|
192
|
+
'atris task next',
|
|
193
|
+
'atris member activate operator',
|
|
194
|
+
'```',
|
|
195
|
+
'',
|
|
196
|
+
'If no active mission exists, start the first bounded business loop:',
|
|
197
|
+
'',
|
|
198
|
+
'```bash',
|
|
199
|
+
'atris mission status --status active --json',
|
|
200
|
+
`atris mission start "Run the first useful loop for ${name}" --owner operator --runner codex_goal --lane business --verify "atris business check" --stop "first proof recap recorded"`,
|
|
201
|
+
'atris member goal-from-mission operator',
|
|
202
|
+
'atris do',
|
|
203
|
+
'```',
|
|
204
|
+
'',
|
|
205
|
+
'## Core Files',
|
|
206
|
+
'',
|
|
207
|
+
'| File | Purpose |',
|
|
208
|
+
'|------|---------|',
|
|
209
|
+
'| `atris/atris.md` | Workspace boot protocol |',
|
|
210
|
+
'| `atris/MAP.md` | Navigation and where-is-X index |',
|
|
211
|
+
'| `.atris/state/tasks.projection.json` | Current task projection |',
|
|
212
|
+
'| `atris/TODO.md` | Rendered task fallback only |',
|
|
213
|
+
'| `atris/team/START_HERE.md` | Team lanes and first-run flow |',
|
|
214
|
+
'| `atris/wiki/` | Business context and source-backed briefs |',
|
|
215
|
+
'| `atris/reports/` | Proof recaps and share handoffs |',
|
|
216
|
+
'',
|
|
217
|
+
'## Rules',
|
|
218
|
+
'',
|
|
219
|
+
'- Check `atris/MAP.md` before broad code or file search.',
|
|
220
|
+
'- Use `atris task` for ownership, notes, proof, and review state.',
|
|
221
|
+
'- Use `atris mission` when work should survive the current chat.',
|
|
222
|
+
'- Put completed agent work in Review with `atris task ready <id> --proof "<receipt>".`',
|
|
223
|
+
'- Do not run `atris task accept` or claim XP unless a human approved the proof.',
|
|
224
|
+
'- Do not mix another business into this workspace.',
|
|
225
|
+
'- No external sends, spend, or launches without operator approval.',
|
|
226
|
+
'',
|
|
227
|
+
'## Proof Loop',
|
|
228
|
+
'',
|
|
229
|
+
'```bash',
|
|
230
|
+
'atris business check',
|
|
231
|
+
'atris business record atris/reports/<recap>.md --outcome mixed --metric "operator speed"',
|
|
232
|
+
'atris business share --write',
|
|
233
|
+
'```',
|
|
234
|
+
'',
|
|
235
|
+
`Workspace root at creation: ${rootHint}`,
|
|
236
|
+
'',
|
|
237
|
+
].join('\n');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function ensureBusinessRootAgentAdapters(targetRoot, bizMeta = {}, options = {}) {
|
|
241
|
+
const dryRun = options.dryRun === true;
|
|
242
|
+
const written = [];
|
|
243
|
+
const adapter = renderBusinessAgentAdapter(bizMeta, targetRoot);
|
|
244
|
+
const files = ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md'];
|
|
245
|
+
for (const file of files) {
|
|
246
|
+
const fullPath = path.join(targetRoot, file);
|
|
247
|
+
if (fs.existsSync(fullPath)) continue;
|
|
248
|
+
written.push(file);
|
|
249
|
+
if (!dryRun) fs.writeFileSync(fullPath, adapter, 'utf8');
|
|
250
|
+
}
|
|
251
|
+
return written;
|
|
252
|
+
}
|
|
253
|
+
|
|
175
254
|
/**
|
|
176
255
|
* Sync canonical business template files into a business workspace.
|
|
177
256
|
* Used when .atris/business.json is present (business mode).
|
|
@@ -243,6 +322,7 @@ function syncWorkspaceTemplate(targetRoot, bizMeta, options = {}) {
|
|
|
243
322
|
}
|
|
244
323
|
|
|
245
324
|
const stateAddedList = ensureWorkspaceStateFiles(targetRoot, params, { dryRun });
|
|
325
|
+
const agentAdapterList = ensureBusinessRootAgentAdapters(targetRoot, params, { dryRun });
|
|
246
326
|
|
|
247
327
|
// Skills: sync the canonical skill set from atris-cli package into the
|
|
248
328
|
// customer workspace. Business-starter template ships skill infra (README,
|
|
@@ -277,16 +357,34 @@ function syncWorkspaceTemplate(targetRoot, bizMeta, options = {}) {
|
|
|
277
357
|
stateAddedList.forEach(p => console.log(` + ${p}`));
|
|
278
358
|
console.log('');
|
|
279
359
|
}
|
|
360
|
+
if (agentAdapterList.length > 0) {
|
|
361
|
+
console.log(' Root agent adapters:');
|
|
362
|
+
agentAdapterList.forEach(p => console.log(` + ${p}`));
|
|
363
|
+
console.log('');
|
|
364
|
+
}
|
|
280
365
|
|
|
281
366
|
if (dryRun) {
|
|
282
367
|
console.log(' (--dry-run, no changes made)');
|
|
283
|
-
} else if (added === 0 && updated === 0 && stateAddedList.length === 0) {
|
|
368
|
+
} else if (added === 0 && updated === 0 && stateAddedList.length === 0 && agentAdapterList.length === 0) {
|
|
284
369
|
ensureWikiScaffold(targetRoot);
|
|
285
370
|
console.log(' ✓ Already up to date');
|
|
286
371
|
} else {
|
|
287
372
|
ensureWikiScaffold(targetRoot);
|
|
288
373
|
console.log(` ✓ Local workspace updated. Run \`atris align ${params.slug} --fix\` to push to EC2.`);
|
|
289
374
|
}
|
|
375
|
+
|
|
376
|
+
return {
|
|
377
|
+
added,
|
|
378
|
+
updated,
|
|
379
|
+
preserved,
|
|
380
|
+
skipped,
|
|
381
|
+
skillsUpdated,
|
|
382
|
+
addedList,
|
|
383
|
+
updatedList,
|
|
384
|
+
preservedList,
|
|
385
|
+
stateAddedList,
|
|
386
|
+
agentAdapterList,
|
|
387
|
+
};
|
|
290
388
|
}
|
|
291
389
|
|
|
292
390
|
function syncBusinessCanonical(targetRoot, bizMeta, options = {}) {
|
|
@@ -862,4 +960,6 @@ module.exports = {
|
|
|
862
960
|
syncWorkspaceTemplate,
|
|
863
961
|
resolveWorkspaceTemplate,
|
|
864
962
|
ensureWorkspaceStateFiles,
|
|
963
|
+
renderBusinessAgentAdapter,
|
|
964
|
+
ensureBusinessRootAgentAdapters,
|
|
865
965
|
};
|
package/lib/task-db.js
CHANGED
|
@@ -567,17 +567,38 @@ function reviewTask(db, { id, actor, reward, lesson, nextTask, proof, careerXpEl
|
|
|
567
567
|
const row = getTask(db, id);
|
|
568
568
|
if (!row) return { reviewed: false, reason: 'not_found' };
|
|
569
569
|
const numericReward = Number.isFinite(Number(reward)) ? Number(reward) : 0;
|
|
570
|
+
const now = Date.now();
|
|
571
|
+
const reviewer = actor || process.env.ATRIS_AGENT_ID || process.env.USER || null;
|
|
570
572
|
const metadata = row.metadata && typeof row.metadata === 'object' ? { ...row.metadata } : {};
|
|
573
|
+
const reviewingPendingProof = row.status === 'review'
|
|
574
|
+
&& metadata.approval_status === 'pending'
|
|
575
|
+
&& numericReward <= 0
|
|
576
|
+
&& metadata.agent_certified !== true;
|
|
577
|
+
let reviewPassCount = Number(metadata.agent_review_pass_count || 0);
|
|
578
|
+
if (reviewingPendingProof) {
|
|
579
|
+
reviewPassCount += 1;
|
|
580
|
+
metadata.agent_review_pass_count = reviewPassCount;
|
|
581
|
+
metadata.agent_reviewed_at = new Date(now).toISOString();
|
|
582
|
+
metadata.agent_reviewed_by = reviewer;
|
|
583
|
+
if (reviewPassCount >= AGENT_CERTIFICATION_REVIEW_PASSES) {
|
|
584
|
+
metadata.agent_certified = true;
|
|
585
|
+
metadata.agent_certified_at = new Date(now).toISOString();
|
|
586
|
+
metadata.agent_certified_by = reviewer;
|
|
587
|
+
metadata.agent_certification_policy = `${AGENT_CERTIFICATION_REVIEW_PASSES}_agent_review_passes`;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
571
590
|
if (numericReward > 0 && row.status === 'done') {
|
|
572
591
|
metadata.approval_status = 'accepted';
|
|
573
592
|
metadata.accepted_at = new Date().toISOString();
|
|
574
|
-
metadata.accepted_by =
|
|
593
|
+
metadata.accepted_by = reviewer;
|
|
594
|
+
}
|
|
595
|
+
if (reviewingPendingProof || (numericReward > 0 && row.status === 'done')) {
|
|
575
596
|
withBusyRetry(() => db.prepare(`
|
|
576
597
|
UPDATE tasks
|
|
577
598
|
SET metadata = ?,
|
|
578
599
|
updated_at = ?
|
|
579
600
|
WHERE id = ?
|
|
580
|
-
`).run(JSON.stringify(metadata),
|
|
601
|
+
`).run(JSON.stringify(metadata), now, id));
|
|
581
602
|
}
|
|
582
603
|
const payload = {
|
|
583
604
|
reward: numericReward,
|
|
@@ -586,6 +607,11 @@ function reviewTask(db, { id, actor, reward, lesson, nextTask, proof, careerXpEl
|
|
|
586
607
|
proof: String(proof || '').trim() || null,
|
|
587
608
|
career_xp_eligible: Boolean(careerXpEligible),
|
|
588
609
|
};
|
|
610
|
+
if (reviewingPendingProof) {
|
|
611
|
+
payload.review_pass_count = reviewPassCount;
|
|
612
|
+
payload.agent_certified = metadata.agent_certified === true;
|
|
613
|
+
payload.agent_certification_policy = metadata.agent_certification_policy || null;
|
|
614
|
+
}
|
|
589
615
|
const clearedReviewFields = Array.isArray(clearedFields)
|
|
590
616
|
? Array.from(new Set(clearedFields.filter(field => field === 'lesson' || field === 'next_task')))
|
|
591
617
|
: [];
|
|
@@ -593,7 +619,7 @@ function reviewTask(db, { id, actor, reward, lesson, nextTask, proof, careerXpEl
|
|
|
593
619
|
const event = appendTaskEvent(db, {
|
|
594
620
|
taskId: id,
|
|
595
621
|
workspaceRoot: row.workspace_root,
|
|
596
|
-
actor:
|
|
622
|
+
actor: reviewer,
|
|
597
623
|
eventType: 'reviewed',
|
|
598
624
|
payload,
|
|
599
625
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atris",
|
|
3
|
-
"version": "3.15.
|
|
3
|
+
"version": "3.15.48",
|
|
4
4
|
"main": "bin/atris.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"atris": "bin/atris.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"commands/",
|
|
14
14
|
"utils/",
|
|
15
15
|
"lib/",
|
|
16
|
+
"templates/",
|
|
16
17
|
"README.md",
|
|
17
18
|
"AGENTS.md",
|
|
18
19
|
"atris.md",
|
|
@@ -56,6 +56,7 @@ Keep owner metadata in `.atris/business.json`; keep computer memory, files, tool
|
|
|
56
56
|
| Path | What |
|
|
57
57
|
|------|------|
|
|
58
58
|
| `atris/team/` | Role lenses inside the shared business environment |
|
|
59
|
+
| `atris/team/START_HERE.md` | Collaborator guide for which member lane to wake first |
|
|
59
60
|
| `atris/team/_template/MEMBER.md` | Starter member template for real humans or new lanes |
|
|
60
61
|
| `atris/team/ops/MEMBER.md` | Default operating lane |
|
|
61
62
|
| `atris/team/operator/MEMBER.md` | Default owner for the business computer |
|
|
@@ -5,6 +5,9 @@ Anything durable and structured belongs under `atris/`.
|
|
|
5
5
|
|
|
6
6
|
## Role Lenses
|
|
7
7
|
|
|
8
|
+
Start with `atris/team/START_HERE.md`.
|
|
9
|
+
It explains which lane to wake first and when proof needs validator review.
|
|
10
|
+
|
|
8
11
|
Create lanes that match the real business workflow.
|
|
9
12
|
Examples: intake, scheduling, reactivation, revops, content, partnerships, support.
|
|
10
13
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Team Start Here — {{name}}
|
|
2
|
+
|
|
3
|
+
Use this when a collaborator opens the shared business workspace for the first time.
|
|
4
|
+
|
|
5
|
+
## Default Path
|
|
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.
|
|
15
|
+
|
|
16
|
+
## Mission Loop
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
atris mission status --status active --json
|
|
20
|
+
# If no active mission exists:
|
|
21
|
+
atris mission start "Run the first useful loop for this business" --owner operator --runner codex_goal --lane business --verify "atris business check" --stop "first proof recap recorded"
|
|
22
|
+
atris member goal-from-mission operator
|
|
23
|
+
atris do
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Lanes
|
|
27
|
+
|
|
28
|
+
| Lane | Use when |
|
|
29
|
+
|------|----------|
|
|
30
|
+
| `operator` | Someone needs to pick and drive the next concrete action |
|
|
31
|
+
| `validator` | A result needs proof, cost-safety, or external-readiness review |
|
|
32
|
+
| `ops` | The work is blocked on owner, date, status, or a crisp next step |
|
|
33
|
+
| `research` | The workspace lacks sourced facts for the next decision |
|
|
34
|
+
| `comms` | The next artifact is a message, update, reminder, or draft |
|
|
35
|
+
|
|
36
|
+
## Proof Rule
|
|
37
|
+
|
|
38
|
+
Record the first real run with:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
atris business record atris/reports/<recap>.md --outcome mixed --metric "operator speed"
|
|
42
|
+
atris business share --write
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
No XP or external action until a human approves the proof.
|