atris 3.37.1 → 3.40.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.
- package/AGENTS.md +25 -6
- package/README.md +2 -0
- package/atris/PERSONA.md +11 -11
- package/atris.md +17 -2
- package/ax +160 -34
- package/bin/atris.js +78 -6
- package/commands/activate.js +16 -3
- package/commands/agent-spawn.js +13 -18
- package/commands/autoland.js +76 -47
- package/commands/autopilot-front.js +0 -4
- package/commands/autopilot.js +0 -12
- package/commands/bench.js +10 -12
- package/commands/brain.js +0 -7
- package/commands/brief.js +0 -2
- package/commands/business-sync.js +0 -1
- package/commands/business.js +452 -12
- package/commands/chat-scan.js +5 -7
- package/commands/clean.js +31 -2
- package/commands/close.js +46 -11
- package/commands/cloud.js +0 -1
- package/commands/codex-goal.js +8 -12
- package/commands/computer.js +6 -5
- package/commands/console.js +64 -11
- package/commands/decide.js +166 -0
- package/commands/deck.js +30 -12
- package/commands/dream.js +0 -7
- package/commands/drill.js +14 -25
- package/commands/engine.js +206 -26
- package/commands/experiments.js +0 -4
- package/commands/fleet-report.js +12 -4
- package/commands/game.js +261 -0
- package/commands/gm.js +17 -7
- package/commands/goal.js +0 -6
- package/commands/harvest.js +1 -5
- package/commands/improve.js +29 -8
- package/commands/init.js +41 -37
- package/commands/integrations.js +0 -7
- package/commands/land.js +77 -20
- package/commands/launchpad.js +1 -16
- package/commands/lesson.js +17 -7
- package/commands/lifecycle.js +5 -5
- package/commands/log.js +55 -5
- package/commands/loop-front.js +0 -2
- package/commands/loops.js +6 -5
- package/commands/meet.js +0 -2
- package/commands/member.js +622 -573
- package/commands/mission.js +790 -314
- package/commands/next.js +0 -1
- package/commands/now.js +0 -12
- package/commands/one-lap.js +8 -8
- package/commands/orb.js +0 -4
- package/commands/pack-craft.js +0 -1
- package/commands/pack.js +3599 -424
- package/commands/play.js +6 -6
- package/commands/probe.js +12 -6
- package/commands/pulse.js +88 -64
- package/commands/push.js +0 -4
- package/commands/radar.js +14 -11
- package/commands/recover.js +340 -0
- package/commands/release.js +10 -9
- package/commands/report.js +0 -1
- package/commands/router.js +320 -0
- package/commands/run-front.js +0 -2
- package/commands/search.js +0 -3
- package/commands/site-deploy.js +870 -0
- package/commands/site.js +11 -2
- package/commands/skill.js +7 -2
- package/commands/slop.js +237 -7
- package/commands/status.js +6 -0
- package/commands/stream.js +4 -20
- package/commands/study.js +0 -3
- package/commands/sync-checkout.js +51 -0
- package/commands/sync.js +11 -40
- package/commands/task.js +999 -595
- package/commands/taste.js +101 -0
- package/commands/teach.js +86 -0
- package/commands/team.js +83 -3
- package/commands/unknowns.js +0 -10
- package/commands/update.js +0 -1
- package/commands/vercel.js +4 -2
- package/commands/visualize.js +0 -5
- package/commands/voice.js +195 -0
- package/commands/watch.js +1 -28
- package/commands/wiki.js +42 -15
- package/commands/wish.js +0 -1
- package/commands/workflow.js +2 -2
- package/commands/worktree.js +88 -28
- package/commands/xp.js +28 -30
- package/commands/youtube.js +0 -2
- package/lib/accept-verify-gate.js +126 -0
- package/lib/activity-stream.js +0 -2
- package/lib/arg-parser.js +41 -0
- package/lib/auto-accept-certified.js +261 -3
- package/lib/autoland.js +66 -3
- package/lib/ax-auto-lane.js +68 -7
- package/lib/bench/context.js +0 -2
- package/lib/bench/report.js +0 -1
- package/lib/bench/runner.js +18 -11
- package/lib/brief-ledger.js +0 -6
- package/lib/business-simulate.js +382 -0
- package/lib/chat-log-scan.js +0 -5
- package/lib/checkout-sync.js +52 -0
- package/lib/claude-boot-block.js +48 -0
- package/lib/cloud-mission.js +0 -6
- package/lib/codex-flight.js +0 -1
- package/lib/conductor-artifacts.js +25 -0
- package/lib/context-gatherer.js +7 -2
- package/lib/deck-compose.js +0 -1
- package/lib/deck-history.js +0 -1
- package/lib/deck-layout.js +0 -5
- package/lib/deck-review.js +0 -7
- package/lib/deck-schema.js +0 -1
- package/lib/default-verifier.js +0 -2
- package/lib/engine-registry.js +157 -28
- package/lib/experiments/daily.js +0 -6
- package/lib/falsifier-probe.js +84 -0
- package/lib/fleet.js +275 -42
- package/lib/functional-owner.js +0 -3
- package/lib/git-spawn.js +15 -0
- package/lib/inspect-fields.js +0 -1
- package/lib/json-file.js +37 -0
- package/lib/known-commands.js +2 -2
- package/lib/learnings.js +0 -2
- package/lib/lesson-preflight.js +146 -0
- package/lib/loop-doctor.js +11 -19
- package/lib/manifest.js +0 -2
- package/lib/member-alive.js +0 -1
- package/lib/member-switches.js +0 -5
- package/lib/mission-artifact.js +0 -1
- package/lib/mission-human-asks.js +28 -0
- package/lib/mission-protected-lane.js +296 -0
- package/lib/mission-room.js +0 -2
- package/lib/mission-runtime-loop.js +0 -1
- package/lib/next-moves.js +0 -18
- package/lib/official-cli-integration.js +47 -6
- package/lib/orb-context.js +14 -4
- package/lib/orb-scorecard.js +0 -1
- package/lib/outbound-send-gate.js +0 -6
- package/lib/pack-capabilities.js +685 -0
- package/lib/permission-grants.js +0 -6
- package/lib/policy-lessons.js +0 -2
- package/lib/pulse.js +68 -15
- package/lib/review-integrity.js +0 -2
- package/lib/router-brain.js +51 -3
- package/lib/runner-command.js +0 -10
- package/lib/runtime-bootstrap.js +0 -1
- package/lib/scorecard.js +0 -1
- package/lib/self-drive.js +45 -14
- package/lib/state-detection.js +0 -6
- package/lib/task-db.js +137 -7
- package/lib/task-decision.js +50 -0
- package/lib/taste-lessons.js +153 -0
- package/lib/team-presence.js +0 -1
- package/lib/tool-result-encode.js +17 -1
- package/lib/voice-gate.js +129 -2
- package/lib/wiki.js +152 -9
- package/lib/wish-audit.js +21 -7
- package/lib/wish-delegate.js +27 -21
- package/lib/wish-stats.js +0 -5
- package/lib/wish-store.js +0 -1
- package/lib/workspace-safety.js +0 -2
- package/lib/zip.js +95 -8
- package/package.json +2 -1
- package/templates/business-starter/persona.md +9 -0
package/bin/atris.js
CHANGED
|
@@ -504,7 +504,7 @@ function showHelp() {
|
|
|
504
504
|
console.log(' activate - Load Atris context');
|
|
505
505
|
console.log(' radar - Show live agents joined with tasks, missions, and worktrees');
|
|
506
506
|
console.log(' stream - Watch the whole team work live in one terminal');
|
|
507
|
-
console.log(' team -
|
|
507
|
+
console.log(' team - One team view: members, roles, engine assignments (presence for live)');
|
|
508
508
|
console.log(' watch - Turn one sentence into an always-on background watcher');
|
|
509
509
|
console.log(' ctop - Show a process-first live agent CPU/memory view');
|
|
510
510
|
console.log(' launchpad - Show the next action from local brain, task, mission, and proof state');
|
|
@@ -519,14 +519,18 @@ function showHelp() {
|
|
|
519
519
|
console.log(' close - track open loops with deadlines and daily escalation');
|
|
520
520
|
console.log(' harvest - Find bugs and next actions from receipts, run logs, and thinking');
|
|
521
521
|
console.log(' verify - Validate work is done (tests, MAP.md, changes)');
|
|
522
|
+
console.log(' slop - Deterministic slop detector: frontend/prose tells, dead code (slop dead --exports)');
|
|
523
|
+
console.log(' voice - Scan binary voice tells or judge reply shape and plainness');
|
|
524
|
+
console.log(' recover - Explain stopped missions; --apply performs safe recovery only');
|
|
522
525
|
console.log(' task - Local agent task plane (atomic claims, TODO import)');
|
|
523
|
-
console.log(' golden path (
|
|
526
|
+
console.log(' golden path (one tick, by cron or by hand):');
|
|
524
527
|
console.log(' atris task delegate "fix the login bug" --to <member>');
|
|
525
528
|
console.log(' atris task claim <id> --as <member>');
|
|
526
529
|
console.log(' ... build ...');
|
|
527
530
|
console.log(' atris task ready <id> --verify');
|
|
528
531
|
console.log(' atris autoland tick # second check runs, task lands');
|
|
529
532
|
console.log(' mission - Goal + loop + member owner + verifier + receipt; --budget quick|long|deep sets bounded tiers');
|
|
533
|
+
console.log(' decide - Answer open mission asks and send the decision to the next tick');
|
|
530
534
|
console.log(' release - Tag release, bump version, create GitHub release, draft /launch');
|
|
531
535
|
console.log(' learn - Project learnings (patterns, pitfalls, preferences)');
|
|
532
536
|
console.log(' study - On-demand learning feed: ingest topic, start server, open browser');
|
|
@@ -535,10 +539,12 @@ function showHelp() {
|
|
|
535
539
|
console.log(' avail - Booking availability (/book/{username} weekly windows)');
|
|
536
540
|
console.log(' brain - Compile MAP/TODO/wiki/state into a loadable agent brain');
|
|
537
541
|
console.log(' lesson - Append a one-line lesson to atris/lessons.md (mine: distill receipts/episodes/scorecards into policy lessons)');
|
|
542
|
+
console.log(' taste - Record the operator\'s keep, kill, and more creative verdicts');
|
|
543
|
+
console.log(' teach - Turn a bad turn into a failing benchmark, then a permanent guard (red gate: no promotion without a proven failure)');
|
|
538
544
|
console.log(' ingest - Local-first wiki ingest into atris/wiki/');
|
|
539
545
|
console.log(' query - Local-first wiki query against atris/wiki/');
|
|
540
546
|
console.log(' lint - Local-first wiki lint for atris/wiki/');
|
|
541
|
-
console.log(' loop -
|
|
547
|
+
console.log(' loop - Recurring loops front door (wiki upkeep lives under: loop wiki)');
|
|
542
548
|
console.log(' write - Guided writing sessions: you write every word, atris structures + reviews');
|
|
543
549
|
console.log('');
|
|
544
550
|
console.log('Optional helpers:');
|
|
@@ -548,8 +554,9 @@ function showHelp() {
|
|
|
548
554
|
console.log(' worktree - Isolated Git worktrees plus guarded ship/merge for parallel agents');
|
|
549
555
|
console.log(' land - The landing: what is actually done vs still in the air; --reap backs up + clears overdue');
|
|
550
556
|
console.log(' drive - One self-driving tick: mission doctor -> auto-fix -> count disengagements');
|
|
551
|
-
console.log(
|
|
557
|
+
console.log(` autoland - Approve the policy once; ${require('../lib/autoland').certifiedWorkLandsPhrase(process.cwd())}, you keep irreversible calls`);
|
|
552
558
|
console.log(' engine - Engine registry: list/resolve roles, health flips, default engine, `engine test`, and dispatch flights');
|
|
559
|
+
console.log(' router - inspect ax lane outcomes and promote gated reflex overrides');
|
|
553
560
|
console.log(' sign - Co-author trailer on every commit in an atris workspace (on/off/status)');
|
|
554
561
|
console.log(' visualize - Generate a Slack/deck-ready visual from a prompt');
|
|
555
562
|
console.log(' youtube - Process YouTube videos with timestamped transcript-first analysis');
|
|
@@ -575,6 +582,7 @@ function showHelp() {
|
|
|
575
582
|
console.log('Sync:');
|
|
576
583
|
console.log(' pull - Pull journals + member data from cloud');
|
|
577
584
|
console.log(' push - Push workspace files to cloud');
|
|
585
|
+
console.log(' sync-checkout - fetch and fast-forward a clean current branch');
|
|
578
586
|
console.log(' cloud - Delete cloud files not present locally (cloud clean --dry-run|--yes)');
|
|
579
587
|
console.log(' live - Keep a business brain fresh (doctor, pull, watch, push)');
|
|
580
588
|
console.log(' clean-workspace <slug> - Analyze & remove junk files from a workspace (alias: cw)');
|
|
@@ -583,7 +591,7 @@ function showHelp() {
|
|
|
583
591
|
console.log(' browse [query] - Discover workspace templates');
|
|
584
592
|
console.log(' fork <template> - Clone a template into a new workspace');
|
|
585
593
|
console.log(' publish - Share your workspace as a template');
|
|
586
|
-
console.log(' pack -
|
|
594
|
+
console.log(' pack - Craft, publish, share, browse, or install an Atris brain zip');
|
|
587
595
|
console.log(' sleep [business|member] [--loop id] - Pause compute or flip a member switch');
|
|
588
596
|
console.log(' wake [business|member] [--loop id] - Resume compute or flip a member switch');
|
|
589
597
|
console.log('');
|
|
@@ -592,6 +600,8 @@ function showHelp() {
|
|
|
592
600
|
console.log(' business onboard - Onboard from sparse input (--name, --website, --contact)');
|
|
593
601
|
console.log(' business add <slug> - Connect a business');
|
|
594
602
|
console.log(' business list - Show connected businesses');
|
|
603
|
+
console.log(' business room [slug] - Show the live room from the production API');
|
|
604
|
+
console.log(' business store on - Enable the room store with its current catalog');
|
|
595
605
|
console.log(' business remove <slug> - Disconnect a business');
|
|
596
606
|
console.log(' business team [slug] - Show members, roles, and admin access');
|
|
597
607
|
console.log(' business health <slug> - Health report (members, workspace, issues)');
|
|
@@ -1617,6 +1627,11 @@ function showWelcomeVisualization() {
|
|
|
1617
1627
|
console.log(` learned \"${latestBriefTitle}\" overnight -> atris/wiki/briefs/${latestBriefName}`);
|
|
1618
1628
|
}
|
|
1619
1629
|
|
|
1630
|
+
const checkoutWarning = require('../lib/checkout-sync').checkoutBehindMessage(cwd);
|
|
1631
|
+
if (checkoutWarning) {
|
|
1632
|
+
console.log(` ${checkoutWarning}`);
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1620
1635
|
// Show the work itself, not counts. A newcomer in any domain (code, docs,
|
|
1621
1636
|
// a travel plan) should read actual task names and know what's happening.
|
|
1622
1637
|
// Waiting-on-you comes first: the one thing only a human can do.
|
|
@@ -1694,6 +1709,16 @@ function showWelcomeVisualization() {
|
|
|
1694
1709
|
console.log(row('tidy', tidyBits.join(', ')));
|
|
1695
1710
|
}
|
|
1696
1711
|
|
|
1712
|
+
let wikiNudge = '';
|
|
1713
|
+
try {
|
|
1714
|
+
wikiNudge = require('../lib/wiki').wikiMetabolismNudge(cwd);
|
|
1715
|
+
} catch {
|
|
1716
|
+
wikiNudge = '';
|
|
1717
|
+
}
|
|
1718
|
+
if (wikiNudge) {
|
|
1719
|
+
console.log(` ${wikiNudge}`);
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1697
1722
|
console.log(row('logs', journalEntries > 0
|
|
1698
1723
|
? `${journalEntries} note${journalEntries === 1 ? '' : 's'} today`
|
|
1699
1724
|
: 'nothing yet today'));
|
|
@@ -1792,6 +1817,21 @@ if (command === 'init') {
|
|
|
1792
1817
|
Promise.resolve(require('../commands/bench').benchCommand(process.argv.slice(3)))
|
|
1793
1818
|
.then((code) => process.exit(code || 0))
|
|
1794
1819
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(2); });
|
|
1820
|
+
} else if (command === 'router') {
|
|
1821
|
+
const code = require('../commands/router').routerCommand(process.argv.slice(3));
|
|
1822
|
+
if (Number.isInteger(code) && code !== 0) process.exit(code);
|
|
1823
|
+
} else if (command === 'decide') {
|
|
1824
|
+
// process.exit() can outrun a piped stdout: writes beyond the 64KB pipe
|
|
1825
|
+
// buffer are async, so large --json payloads truncate at 64KB multiples.
|
|
1826
|
+
// Queue an empty write and exit from its callback — it fires only after
|
|
1827
|
+
// every earlier buffered write has drained (BCK-1306).
|
|
1828
|
+
const exitAfterStdoutDrain = (code) => {
|
|
1829
|
+
if (process.stdout.writableLength === 0) process.exit(code);
|
|
1830
|
+
else process.stdout.write('', () => process.exit(code));
|
|
1831
|
+
};
|
|
1832
|
+
Promise.resolve(require('../commands/decide').decideCommand(process.argv.slice(3)))
|
|
1833
|
+
.then(() => exitAfterStdoutDrain(process.exitCode || 0))
|
|
1834
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); exitAfterStdoutDrain(1); });
|
|
1795
1835
|
} else if (command === 'mission') {
|
|
1796
1836
|
// process.exit() can outrun a piped stdout: writes beyond the 64KB pipe
|
|
1797
1837
|
// buffer are async, so large --json payloads truncate at 64KB multiples.
|
|
@@ -1804,6 +1844,10 @@ if (command === 'init') {
|
|
|
1804
1844
|
Promise.resolve(require('../commands/mission').missionCommand(process.argv.slice(3)))
|
|
1805
1845
|
.then(() => exitAfterStdoutDrain(process.exitCode || 0))
|
|
1806
1846
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); exitAfterStdoutDrain(1); });
|
|
1847
|
+
} else if (command === 'recover') {
|
|
1848
|
+
Promise.resolve(require('../commands/recover').recoverCommand(process.argv.slice(3)))
|
|
1849
|
+
.then((code) => process.exit(code || 0))
|
|
1850
|
+
.catch((err) => { console.error(`\nerror: ${err.message || err}`); process.exit(1); });
|
|
1807
1851
|
} else if (command === 'agents') {
|
|
1808
1852
|
// Glanceable view of every member's state: stuck, waiting on you, working, resting.
|
|
1809
1853
|
const code = require('../commands/agents').agentsCommand(process.argv.slice(3));
|
|
@@ -1931,8 +1975,17 @@ if (command === 'init') {
|
|
|
1931
1975
|
logCmd();
|
|
1932
1976
|
}
|
|
1933
1977
|
} else if (command === 'logs') {
|
|
1978
|
+
const logsArgs = process.argv.slice(3);
|
|
1979
|
+
if (logsArgs.includes('--help') || logsArgs.includes('-h') || logsArgs[0] === 'help') {
|
|
1980
|
+
console.log('Usage: atris logs [--date YYYY-MM-DD] [--json]');
|
|
1981
|
+
console.log('');
|
|
1982
|
+
console.log(' atris logs Show today\'s journal entries, completed receipts, and inbox in one view');
|
|
1983
|
+
console.log(' atris logs --date <day> Show the digest for a specific day');
|
|
1984
|
+
console.log(' atris logs --json Emit the digest as JSON');
|
|
1985
|
+
process.exit(0);
|
|
1986
|
+
}
|
|
1934
1987
|
try {
|
|
1935
|
-
require('../commands/log').logsDigest(
|
|
1988
|
+
require('../commands/log').logsDigest(logsArgs);
|
|
1936
1989
|
process.exit(0);
|
|
1937
1990
|
} catch (error) {
|
|
1938
1991
|
console.error(error.message || String(error));
|
|
@@ -1956,6 +2009,9 @@ if (command === 'init') {
|
|
|
1956
2009
|
activateCmd();
|
|
1957
2010
|
} else if (command === 'watch') {
|
|
1958
2011
|
require('../commands/watch').watchAtris();
|
|
2012
|
+
} else if (command === 'sync-checkout') {
|
|
2013
|
+
const code = require('../commands/sync-checkout').syncCheckoutCommand(process.argv.slice(3));
|
|
2014
|
+
process.exit(code);
|
|
1959
2015
|
} else if (command === 'update' || command === 'sync') {
|
|
1960
2016
|
const args = process.argv.slice(3);
|
|
1961
2017
|
const firstSyncArg = process.argv[3];
|
|
@@ -2514,6 +2570,10 @@ if (command === 'init') {
|
|
|
2514
2570
|
require('../commands/gm').gmCommand(...process.argv.slice(3))
|
|
2515
2571
|
.then(() => process.exit(0))
|
|
2516
2572
|
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2573
|
+
} else if (command === 'game') {
|
|
2574
|
+
require('../commands/game').gameCommand(process.argv.slice(3))
|
|
2575
|
+
.then((status) => process.exit(status === 1 ? 1 : 0))
|
|
2576
|
+
.catch((err) => { console.error(`✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2517
2577
|
} else if (command === 'github') {
|
|
2518
2578
|
const status = require('../commands/github').githubCommand(process.argv.slice(3));
|
|
2519
2579
|
process.exit(status);
|
|
@@ -2590,6 +2650,14 @@ if (command === 'init') {
|
|
|
2590
2650
|
const subcommand = process.argv[3];
|
|
2591
2651
|
const args = process.argv.slice(4);
|
|
2592
2652
|
require('../commands/lesson')(subcommand, ...args);
|
|
2653
|
+
} else if (command === 'taste') {
|
|
2654
|
+
Promise.resolve(require('../commands/taste').tasteCommand(process.argv.slice(3)))
|
|
2655
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2656
|
+
.catch((err) => { console.error(`taste could not continue: ${err.message || err}.`); process.exit(1); });
|
|
2657
|
+
} else if (command === 'teach') {
|
|
2658
|
+
const subcommand = process.argv[3];
|
|
2659
|
+
const args = process.argv.slice(4);
|
|
2660
|
+
require('../commands/teach')(subcommand, ...args);
|
|
2593
2661
|
} else if (command === 'skill') {
|
|
2594
2662
|
const subcommand = process.argv[3];
|
|
2595
2663
|
const args = process.argv.slice(4);
|
|
@@ -2759,6 +2827,10 @@ if (command === 'init') {
|
|
|
2759
2827
|
Promise.resolve(require('../commands/slop').slopCommand(process.argv.slice(3)))
|
|
2760
2828
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2761
2829
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2830
|
+
} else if (command === 'voice') {
|
|
2831
|
+
Promise.resolve(require('../commands/voice').voiceCommand(process.argv.slice(3)))
|
|
2832
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2833
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2762
2834
|
} else if (command === 'write') {
|
|
2763
2835
|
// Write: guided writing sessions — human types every word, atris structures + reviews (plan-do-review for prose).
|
|
2764
2836
|
Promise.resolve(require('../commands/write').writeCommand(process.argv.slice(3)))
|
package/commands/activate.js
CHANGED
|
@@ -110,6 +110,15 @@ function completionSentence(completions) {
|
|
|
110
110
|
return humanSentence(`since last time: ${landed}; the biggest: ${biggest}.`);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// STATUS.md bullets can carry paths and counts the gate would reject, so the
|
|
114
|
+
// narration only says that attention is needed, never quotes the bullet.
|
|
115
|
+
function wikiHealthSentence(wikiStatus) {
|
|
116
|
+
if (!wikiStatus || !Array.isArray(wikiStatus.bullets)) return null;
|
|
117
|
+
const needsAttention = wikiStatus.bullets.some((b) => /stale|orphan/i.test(b));
|
|
118
|
+
if (!needsAttention) return null;
|
|
119
|
+
return humanSentence('the wiki has pages going stale; refresh them: atris loop wiki');
|
|
120
|
+
}
|
|
121
|
+
|
|
113
122
|
function activeWorkSentence(state, context) {
|
|
114
123
|
const tasks = Array.isArray(context?.inProgressTasks) ? context.inProgressTasks : [];
|
|
115
124
|
if (tasks.length) {
|
|
@@ -237,13 +246,14 @@ function activateAtris() {
|
|
|
237
246
|
} catch {}
|
|
238
247
|
|
|
239
248
|
let moves = [];
|
|
249
|
+
let clarityLine = null;
|
|
240
250
|
try {
|
|
241
251
|
const { nextMoves } = require('../lib/next-moves');
|
|
242
252
|
const { profilePaths } = require('../lib/clarity');
|
|
243
253
|
const root = process.cwd();
|
|
244
254
|
moves = nextMoves(root, 3);
|
|
245
255
|
const { profile, mdPath } = readActivationClarityProfile(root, profilePaths);
|
|
246
|
-
formatClarityLine(profile, rel(mdPath));
|
|
256
|
+
clarityLine = formatClarityLine(profile, rel(mdPath));
|
|
247
257
|
} catch { /* alive onboarding is best-effort; never block activate */ }
|
|
248
258
|
|
|
249
259
|
let briefData = null;
|
|
@@ -258,7 +268,6 @@ function activateAtris() {
|
|
|
258
268
|
|
|
259
269
|
void dateFormatted;
|
|
260
270
|
void learningCount;
|
|
261
|
-
void wikiStatus;
|
|
262
271
|
fs.existsSync(personaFile);
|
|
263
272
|
fs.existsSync(mapFile);
|
|
264
273
|
void taskFilePath;
|
|
@@ -269,6 +278,7 @@ function activateAtris() {
|
|
|
269
278
|
handoffSentence(handoffContent),
|
|
270
279
|
completionSentence(recentCompletions),
|
|
271
280
|
activeWorkSentence(state, context),
|
|
281
|
+
wikiHealthSentence(wikiStatus),
|
|
272
282
|
].filter(Boolean);
|
|
273
283
|
if (Array.isArray(briefData?.waiting)) {
|
|
274
284
|
const approvalCount = briefData.waiting.length;
|
|
@@ -284,6 +294,9 @@ function activateAtris() {
|
|
|
284
294
|
statusLines.forEach((line) => console.log(line));
|
|
285
295
|
}
|
|
286
296
|
|
|
297
|
+
console.log('');
|
|
298
|
+
console.log(clarityLine || 'Tip: run atris clarity once so agents learn how you work.');
|
|
299
|
+
|
|
287
300
|
const nextMove = moves[0] || briefData?.moves?.[0];
|
|
288
301
|
const nextMoveTitle = focusFragment(nextMove?.title, 100);
|
|
289
302
|
if (nextMoveTitle) {
|
|
@@ -292,4 +305,4 @@ function activateAtris() {
|
|
|
292
305
|
}
|
|
293
306
|
}
|
|
294
307
|
|
|
295
|
-
module.exports = { activateAtris };
|
|
308
|
+
module.exports = { activateAtris, wikiHealthSentence };
|
package/commands/agent-spawn.js
CHANGED
|
@@ -2,6 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const { spawnSync } = require('child_process');
|
|
5
|
+
const { hasFlag: hasSingleFlag } = require('../lib/arg-parser');
|
|
5
6
|
|
|
6
7
|
const SPAWN_SCHEMA = 'atris.agent_spawn.v1';
|
|
7
8
|
const DOGFOOD_SCHEMA = 'atris.agent_cli_dogfood.v1';
|
|
@@ -63,8 +64,9 @@ function flagValue(args, names) {
|
|
|
63
64
|
return null;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
// This command accepts alias lists, while the shared helper checks one name.
|
|
68
|
+
function hasAnyFlag(args, names) {
|
|
69
|
+
return names.some(name => hasSingleFlag(args, name));
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
function positionalArgs(args) {
|
|
@@ -148,11 +150,11 @@ function commandForEngine(request) {
|
|
|
148
150
|
}
|
|
149
151
|
|
|
150
152
|
function parseSpawnArgs(args = []) {
|
|
151
|
-
const help = args.length === 0 ||
|
|
153
|
+
const help = args.length === 0 || hasAnyFlag(args, ['--help', '-h']) || args[0] === 'help';
|
|
152
154
|
if (help) return { help: true };
|
|
153
155
|
|
|
154
|
-
const json =
|
|
155
|
-
const dryRun =
|
|
156
|
+
const json = hasAnyFlag(args, ['--json']);
|
|
157
|
+
const dryRun = hasAnyFlag(args, ['--dry-run']);
|
|
156
158
|
const roleFlag = flagValue(args, ['--role']);
|
|
157
159
|
const engine = String(flagValue(args, ['--engine']) || 'manual').toLowerCase();
|
|
158
160
|
if (!ALLOWED_ENGINES.has(engine)) throw new Error(`Unknown engine: ${engine}`);
|
|
@@ -209,10 +211,10 @@ function showSpawnHelp(output = console.log, commandName = 'atris agent spawn')
|
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
function parseDogfoodArgs(args = []) {
|
|
212
|
-
const help =
|
|
213
|
-
const json =
|
|
214
|
-
const live =
|
|
215
|
-
const noWrite =
|
|
214
|
+
const help = hasAnyFlag(args, ['--help', '-h']) || args[0] === 'help';
|
|
215
|
+
const json = hasAnyFlag(args, ['--json']);
|
|
216
|
+
const live = hasAnyFlag(args, ['--live']);
|
|
217
|
+
const noWrite = hasAnyFlag(args, ['--no-write']);
|
|
216
218
|
const model = flagValue(args, ['--model']) || 'glm-5.2';
|
|
217
219
|
const timeoutRaw = Number(flagValue(args, ['--timeout']) || 45);
|
|
218
220
|
const timeoutMs = Math.max(5, Math.min(300, timeoutRaw)) * 1000;
|
|
@@ -431,7 +433,7 @@ function agentSpawnCommand(args = [], deps = {}) {
|
|
|
431
433
|
function agentSpawnListCommand(args = [], deps = {}) {
|
|
432
434
|
const root = deps.root || process.cwd();
|
|
433
435
|
const output = deps.output || ((line = '') => console.log(line));
|
|
434
|
-
const json =
|
|
436
|
+
const json = hasAnyFlag(args, ['--json']);
|
|
435
437
|
const requests = loadSpawnRequests(root).reverse();
|
|
436
438
|
const payload = { ok: true, action: 'spawn_list', requests, state_path: spawnStatePath(root) };
|
|
437
439
|
if (json) {
|
|
@@ -451,7 +453,7 @@ function agentSpawnListCommand(args = [], deps = {}) {
|
|
|
451
453
|
function agentSpawnStatusCommand(args = [], deps = {}) {
|
|
452
454
|
const root = deps.root || process.cwd();
|
|
453
455
|
const output = deps.output || ((line = '') => console.log(line));
|
|
454
|
-
const json =
|
|
456
|
+
const json = hasAnyFlag(args, ['--json']);
|
|
455
457
|
const id = positionalArgs(args)[0];
|
|
456
458
|
if (!id) throw new Error('Missing spawn id. Usage: atris agent spawn-status <id>');
|
|
457
459
|
const request = loadSpawnRequests(root).find(req => req.id === id);
|
|
@@ -463,18 +465,11 @@ function agentSpawnStatusCommand(args = [], deps = {}) {
|
|
|
463
465
|
}
|
|
464
466
|
|
|
465
467
|
module.exports = {
|
|
466
|
-
SPAWN_SCHEMA,
|
|
467
|
-
SPAWN_STATE_REL,
|
|
468
468
|
parseSpawnArgs,
|
|
469
|
-
buildDelegatePrompt,
|
|
470
469
|
commandForEngine,
|
|
471
470
|
createSpawnRequest,
|
|
472
471
|
agentDogfoodCommand,
|
|
473
|
-
parseDogfoodArgs,
|
|
474
|
-
runDogfoodEngine,
|
|
475
|
-
loadSpawnRequests,
|
|
476
472
|
agentSpawnCommand,
|
|
477
473
|
agentSpawnListCommand,
|
|
478
474
|
agentSpawnStatusCommand,
|
|
479
|
-
showSpawnHelp,
|
|
480
475
|
};
|
package/commands/autoland.js
CHANGED
|
@@ -6,7 +6,7 @@ const os = require('os');
|
|
|
6
6
|
const { spawnSync } = require('child_process');
|
|
7
7
|
|
|
8
8
|
const autoland = require('../lib/autoland');
|
|
9
|
-
const { gateForHuman } = require('../lib/voice-gate');
|
|
9
|
+
const { gateForHuman, plainLandingReason } = require('../lib/voice-gate');
|
|
10
10
|
const { evaluateAutoAccept } = require('../lib/auto-accept-certified');
|
|
11
11
|
const { operatorReady, hasAgentJargon, explainResult } = autoland;
|
|
12
12
|
const MISSION_AUTO_VERIFY_STATUSES = new Set(['planning', 'paused', 'ready']);
|
|
@@ -436,26 +436,9 @@ function protectedReviewWaiting(root, policy = {}, waiting = []) {
|
|
|
436
436
|
.filter((row) => !alreadyWaiting.has(row.ref));
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
denied_tag_deploy: 'a deploy: human decision required',
|
|
443
|
-
denied_tag_security: 'security: human decision required',
|
|
444
|
-
denied_tag_customer: 'customer-facing: human decision required',
|
|
445
|
-
denied_tag_external: 'outward-facing: human decision required',
|
|
446
|
-
denied_tag_feedback: 'customer feedback: human decision required',
|
|
447
|
-
needs_second_reviewer_or_third_pass: 'needs one more independent check first',
|
|
448
|
-
needs_independent_reviewer: 'built and judged by the same actor, needs an independent check',
|
|
449
|
-
verifier_is_builder: 'the re-check actor built this row, another actor must re-check',
|
|
450
|
-
judge_equals_worker: 'built and judged by the same actor, hand the review to someone else',
|
|
451
|
-
not_agent_certified: 'not certified yet',
|
|
452
|
-
insufficient_review_passes: 'not enough review passes yet',
|
|
453
|
-
strict_verify_missing: 'no recorded check command to re-run',
|
|
454
|
-
verify_failed: 'its check command failed on re-run',
|
|
455
|
-
proof_unmerged_or_draft_pr_boundary: 'its proof points at an unmerged draft',
|
|
456
|
-
};
|
|
457
|
-
return map[reason] || reason.replace(/_/g, ' ');
|
|
458
|
-
}
|
|
439
|
+
// One reason table for every human-facing landing refusal lives in
|
|
440
|
+
// lib/voice-gate.js (plainLandingReason); this alias keeps call sites short.
|
|
441
|
+
const plainReason = plainLandingReason;
|
|
459
442
|
|
|
460
443
|
function showStatus(root, args) {
|
|
461
444
|
const json = args.includes('--json');
|
|
@@ -470,9 +453,13 @@ function showStatus(root, args) {
|
|
|
470
453
|
const blocked = results.filter((r) => r.action !== 'would_accept');
|
|
471
454
|
const tasks = readProjection(root);
|
|
472
455
|
const waiting = autoland.waitingOnHuman(tasks);
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
456
|
+
// Ask the crontab, not the policy file. The cached flag is written once at
|
|
457
|
+
// `autoland on` time, so it reports "unknown" for a cron that has been
|
|
458
|
+
// running hourly for weeks, and would keep reporting "running" for one
|
|
459
|
+
// someone deleted. A loop that cannot confirm its own liveness from
|
|
460
|
+
// evidence cannot be trusted to say it is healthy.
|
|
461
|
+
const heartbeatInstalled = autoland.heartbeatLiveness(root, policy);
|
|
462
|
+
const heartbeatLive = autoland.heartbeatIsLive(root);
|
|
476
463
|
|
|
477
464
|
if (json) {
|
|
478
465
|
console.log(JSON.stringify({
|
|
@@ -488,7 +475,7 @@ function showStatus(root, args) {
|
|
|
488
475
|
}
|
|
489
476
|
|
|
490
477
|
console.log('');
|
|
491
|
-
console.log(
|
|
478
|
+
console.log(`autoland: ${autoland.certifiedWorkLandsPhrase(root)}; you keep the irreversible calls`);
|
|
492
479
|
console.log('');
|
|
493
480
|
const policyOwner = String(policy?.enabled_by || 'unknown').trim() || 'unknown';
|
|
494
481
|
const policyText = enabled
|
|
@@ -498,31 +485,33 @@ function showStatus(root, args) {
|
|
|
498
485
|
: 'off - everything waits for you';
|
|
499
486
|
console.log(` policy: ${policyText}`);
|
|
500
487
|
if (enabled && acceptAll) console.log(' bar: everything lands except the protected lanes (money, deploys, security, customer, outward)');
|
|
501
|
-
|
|
502
|
-
? 'running hourly'
|
|
503
|
-
: heartbeatInstalled === false
|
|
504
|
-
? 'not installed'
|
|
505
|
-
: 'unknown - run atris autoland on to check and repair';
|
|
506
|
-
console.log(` heartbeat: ${heartbeatText}`);
|
|
488
|
+
console.log(` heartbeat: ${autoland.heartbeatStatusText(root, policy)}`);
|
|
507
489
|
if (policy && policy.imessage_to) console.log(` daily message: ${policy.imessage_to} at ${policy.digest_hour ?? autoland.DEFAULT_DIGEST_HOUR}:00`);
|
|
508
490
|
const reapTrouble = autoland.readState(root).last_reap_error;
|
|
509
491
|
if (reapTrouble) console.log(` cleanup trouble: landing sweep failed on ${reapTrouble.date} (${reapTrouble.error}) - run: atris land --reap`);
|
|
510
492
|
console.log('');
|
|
511
|
-
if (readyForRecheck.length > 0) {
|
|
512
|
-
console.log(` ready for heartbeat recheck: ${readyForRecheck.length}`);
|
|
513
|
-
for (const r of readyForRecheck.slice(0, 10)) console.log(` rechecks then lands ${r.ref}`);
|
|
514
|
-
} else {
|
|
515
|
-
console.log(' nothing is ready to land on its own right now.');
|
|
516
|
-
}
|
|
517
493
|
const humanOnly = blocked.filter((r) => String(r.reason || '').startsWith('denied_tag_'));
|
|
518
494
|
const needsWork = blocked.filter((r) => !String(r.reason || '').startsWith('denied_tag_'));
|
|
519
495
|
if (humanOnly.length > 0) {
|
|
520
|
-
console.log(`
|
|
521
|
-
for (const r of humanOnly.slice(0, 10)) console.log(`
|
|
496
|
+
console.log(` yours to decide first: ${humanOnly.length} protected ${humanOnly.length === 1 ? 'review' : 'reviews'}.`);
|
|
497
|
+
for (const r of humanOnly.slice(0, 10)) console.log(` ${r.ref} waits for you; ${plainReason(r.reason)}.`);
|
|
498
|
+
}
|
|
499
|
+
if (readyForRecheck.length > 0) {
|
|
500
|
+
if (heartbeatLive) {
|
|
501
|
+
console.log(` landing on their own after the hourly recheck: ${readyForRecheck.length}.`);
|
|
502
|
+
for (const r of readyForRecheck.slice(0, 10)) console.log(` ${r.ref} passes the recheck, then lands itself.`);
|
|
503
|
+
} else {
|
|
504
|
+
console.log(` ready to land ${autoland.STALE_HEARTBEAT_LANDING}: ${readyForRecheck.length}.`);
|
|
505
|
+
for (const r of readyForRecheck.slice(0, 10)) {
|
|
506
|
+
console.log(` ${r.ref} passes the recheck, then lands ${autoland.STALE_HEARTBEAT_LANDING}.`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
console.log(' nothing is ready to land on its own right now.');
|
|
522
511
|
}
|
|
523
512
|
if (needsWork.length > 0) {
|
|
524
|
-
console.log(`
|
|
525
|
-
for (const r of needsWork.slice(0, 10)) console.log(`
|
|
513
|
+
console.log(` still needs work before it can land: ${needsWork.length}.`);
|
|
514
|
+
for (const r of needsWork.slice(0, 10)) console.log(` ${r.ref} stays put; ${plainReason(String(r.reason || ''))}.`);
|
|
526
515
|
}
|
|
527
516
|
if (waiting.length > 0) {
|
|
528
517
|
console.log('');
|
|
@@ -696,6 +685,28 @@ function persistTickReceipt(root, receipt) {
|
|
|
696
685
|
return receipt.receipt_path;
|
|
697
686
|
}
|
|
698
687
|
|
|
688
|
+
// A tick that scans a backlog, lands none of it, and prints only zeros is
|
|
689
|
+
// indistinguishable from a tick with no work. Say the standing numbers out
|
|
690
|
+
// loud, and call out the two states that mean the loop is wedged rather than
|
|
691
|
+
// idle: work blocked behind a check the harness could not execute, and work
|
|
692
|
+
// that passed every gate and still did not land.
|
|
693
|
+
// Heartbeat liveness helpers live in lib/autoland.js so task ready copy and
|
|
694
|
+
// status share one gate (recent tick receipt within two hours).
|
|
695
|
+
|
|
696
|
+
function stuckBacklogNote(receipt) {
|
|
697
|
+
const parts = [];
|
|
698
|
+
const scanned = Number(receipt.scanned || 0);
|
|
699
|
+
const certified = Number(receipt.certified || 0);
|
|
700
|
+
if (scanned > 0 && receipt.landed.length === 0) {
|
|
701
|
+
parts.push(`${certified}/${scanned} certified in review, none landed`);
|
|
702
|
+
}
|
|
703
|
+
const unrunnable = Array.isArray(receipt.unrunnable_verifiers) ? receipt.unrunnable_verifiers.length : 0;
|
|
704
|
+
if (unrunnable > 0) {
|
|
705
|
+
parts.push(`${unrunnable} blocked by a check this machine could not run`);
|
|
706
|
+
}
|
|
707
|
+
return parts.length ? `, ${parts.join(', ')}` : '';
|
|
708
|
+
}
|
|
709
|
+
|
|
699
710
|
function digestTickStatus(receipt) {
|
|
700
711
|
if (receipt.digest_sent) return 'sent';
|
|
701
712
|
if (receipt.digest_due) return 'saved';
|
|
@@ -734,6 +745,23 @@ function runTickBody(root, { json, policy, receipt }) {
|
|
|
734
745
|
.filter((r) => r.action === 'skipped' && r.proof_state === 'suite_green_citation_required')
|
|
735
746
|
.map((r) => ({ ref: r.ref, reason: r.reason }));
|
|
736
747
|
if (citationBlocks.length) receipt.citation_blocks = citationBlocks;
|
|
748
|
+
// A verifier the machine cannot execute is a broken harness, not a verdict
|
|
749
|
+
// on the diff. It must never sit quietly in the skipped pile: surface it
|
|
750
|
+
// as an alarm so a wedged loop is visible on the first tick, not the 480th.
|
|
751
|
+
// Not filtered by action: an unrunnable check surfaces as `skipped` from
|
|
752
|
+
// the eligibility gate and as `revised`/`revise_failed` from the landing
|
|
753
|
+
// gate. The reason is the signal, not the lane it came through.
|
|
754
|
+
const unrunnable = results
|
|
755
|
+
.filter((r) => r && r.action !== 'accepted' && r.reason === 'verify_unrunnable')
|
|
756
|
+
.map((r) => ({
|
|
757
|
+
ref: r.ref,
|
|
758
|
+
cause: r.unrunnable_cause || 'unknown',
|
|
759
|
+
command: r.command || r.verify || null,
|
|
760
|
+
}));
|
|
761
|
+
if (unrunnable.length) {
|
|
762
|
+
receipt.unrunnable_verifiers = unrunnable;
|
|
763
|
+
receipt.alarms = Number(receipt.alarms || 0) + unrunnable.length;
|
|
764
|
+
}
|
|
737
765
|
receipt.certified = parsed.certified ?? null;
|
|
738
766
|
receipt.scanned = parsed.scanned ?? null;
|
|
739
767
|
receipt.revised = parsed.revised ?? null;
|
|
@@ -956,7 +984,12 @@ function runTickBody(root, { json, policy, receipt }) {
|
|
|
956
984
|
const heldNote = receipt.missions_held ? `, held ${receipt.missions_held} human-blocked mission${receipt.missions_held === 1 ? '' : 's'}` : '';
|
|
957
985
|
const wishNote = `, ${wishSweepSummaryLine(receipt.wish_dispatch, receipt.wish_dispatch_error)}`;
|
|
958
986
|
const receiptNote = receipt.receipt_path ? `, receipt ${receipt.receipt_path}` : '';
|
|
959
|
-
|
|
987
|
+
// Deltas alone ("0 certified, 0 landed") are true and useless: they read
|
|
988
|
+
// as "nothing to do" whether the queue is empty or 19-deep and wedged.
|
|
989
|
+
// Always print the standing backlog, and name work that cleared every
|
|
990
|
+
// gate and still did not land — that is the shape of a stuck loop.
|
|
991
|
+
const stuckNote = stuckBacklogNote(receipt);
|
|
992
|
+
const summary = `autoland tick: ${receipt.reviews_certified ?? 0} reviews certified, ${receipt.landed.length} landed${receipt.landed.length ? ` (${receipt.landed.join(', ')})` : ''}, ${receipt.alarms} alarms${stuckNote}, digest ${digestTickStatus(receipt)}${reapNote}${janitorNote}${heldNote}${wishNote}${receiptNote}`;
|
|
960
993
|
console.log(gateForHuman(summary).text);
|
|
961
994
|
for (const fulfilled of receipt.wish_dispatch?.fulfilled_results || []) {
|
|
962
995
|
if (fulfilled.review_ask) console.log(fulfilled.review_ask);
|
|
@@ -967,7 +1000,7 @@ function runTickBody(root, { json, policy, receipt }) {
|
|
|
967
1000
|
|
|
968
1001
|
function showHelp() {
|
|
969
1002
|
console.log('');
|
|
970
|
-
console.log(
|
|
1003
|
+
console.log(`atris autoland: you approve the policy once; ${autoland.certifiedWorkLandsPhrase(process.cwd())}`);
|
|
971
1004
|
console.log('');
|
|
972
1005
|
console.log('finished work that passed its checks and two independent reviews lands');
|
|
973
1006
|
console.log('automatically with a receipt. money, deploys, security, customer, and');
|
|
@@ -1014,18 +1047,14 @@ function autolandCommand(args = []) {
|
|
|
1014
1047
|
|
|
1015
1048
|
module.exports = {
|
|
1016
1049
|
autolandCommand,
|
|
1017
|
-
attachedTasksForMission,
|
|
1018
1050
|
digestNextMoves,
|
|
1019
1051
|
digestStoryRows,
|
|
1020
1052
|
digestTickStatus,
|
|
1021
1053
|
explainResult,
|
|
1022
|
-
missionReadyForClosedTaskVerify,
|
|
1023
1054
|
operatorReady,
|
|
1024
1055
|
readAcceptedTaskHistory,
|
|
1025
1056
|
hasAgentJargon,
|
|
1026
1057
|
runTickBody,
|
|
1027
|
-
persistTickReceipt,
|
|
1028
1058
|
sweepLanding,
|
|
1029
1059
|
verifyClosedTaskMissions,
|
|
1030
|
-
wishSweepSummaryLine,
|
|
1031
1060
|
};
|
package/commands/autopilot.js
CHANGED
|
@@ -3825,7 +3825,6 @@ async function autopilotFromTodo(options = {}) {
|
|
|
3825
3825
|
}
|
|
3826
3826
|
|
|
3827
3827
|
module.exports = {
|
|
3828
|
-
appendTickSummary,
|
|
3829
3828
|
snapshotRepoHeads,
|
|
3830
3829
|
diffAdvancedRepoHeads,
|
|
3831
3830
|
reconcileTimedOutTick,
|
|
@@ -3833,10 +3832,7 @@ module.exports = {
|
|
|
3833
3832
|
findCompletionReceipt,
|
|
3834
3833
|
isDoPhaseTimeoutMessage,
|
|
3835
3834
|
validateVerifyCommandShape,
|
|
3836
|
-
askHuman,
|
|
3837
|
-
askModel,
|
|
3838
3835
|
autopilotAtris,
|
|
3839
|
-
autopilotFromTodo,
|
|
3840
3836
|
buildPrompt,
|
|
3841
3837
|
pendingExperimentTargets,
|
|
3842
3838
|
isLessonResolved,
|
|
@@ -3847,7 +3843,6 @@ module.exports = {
|
|
|
3847
3843
|
parseLessons,
|
|
3848
3844
|
pickUnresolvedFailLesson,
|
|
3849
3845
|
runLessonDetector,
|
|
3850
|
-
isStillTrue,
|
|
3851
3846
|
getTaskAgeDays,
|
|
3852
3847
|
getIdleTickCount,
|
|
3853
3848
|
getRecentSignals,
|
|
@@ -3865,14 +3860,8 @@ module.exports = {
|
|
|
3865
3860
|
renderHumanSuggestion,
|
|
3866
3861
|
renderHumanTickIntro,
|
|
3867
3862
|
proposeCandidateHorizons,
|
|
3868
|
-
recordTickCommit,
|
|
3869
|
-
regressionCheck,
|
|
3870
|
-
repoMapAuditReportsClean,
|
|
3871
|
-
isCleanMapBrokenRefFailLesson,
|
|
3872
|
-
inlinePythonVerifyFailureNowPasses,
|
|
3873
3863
|
runPlanReview,
|
|
3874
3864
|
runTaskOnce,
|
|
3875
|
-
buildPlanReviewPrompt,
|
|
3876
3865
|
parseVerdict,
|
|
3877
3866
|
scoreEndgameCandidates,
|
|
3878
3867
|
suggestNextTask,
|
|
@@ -3882,7 +3871,6 @@ module.exports = {
|
|
|
3882
3871
|
isPhaseKillError,
|
|
3883
3872
|
execPhaseCommandSync,
|
|
3884
3873
|
executePhaseDetailed,
|
|
3885
|
-
autopilotGlassLogDir,
|
|
3886
3874
|
buildAutopilotGlassLog,
|
|
3887
3875
|
writeAutopilotGlassLog,
|
|
3888
3876
|
lessonSlug
|