atris 3.57.3 → 3.58.5
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/README.md +12 -1
- package/atris/skills/clawhub/member-runtime/SKILL.md +9 -9
- package/atris/skills/create-member/SKILL.md +16 -13
- package/atris/skills/design/SKILL.md +27 -4
- package/atris/skills/engines/SKILL.md +57 -13
- package/atris/skills/x-search/SKILL.md +13 -5
- package/atris/skills/youtube/SKILL.md +39 -8
- package/atris/team/brainstormer/MEMBER.md +2 -2
- package/atris/team/executor/MEMBER.md +3 -3
- package/atris/team/launcher/MEMBER.md +4 -4
- package/atris/team/navigator/MEMBER.md +3 -3
- package/atris/team/researcher/MEMBER.md +2 -2
- package/atris/team/validator/MEMBER.md +1 -1
- package/atris.md +14 -0
- package/ax +157 -24
- package/bin/atris.js +79 -31
- package/commands/aeo.js +4 -4
- package/commands/agents.js +1 -1
- package/commands/align.js +12 -12
- package/commands/analytics.js +3 -3
- package/commands/app.js +5 -5
- package/commands/ask.js +175 -0
- package/commands/auth.js +7 -7
- package/commands/autoland.js +29 -5
- package/commands/autopilot-front.js +6 -6
- package/commands/autopilot.js +90 -90
- package/commands/avail.js +5 -5
- package/commands/bench.js +63 -1
- package/commands/browse.js +2 -2
- package/commands/business.js +12 -12
- package/commands/card.js +2 -2
- package/commands/clean.js +13 -13
- package/commands/close.js +297 -15
- package/commands/compile.js +13 -13
- package/commands/computer.js +94 -27
- package/commands/console.js +5 -5
- package/commands/decide.js +1 -1
- package/commands/deck.js +9 -9
- package/commands/drive.js +4 -4
- package/commands/engine.js +173 -19
- package/commands/errors.js +3 -3
- package/commands/experiments.js +18 -1
- package/commands/feed.js +2 -2
- package/commands/feedback.js +4 -4
- package/commands/fleet.js +12 -12
- package/commands/game.js +1 -1
- package/commands/guide.js +49 -0
- package/commands/improve.js +19 -17
- package/commands/init.js +67 -19
- package/commands/interview.js +7 -7
- package/commands/land.js +40 -15
- package/commands/learn.js +12 -12
- package/commands/lesson.js +2 -2
- package/commands/log.js +1 -1
- package/commands/loops.js +4 -4
- package/commands/member.js +75 -50
- package/commands/mission.js +97 -98
- package/commands/one-lap.js +1 -1
- package/commands/pack.js +74 -8
- package/commands/plugin.js +6 -6
- package/commands/probe.js +9 -9
- package/commands/pull.js +35 -35
- package/commands/pulse.js +1 -1
- package/commands/push.js +21 -21
- package/commands/rainmaker.js +1 -1
- package/commands/recap.js +7 -7
- package/commands/reel.js +2 -2
- package/commands/release.js +3 -3
- package/commands/report.js +1 -1
- package/commands/review.js +5 -5
- package/commands/revisions.js +1 -1
- package/commands/run.js +1 -1
- package/commands/scout.js +3 -3
- package/commands/security-review.js +7 -7
- package/commands/serve.js +9 -9
- package/commands/setup.js +1 -1
- package/commands/sign.js +4 -4
- package/commands/signup.js +4 -4
- package/commands/site.js +8 -3
- package/commands/skill.js +6 -6
- package/commands/slop.js +18 -18
- package/commands/social.js +3 -3
- package/commands/soul.js +14 -14
- package/commands/spaceship.js +1 -1
- package/commands/status.js +2 -2
- package/commands/strings.js +13 -13
- package/commands/study.js +4 -4
- package/commands/sync.js +8 -8
- package/commands/task.js +50 -25
- package/commands/teach.js +2 -2
- package/commands/team.js +1 -1
- package/commands/theme.js +2 -2
- package/commands/tree.js +34 -0
- package/commands/truth.js +7 -7
- package/commands/verify.js +12 -12
- package/commands/visualize.js +2 -2
- package/commands/workflow.js +97 -40
- package/commands/worktree.js +57 -1
- package/commands/write.js +9 -9
- package/commands/x-search.js +304 -15
- package/commands/xp.js +6 -3
- package/commands/youtube.js +916 -65
- package/lib/accept-verify-gate.js +3 -3
- package/lib/activity-stream.js +1 -1
- package/lib/apply-gate.js +13 -0
- package/lib/auto-accept-certified.js +28 -12
- package/lib/autoland.js +6 -6
- package/lib/bench/engines.js +59 -8
- package/lib/bench/report.js +1 -1
- package/lib/bench/runner.js +204 -5
- package/lib/bench/tree-render.js +76 -0
- package/lib/card.js +1 -1
- package/lib/chat-log-scan.js +1 -1
- package/lib/claude-boot-block.js +2 -0
- package/lib/deck-compose.js +1 -1
- package/lib/deck-history.js +2 -2
- package/lib/deck-layout.js +1 -1
- package/lib/deck-review.js +5 -5
- package/lib/deck-schema.js +1 -1
- package/lib/default-verifier.js +1 -1
- package/lib/developer-api.js +3 -0
- package/lib/engine-ask.js +66 -9
- package/lib/engine-registry.js +15 -2
- package/lib/file-ops.js +1 -1
- package/lib/fleet.js +71 -35
- package/lib/html-render.js +1 -1
- package/lib/intents.js +172 -0
- package/lib/journal.js +1 -1
- package/lib/known-commands.js +2 -2
- package/lib/land-green.js +364 -0
- package/lib/lesson-contradiction.js +2 -2
- package/lib/lesson-preflight.js +1 -1
- package/lib/manifest.js +5 -5
- package/lib/member-alive.js +9 -5
- package/lib/memory-view.js +3 -3
- package/lib/mission-protected-lane.js +1 -1
- package/lib/mission-root.js +2 -2
- package/lib/orb-context.js +10 -10
- package/lib/pack-capabilities.js +861 -3
- package/lib/permission-grants.js +2 -2
- package/lib/policy-lessons.js +6 -6
- package/lib/pulse.js +8 -8
- package/lib/receipt-evidence.js +1 -1
- package/lib/reel.js +1 -1
- package/lib/review-integrity.js +1 -1
- package/lib/runner-command.js +35 -5
- package/lib/scorecard.js +4 -4
- package/lib/security-scan.js +5 -5
- package/lib/self-drive.js +1 -1
- package/lib/site-publish.js +372 -0
- package/lib/site.js +1 -1
- package/lib/slides-deck.js +2 -2
- package/lib/state-detection.js +2 -2
- package/lib/sync-telemetry.js +2 -2
- package/lib/task-db.js +17 -10
- package/lib/task-explanation.js +1 -1
- package/lib/task-proof.js +2 -2
- package/lib/task-receipt.js +3 -3
- package/lib/theme.js +12 -12
- package/lib/todo-fallback.js +3 -3
- package/lib/todo-sections.js +1 -1
- package/lib/tree-hash.js +79 -0
- package/lib/usage.js +1 -1
- package/lib/wish-delegate.js +1 -1
- package/lib/workspace-safety.js +4 -4
- package/lib/workspace-scaffold.js +3 -3
- package/package.json +1 -1
- package/scripts/det/concierge-bakeoff.sh +26 -0
- package/scripts/det/ytquote-repair.js +0 -1
- package/scripts/det/ytrail-race.js +0 -5
- package/scripts/member-operate.mjs +52 -14
- package/scripts/outbound-artifact-gate.js +0 -3
- package/utils/auth.js +0 -3
- package/utils/config.js +0 -1
- package/scripts/det/checklist-score.js +0 -191
package/commands/task.js
CHANGED
|
@@ -1622,8 +1622,21 @@ function buildTaskStreams(tasks, goals) {
|
|
|
1622
1622
|
// from the existing review handoff, so this relabels what the certification
|
|
1623
1623
|
// rules already allow and can never widen it.
|
|
1624
1624
|
function taskApprovalFor(task, { reviewer = 'codex-review', hasExistingReviewFollowUp = null } = {}) {
|
|
1625
|
-
const current = taskPageCurrentStage(task);
|
|
1626
1625
|
const metadata = task && task.metadata || {};
|
|
1626
|
+
const approvalStatus = (task && task.review && task.review.approval_status) || metadata.approval_status || null;
|
|
1627
|
+
if (task && task.status === 'done' && approvalStatus === 'accepted') {
|
|
1628
|
+
return taskApprovalControls({
|
|
1629
|
+
question: 'Landed and accepted. Nothing to do.',
|
|
1630
|
+
approveLabel: 'Approve the completed work',
|
|
1631
|
+
acceptEnabled: false,
|
|
1632
|
+
acceptCommand: null,
|
|
1633
|
+
requestChangeEnabled: false,
|
|
1634
|
+
requestChangeCommand: null,
|
|
1635
|
+
blockedReason: null,
|
|
1636
|
+
waitingOn: null,
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
const current = taskPageCurrentStage(task);
|
|
1627
1640
|
const actions = taskPageActions(task, { reviewer, hasExistingReviewFollowUp });
|
|
1628
1641
|
const inReview = current === 'review';
|
|
1629
1642
|
const handoff = inReview
|
|
@@ -5333,7 +5346,7 @@ function evaluateReviewAutoAccept(task, root) {
|
|
|
5333
5346
|
if (!protectedGate.ok) return { eligible: false, ref, reason: protectedGate.reason };
|
|
5334
5347
|
const sizeGate = reviewAutoAcceptSizeGate(task, root);
|
|
5335
5348
|
if (!sizeGate.ok) return { eligible: false, ref, reason: sizeGate.reason, size: sizeGate.stats };
|
|
5336
|
-
// executeVerify: false
|
|
5349
|
+
// executeVerify: false, this is a READ path. The verdict comes from
|
|
5337
5350
|
// metadata.verify_cache, stamped by the two lanes allowed to spawn
|
|
5338
5351
|
// checks (certify-verified, autoland landing re-check). Spawning here is
|
|
5339
5352
|
// what turned `atris task reviews` into a fork-bomb multiplier.
|
|
@@ -5840,7 +5853,7 @@ function stampAcceptGroupMetadata(taskDb, db, taskId, { actor, group, verified,
|
|
|
5840
5853
|
}
|
|
5841
5854
|
|
|
5842
5855
|
// Accept a whole certified cluster honestly: the human spot-checks K rows (real career XP), the rest
|
|
5843
|
-
// are accepted-by-sampling (cleared from the backlog, provenance recorded, NO career XP
|
|
5856
|
+
// are accepted-by-sampling (cleared from the backlog, provenance recorded, NO career XP, never fake XP).
|
|
5844
5857
|
function cmdAcceptGroup(args) {
|
|
5845
5858
|
const pos = positional(args);
|
|
5846
5859
|
const spec = pos[0];
|
|
@@ -5891,7 +5904,7 @@ function cmdAcceptGroup(args) {
|
|
|
5891
5904
|
});
|
|
5892
5905
|
return;
|
|
5893
5906
|
}
|
|
5894
|
-
console.log(`accept-group DRY RUN
|
|
5907
|
+
console.log(`accept-group DRY RUN, ${key}=${value}: ${group.length} certified task(s)`);
|
|
5895
5908
|
console.log(`Spot-check these ${need} (weakest evidence first; open + verify), then accept the whole cluster:`);
|
|
5896
5909
|
sample.forEach((task) => {
|
|
5897
5910
|
console.log(` ${taskRef(task)} ${task.title}`);
|
|
@@ -5908,7 +5921,7 @@ function cmdAcceptGroup(args) {
|
|
|
5908
5921
|
}
|
|
5909
5922
|
});
|
|
5910
5923
|
console.log('');
|
|
5911
|
-
console.log(`If they hold up
|
|
5924
|
+
console.log(`If they hold up, accept all ${group.length} (career XP only on the ${need} you verified):`);
|
|
5912
5925
|
console.log(` atris task accept-group ${key}=${JSON.stringify(value)} --spot-check ${spotCheck} --confirm-human-accept --as <you> --verified ${sample.map(task => task.id).join(',')}`);
|
|
5913
5926
|
return;
|
|
5914
5927
|
}
|
|
@@ -6215,7 +6228,7 @@ function cmdAdd(args) {
|
|
|
6215
6228
|
const db = taskDb.open();
|
|
6216
6229
|
const ws = taskDb.workspaceRoot();
|
|
6217
6230
|
const operatorTitleWarning = warnIfTaskTitleNeedsOperatorWhy(title);
|
|
6218
|
-
// Generation throttle
|
|
6231
|
+
// Generation throttle, the named root cause is generation > human-review rate. An AGENT cannot keep
|
|
6219
6232
|
// minting tasks while a wall of certified-but-unaccepted work waits; that treadmill is what accept-group
|
|
6220
6233
|
// only drains. Humans and --force bypass. Closes the tap instead of just enlarging the bucket.
|
|
6221
6234
|
if (agentProofOnlyMode() && !hasFlag(args, '--force')) {
|
|
@@ -6387,7 +6400,7 @@ function taskDayTextGroups(groups, { full = false } = {}) {
|
|
|
6387
6400
|
}
|
|
6388
6401
|
|
|
6389
6402
|
function taskDayTitle(title, maxLength = 120) {
|
|
6390
|
-
const text = String(title || '').replace(/\s*[
|
|
6403
|
+
const text = String(title || '').replace(/\s*[\u2014\u2013]\s*/g, ' - ').replace(/\s+/g, ' ').trim();
|
|
6391
6404
|
if (text.length <= maxLength) return text;
|
|
6392
6405
|
const sentence = text.slice(0, maxLength + 1).match(/^(.{48,}?[.!?])(?:\s|$)/);
|
|
6393
6406
|
if (sentence) return sentence[1];
|
|
@@ -7468,6 +7481,7 @@ function cmdPlan(args) {
|
|
|
7468
7481
|
goal,
|
|
7469
7482
|
summary,
|
|
7470
7483
|
owner: automaticPlan.ownerForStage || owner,
|
|
7484
|
+
ownerExplicit: Boolean(owner),
|
|
7471
7485
|
exit,
|
|
7472
7486
|
proofNeeded,
|
|
7473
7487
|
firstMove,
|
|
@@ -8402,9 +8416,13 @@ function buildAutomaticPlanTrace(taskDb, task, { actor, actorExplicit = false, o
|
|
|
8402
8416
|
const metadata = task.metadata || {};
|
|
8403
8417
|
const purpose = cleanPublicText(goal, 240) || taskPurpose(task);
|
|
8404
8418
|
const claimedOwner = cleanPublicText(task.claimed_by, 80);
|
|
8419
|
+
// A delegated owner (metadata.assigned_to) is a functional decision already
|
|
8420
|
+
// recorded on the task. Only an explicit caller owner or an existing claim
|
|
8421
|
+
// outranks it; automatic team choice never does.
|
|
8422
|
+
const delegatedOwner = cleanPublicText(metadata.assigned_to, 80);
|
|
8405
8423
|
const actorNamed = taskTextMentionsActor(actor, `${purpose} ${task.title || ''} ${task.tag || ''}`);
|
|
8406
8424
|
const requestedActor = actorExplicit && (!isGenericPlanActor(actor) || actorNamed) ? actor : null;
|
|
8407
|
-
const requestedOwner = owner || claimedOwner || requestedActor || null;
|
|
8425
|
+
const requestedOwner = owner || claimedOwner || delegatedOwner || requestedActor || null;
|
|
8408
8426
|
const ownerChoice = chooseTaskOwner({
|
|
8409
8427
|
purpose,
|
|
8410
8428
|
tag: task.tag,
|
|
@@ -9778,7 +9796,7 @@ function cmdReapMissionBlockers(args) {
|
|
|
9778
9796
|
// 'failed' (no distinct archived status existed yet). This relabels exactly
|
|
9779
9797
|
// the rows that carry that reset's metadata marker, using the same
|
|
9780
9798
|
// UPDATE+appendTaskEvent write path as every other status transition in
|
|
9781
|
-
// lib/task-db.js
|
|
9799
|
+
// lib/task-db.js, never a raw projection-JSON edit.
|
|
9782
9800
|
function cmdRelabelArchived(args) {
|
|
9783
9801
|
const apply = hasFlag(args, '--apply');
|
|
9784
9802
|
const taskDb = getTaskDb();
|
|
@@ -9892,7 +9910,7 @@ function cmdReady(args) {
|
|
|
9892
9910
|
const { classifyVerifier } = require('../lib/verifier-quality');
|
|
9893
9911
|
const quality = classifyVerifier(verifyFlag);
|
|
9894
9912
|
if (!quality.ok) {
|
|
9895
|
-
console.error(`atris task ready: weak verifier
|
|
9913
|
+
console.error(`atris task ready: weak verifier, ${quality.reason}`);
|
|
9896
9914
|
console.error(` command: ${verifyFlag}`);
|
|
9897
9915
|
console.error(' allowlisted examples: node --test, npm test, git diff --check, node --check, rg <symbol>');
|
|
9898
9916
|
console.error(' or pass --no-falsify-check to accept anyway.');
|
|
@@ -9900,7 +9918,7 @@ function cmdReady(args) {
|
|
|
9900
9918
|
}
|
|
9901
9919
|
const probe = probeVerifierCanFail({ command: verifyFlag });
|
|
9902
9920
|
if (probe.probed && probe.canFail === false) {
|
|
9903
|
-
console.error(`atris task ready: this check cannot fail
|
|
9921
|
+
console.error(`atris task ready: this check cannot fail, ${probe.reason}`);
|
|
9904
9922
|
console.error(` command: ${verifyFlag}`);
|
|
9905
9923
|
console.error(' give a check that fails when the work is missing, or pass --no-falsify-check to accept anyway.');
|
|
9906
9924
|
process.exit(1);
|
|
@@ -9908,7 +9926,7 @@ function cmdReady(args) {
|
|
|
9908
9926
|
if (!probe.probed && !wantsJson(args)) console.log(` ${probe.reason}`);
|
|
9909
9927
|
}
|
|
9910
9928
|
const base = proof.trim();
|
|
9911
|
-
proof = `[verified] \`${verifyFlag}\` passed (exit 0)${base ?
|
|
9929
|
+
proof = `[verified] \`${verifyFlag}\` passed (exit 0)${base ? `, ${base}` : ''}${receipt.output ? `\n${receipt.output}` : ''}\nReceipt: ${receipt.receiptPath}`;
|
|
9912
9930
|
if (!wantsJson(args)) console.log(`✓ verified: \`${verifyFlag}\` exited 0 (receipt ${receipt.receiptPath})`);
|
|
9913
9931
|
}
|
|
9914
9932
|
if (!proof) {
|
|
@@ -10306,7 +10324,7 @@ function acceptReviewTask(taskDb, db, taskId, { actor, proof, reward, lesson = '
|
|
|
10306
10324
|
|
|
10307
10325
|
// Second-actor certification for proof-backed Review rows whose proof names a
|
|
10308
10326
|
// runnable, allowlisted check. Re-running that check as a distinct actor IS
|
|
10309
|
-
// the independent verification the certification gate asks for
|
|
10327
|
+
// the independent verification the certification gate asks for, the row
|
|
10310
10328
|
// becomes certified and autoland can land it on the same heartbeat. Rows in
|
|
10311
10329
|
// denied lanes, without a runnable check, or already certified keep their
|
|
10312
10330
|
// existing paths (review chats, human accept).
|
|
@@ -10355,8 +10373,8 @@ function currentHeadSha(workspaceRoot) {
|
|
|
10355
10373
|
|
|
10356
10374
|
// metadata.verify_cache is the read path's only verify verdict: `reviews`
|
|
10357
10375
|
// must never spawn a check (that read-side execution fork-bombed the fleet
|
|
10358
|
-
// on 2026-07-29), so the two lanes that legitimately execute verifies
|
|
10359
|
-
// certify-verified and the autoland landing re-check
|
|
10376
|
+
// on 2026-07-29), so the two lanes that legitimately execute verifies,
|
|
10377
|
+
// certify-verified and the autoland landing re-check, persist the outcome
|
|
10360
10378
|
// here for the read path to consult.
|
|
10361
10379
|
function stampVerifyCacheMetadata(taskDb, db, taskId, { verify, result, actor, workspaceRoot }) {
|
|
10362
10380
|
const row = taskDb.getTask(db, taskId);
|
|
@@ -10414,8 +10432,8 @@ function reverifyBeforeLanding(taskDb, db, task, { actor = 'autoland-verifier',
|
|
|
10414
10432
|
const verify = certifyVerifyCandidate(task);
|
|
10415
10433
|
if (!verify) {
|
|
10416
10434
|
// No runnable check on record. Landing anyway converts "never verified"
|
|
10417
|
-
// into "accepted with XP"
|
|
10418
|
-
// to prevent
|
|
10435
|
+
// into "accepted with XP", the exact signal poisoning this gate exists
|
|
10436
|
+
// to prevent, so bounce the task back for a recorded verify instead.
|
|
10419
10437
|
const note = 'Autoland refused to land without a runnable verify command: record one with `atris task ready --verify "<cmd>" --result "<sentence>"`.';
|
|
10420
10438
|
const revised = taskDb.reviseTask(db, { id: task.id, actor, note });
|
|
10421
10439
|
return {
|
|
@@ -10494,11 +10512,11 @@ function cmdCertifyVerified(args, options = {}) {
|
|
|
10494
10512
|
}
|
|
10495
10513
|
// Skip only rows the accept lane can already land, or rows blocked by
|
|
10496
10514
|
// something an executed second-actor check cannot cure. A row with two
|
|
10497
|
-
// passes from ONE actor is exactly what this command exists to cure
|
|
10515
|
+
// passes from ONE actor is exactly what this command exists to cure,
|
|
10498
10516
|
// "certified" alone is not landable.
|
|
10499
10517
|
// strictVerify stays off in this eligibility probe: certify-verified runs
|
|
10500
10518
|
// the check itself right below, and strict mode here would execute it a
|
|
10501
|
-
// second time per row before the real run. executeVerify: false as well
|
|
10519
|
+
// second time per row before the real run. executeVerify: false as well,
|
|
10502
10520
|
// an untrusted trust tier re-enables the strict block internally even
|
|
10503
10521
|
// with strictVerify off, which is how this probe spawned a verify per row.
|
|
10504
10522
|
const evaluation = evaluateAutoAccept(task, { strictVerify: false, executeVerify: false });
|
|
@@ -10626,7 +10644,7 @@ function cmdAutoAcceptCertified(args) {
|
|
|
10626
10644
|
const hasExplicitLimit = Boolean(limitRaw) && limitRaw !== true;
|
|
10627
10645
|
// --all means sweep the full certified backlog, not just the first page of
|
|
10628
10646
|
// it. Before this fix `max` was hard-capped at 12 even under --all, so a
|
|
10629
|
-
// real backlog (78 certified rows observed live) only ever drained 12/run
|
|
10647
|
+
// real backlog (78 certified rows observed live) only ever drained 12/run,
|
|
10630
10648
|
// an invisible undercount the autoland heartbeat repeated every hour.
|
|
10631
10649
|
// AUTO_ACCEPT_ALL_SWEEP_CAP is a safety ceiling, not a target: a well-formed
|
|
10632
10650
|
// --all run should always scan fewer rows than this.
|
|
@@ -10659,7 +10677,7 @@ function cmdAutoAcceptCertified(args) {
|
|
|
10659
10677
|
// anyway. Without this exception `atris autoland tick` was blind whenever
|
|
10660
10678
|
// invoked from an agent session (CLAUDECODE etc. in env): the spawned
|
|
10661
10679
|
// sweep failTask'd with no summary and the tick receipt showed nulls.
|
|
10662
|
-
// A per-run --confirm-human-accept claim from an agent is still refused
|
|
10680
|
+
// A per-run --confirm-human-accept claim from an agent is still refused,
|
|
10663
10681
|
// policyAuth is only consulted when no per-run confirmation is passed.
|
|
10664
10682
|
if (agentProofOnlyMode() && !dryRun && !policyAuth.ok) {
|
|
10665
10683
|
failAgentProofOnly(
|
|
@@ -10792,7 +10810,7 @@ function cmdAutoAcceptCertified(args) {
|
|
|
10792
10810
|
return { ...summary, results, certification, projection_path: finalPath, queue };
|
|
10793
10811
|
}
|
|
10794
10812
|
console.log(`AUTO-ACCEPT CERTIFIED (${dryRun ? 'dry-run' : 'execute'})`);
|
|
10795
|
-
console.log(`${summary.certified} certified, ${summary.scanned} scanned, ${summary.accepted || summary.would_accept} accepted, ${summary.skipped} skipped${summary.revised ? `, ${summary.revised} revised` : ''}${summary.failed ? `, ${summary.failed} failed` : ''}${summary.undercounted ? ' (UNDERCOUNTED
|
|
10813
|
+
console.log(`${summary.certified} certified, ${summary.scanned} scanned, ${summary.accepted || summary.would_accept} accepted, ${summary.skipped} skipped${summary.revised ? `, ${summary.revised} revised` : ''}${summary.failed ? `, ${summary.failed} failed` : ''}${summary.undercounted ? ' (UNDERCOUNTED, raise --limit or the sweep cap)' : ''}`);
|
|
10796
10814
|
for (const row of results) {
|
|
10797
10815
|
const nextAction = row.next_action ? ` next_action=${row.next_action}` : '';
|
|
10798
10816
|
const reviewChat = row.review_chat_command ? ` review_chat=${row.review_chat_command}` : '';
|
|
@@ -11104,10 +11122,16 @@ function taskAuditReceiptPath(at) {
|
|
|
11104
11122
|
|
|
11105
11123
|
function runTaskAuditVerify(task, verify) {
|
|
11106
11124
|
const { spawnSync } = require('child_process');
|
|
11125
|
+
// Same measured ceiling as the landing gate: honest suites need minutes,
|
|
11126
|
+
// not seconds. See lib/auto-accept-certified.js verifyTimeoutMs().
|
|
11127
|
+
const rawTimeout = Number(process.env.ATRIS_VERIFY_TIMEOUT_MS);
|
|
11128
|
+
const timeout = Number.isFinite(rawTimeout) && rawTimeout > 0
|
|
11129
|
+
? Math.min(rawTimeout, 60 * 60 * 1000)
|
|
11130
|
+
: 10 * 60 * 1000;
|
|
11107
11131
|
const result = spawnSync('bash', ['-c', verify], {
|
|
11108
11132
|
cwd: task.workspace_root,
|
|
11109
11133
|
encoding: 'utf8',
|
|
11110
|
-
timeout
|
|
11134
|
+
timeout,
|
|
11111
11135
|
});
|
|
11112
11136
|
const passed = !result.error && result.status === 0;
|
|
11113
11137
|
return {
|
|
@@ -11997,7 +12021,7 @@ function taskBoardTemplate(model) {
|
|
|
11997
12021
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11998
12022
|
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
11999
12023
|
<style>
|
|
12000
|
-
/* aesthetic: machine-room telemetry
|
|
12024
|
+
/* aesthetic: machine-room telemetry, warm-tinted dark, mono data, calm signals (no neon) */
|
|
12001
12025
|
:root {
|
|
12002
12026
|
color-scheme: dark;
|
|
12003
12027
|
--bg: oklch(18% 0.012 160);
|
|
@@ -12208,7 +12232,7 @@ function taskBoardTemplate(model) {
|
|
|
12208
12232
|
|
|
12209
12233
|
function renderActivity(events) {
|
|
12210
12234
|
const el = $('activity');
|
|
12211
|
-
if (!events.length) { el.innerHTML = '<h2>Live Stream</h2><div class="empty">no activity yet
|
|
12235
|
+
if (!events.length) { el.innerHTML = '<h2>Live Stream</h2><div class="empty">no activity yet, fire a tick: atris pulse tick</div>'; return; }
|
|
12212
12236
|
let html = '<h2>Live Stream · ' + events.length + ' events</h2>';
|
|
12213
12237
|
for (const e of events) {
|
|
12214
12238
|
const rwCls = e.reward == null ? '' : (e.reward > 0 ? 'pos' : (e.reward < 0 ? 'neg' : ''));
|
|
@@ -12819,6 +12843,7 @@ function postTaskApiPlan({ res, taskDb, db, taskId, body }) {
|
|
|
12819
12843
|
goal,
|
|
12820
12844
|
summary,
|
|
12821
12845
|
owner: automaticPlan.ownerForStage || owner,
|
|
12846
|
+
ownerExplicit: Boolean(owner),
|
|
12822
12847
|
exit,
|
|
12823
12848
|
proofNeeded: String(body.proof_needed || body.proofNeeded || body.proof || body.verify || ''),
|
|
12824
12849
|
firstMove,
|
package/commands/teach.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* atris teach
|
|
4
|
+
* atris teach: local cases under ./atris/teach only.
|
|
5
5
|
*
|
|
6
6
|
* atris teach list cases in atris/teach
|
|
7
7
|
* atris teach <id> show one case file
|
|
@@ -16,7 +16,7 @@ const path = require('path');
|
|
|
16
16
|
const TEACH_DIR = path.join('atris', 'teach');
|
|
17
17
|
|
|
18
18
|
function usage() {
|
|
19
|
-
console.log('atris teach
|
|
19
|
+
console.log('atris teach: local cases under ./atris/teach');
|
|
20
20
|
console.log('');
|
|
21
21
|
console.log(' atris teach list case files in atris/teach');
|
|
22
22
|
console.log(' atris teach <id> show atris/teach/<id>.md (or .json)');
|
package/commands/team.js
CHANGED
|
@@ -145,7 +145,7 @@ function memberFocus(rawNow, { awake, alwaysOn }) {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
function memberIsActive({ frontmatterEngine, awake }) {
|
|
148
|
-
// A stale focus line in now.md does not make a member active
|
|
148
|
+
// A stale focus line in now.md does not make a member active, only an
|
|
149
149
|
// assigned engine or live presence does.
|
|
150
150
|
return Boolean(frontmatterEngine) || awake;
|
|
151
151
|
}
|
package/commands/theme.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// atris theme
|
|
1
|
+
// atris theme, brand themes for the whole design system. Define your colors and
|
|
2
2
|
// fonts once in .atris/theme.json; every deck, HTML page, and site uses them.
|
|
3
3
|
//
|
|
4
4
|
// atris theme create guided interview -> your own theme (alias: new)
|
|
@@ -79,7 +79,7 @@ async function interview(defaults = {}) {
|
|
|
79
79
|
ans.mode = mp.startsWith('l') ? 'light' : mp.startsWith('d') ? 'dark' : dmode;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
console.log('\n 4/5 your accent
|
|
82
|
+
console.log('\n 4/5 your accent, the one color that is unmistakably yours:');
|
|
83
83
|
mood.swatches.forEach((s, i) => console.log(` ${i + 1}. ${sw(s)} ${s}`));
|
|
84
84
|
const dac = normHex(defaults.accent) || mood.swatches[0];
|
|
85
85
|
const ap = (await ask(` pick 1-${mood.swatches.length}, or paste a hex [${dac}]: `)).trim();
|
package/commands/tree.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { computeTreeHash } = require('../lib/tree-hash');
|
|
4
|
+
|
|
5
|
+
function showTreeHelp() {
|
|
6
|
+
console.log('usage: atris tree hash [--json]');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function treeCommand(subcommand, ...args) {
|
|
10
|
+
if (['help', '--help', '-h'].includes(subcommand)) {
|
|
11
|
+
showTreeHelp();
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
if (subcommand !== 'hash') {
|
|
15
|
+
console.error(`unknown tree command: ${subcommand || ''}`.trim());
|
|
16
|
+
showTreeHelp();
|
|
17
|
+
return 2;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let result;
|
|
21
|
+
try {
|
|
22
|
+
result = computeTreeHash(process.cwd());
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(`tree hash failed: ${error.message || error}`);
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
if (args.includes('--json')) console.log(JSON.stringify(result, null, 2));
|
|
28
|
+
else console.log(`${result.short} ${result.files} files`);
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
treeCommand,
|
|
34
|
+
};
|
package/commands/truth.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// atris truth
|
|
1
|
+
// atris truth: one table of what is actually proven, blocked, or stale.
|
|
2
2
|
// Rolls up sources that already exist; writes nothing. SQL/state is truth, this is the render.
|
|
3
|
-
// 1. .atris/state/missions.jsonl
|
|
4
|
-
// 2. ~/.atris/tasks.db
|
|
5
|
-
// 3. atris/features/*/
|
|
6
|
-
// 4. atris/loops/*.md
|
|
3
|
+
// 1. .atris/state/missions.jsonl : mission states (dedupe by id, latest wins)
|
|
4
|
+
// 2. ~/.atris/tasks.db : task counts by status, scoped to this workspace unless --all is passed
|
|
5
|
+
// 3. atris/features/*/ : validate.md frontmatter + newest proof/ receipt age
|
|
6
|
+
// 4. atris/loops/*.md : workspace loops by default; pass --global for ~/.atris/heartbeat
|
|
7
7
|
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
@@ -116,7 +116,7 @@ const PARKED_DAYS = 30;
|
|
|
116
116
|
|
|
117
117
|
// One git call: every feature dir touched in the last PARKED_DAYS.
|
|
118
118
|
// An unproven feature nobody has edited in a month is a parked idea
|
|
119
|
-
// packet, not work-in-progress
|
|
119
|
+
// packet, not work-in-progress. Counting it as "unproven" buries the
|
|
120
120
|
// handful of live lanes that actually need a proof receipt.
|
|
121
121
|
function recentlyTouchedFeatureDirs(cwd) {
|
|
122
122
|
try {
|
|
@@ -275,7 +275,7 @@ function truthCommand(args = []) {
|
|
|
275
275
|
return 0;
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
-
line('ATRIS TRUTH
|
|
278
|
+
line('ATRIS TRUTH: live state, not belief\n');
|
|
279
279
|
line(`Scope: ${taskScopeLine(scope)}`);
|
|
280
280
|
|
|
281
281
|
line(`Missions active: ${missions.length}`);
|
package/commands/verify.js
CHANGED
|
@@ -76,12 +76,12 @@ function verifyWorkspace(cwd, atrisDir) {
|
|
|
76
76
|
|
|
77
77
|
// MAP status
|
|
78
78
|
if (results.mapValid) {
|
|
79
|
-
console.log('✓ MAP.md
|
|
79
|
+
console.log('✓ MAP.md: Valid');
|
|
80
80
|
if (mapResult.stats) {
|
|
81
81
|
console.log(` ${mapResult.stats.fileRefs} file refs, ${mapResult.stats.lineRefs} line refs`);
|
|
82
82
|
}
|
|
83
83
|
} else {
|
|
84
|
-
console.log('✗ MAP.md
|
|
84
|
+
console.log('✗ MAP.md: Issues found');
|
|
85
85
|
mapResult.issues.forEach(issue => console.log(` • ${issue}`));
|
|
86
86
|
}
|
|
87
87
|
(mapResult.notes || []).forEach(note => console.log(` ○ ${note}`));
|
|
@@ -90,20 +90,20 @@ function verifyWorkspace(cwd, atrisDir) {
|
|
|
90
90
|
// Test status
|
|
91
91
|
if (testResult.run) {
|
|
92
92
|
if (results.testsPass) {
|
|
93
|
-
console.log(`✓ Tests
|
|
93
|
+
console.log(`✓ Tests: Pass (${testResult.summary})`);
|
|
94
94
|
} else {
|
|
95
|
-
console.log(`✗ Tests
|
|
95
|
+
console.log(`✗ Tests: Fail (${testResult.summary})`);
|
|
96
96
|
}
|
|
97
97
|
} else {
|
|
98
|
-
console.log('○ Tests
|
|
98
|
+
console.log('○ Tests: Not configured');
|
|
99
99
|
}
|
|
100
100
|
console.log('');
|
|
101
101
|
|
|
102
102
|
// Docs vs changes
|
|
103
103
|
if (results.docsUpToDate) {
|
|
104
|
-
console.log('✓ Docs
|
|
104
|
+
console.log('✓ Docs: Up to date with recent changes');
|
|
105
105
|
} else {
|
|
106
|
-
console.log('⚠ Docs
|
|
106
|
+
console.log('⚠ Docs: May need updating');
|
|
107
107
|
docResult.issues.forEach(issue => console.log(` • ${issue}`));
|
|
108
108
|
}
|
|
109
109
|
console.log('');
|
|
@@ -227,7 +227,7 @@ function verifyMap(cwd, atrisDir) {
|
|
|
227
227
|
const content = fs.readFileSync(mapFile, 'utf8');
|
|
228
228
|
|
|
229
229
|
// Check for placeholder content. Match the specific phrases written by
|
|
230
|
-
// commands/init.js:357
|
|
230
|
+
// commands/init.js:357, where a substring search for "placeholder" is too broad
|
|
231
231
|
// and false-flags any MAP.md that mentions the word in prose.
|
|
232
232
|
const lower = content.toLowerCase();
|
|
233
233
|
const isPlaceholder = lower.includes('generated by your ai agent')
|
|
@@ -239,13 +239,13 @@ function verifyMap(cwd, atrisDir) {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
// Let the repo's own map validator have the final say, when it ships one.
|
|
242
|
-
// A missing python3 is a skip, not a failure
|
|
242
|
+
// A missing python3 is a skip, not a failure. The CLI has no python dependency.
|
|
243
243
|
const validator = path.join(cwd, 'scripts', 'validate_map.py');
|
|
244
244
|
if (fs.existsSync(validator)) {
|
|
245
245
|
const proc = spawnSync('python3', [validator], { cwd, encoding: 'utf8', env: process.env });
|
|
246
246
|
if (proc.error) {
|
|
247
247
|
const reason = proc.error.code === 'ENOENT' ? 'python3 not available' : proc.error.message;
|
|
248
|
-
result.notes.push(`Skipped scripts/validate_map.py
|
|
248
|
+
result.notes.push(`Skipped scripts/validate_map.py: ${reason}`);
|
|
249
249
|
} else if ((proc.status ?? 0) !== 0) {
|
|
250
250
|
const detail = firstOutputLine(proc.stderr) || firstOutputLine(proc.stdout) || `exit ${proc.status}`;
|
|
251
251
|
result.issues.push(`scripts/validate_map.py failed: ${detail}`);
|
|
@@ -539,7 +539,7 @@ function verifyChange(cwd, change) {
|
|
|
539
539
|
};
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
-
// No specific check possible
|
|
542
|
+
// No specific check possible, refuse to auto-pass
|
|
543
543
|
return {
|
|
544
544
|
pass: false,
|
|
545
545
|
description: change.description,
|
|
@@ -583,7 +583,7 @@ function checkMapForFiles(atrisDir, changes) {
|
|
|
583
583
|
*
|
|
584
584
|
* Contract (per atris.md): the rubric must be read-only, deterministic, and
|
|
585
585
|
* reference only the working tree. The command fails loudly when the rubric
|
|
586
|
-
|
|
586
|
+
* or section is missing. That prevents silent "trivial Verify" regressions.
|
|
587
587
|
*/
|
|
588
588
|
function verifyRubric(slug, section, opts = {}) {
|
|
589
589
|
const cwd = opts.cwd || process.cwd();
|
package/commands/visualize.js
CHANGED
|
@@ -41,7 +41,7 @@ function legacyVisualizeInbox() {
|
|
|
41
41
|
|
|
42
42
|
console.log('');
|
|
43
43
|
console.log('┌─────────────────────────────────────────────────────────────┐');
|
|
44
|
-
console.log('│ Atris Visualize
|
|
44
|
+
console.log('│ Atris Visualize: Break Down & Approval Gate │');
|
|
45
45
|
console.log('└─────────────────────────────────────────────────────────────┘');
|
|
46
46
|
console.log('');
|
|
47
47
|
|
|
@@ -368,7 +368,7 @@ async function generateVisual(prompt, options = {}) {
|
|
|
368
368
|
}
|
|
369
369
|
|
|
370
370
|
async function visualizeAtris(args = process.argv.slice(3)) {
|
|
371
|
-
// Bare-word `help` should not be treated as a prompt
|
|
371
|
+
// Bare-word `help` should not be treated as a prompt, it would trigger a
|
|
372
372
|
// paid image-generation call ("draw me a picture of help"). Promote it to
|
|
373
373
|
// the help intent.
|
|
374
374
|
if (args[0] === 'help') {
|