looply-cli 0.5.32 → 0.5.34
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/dist/.src-hash +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -1
- package/dist/checkout-deps.d.ts +75 -0
- package/dist/checkout-deps.d.ts.map +1 -0
- package/dist/checkout-deps.js +154 -0
- package/dist/checkout-deps.js.map +1 -0
- package/dist/daemon-cmd.d.ts.map +1 -1
- package/dist/daemon-cmd.js +11 -0
- package/dist/daemon-cmd.js.map +1 -1
- package/dist/gate-health.d.ts +1 -1
- package/dist/gate-health.d.ts.map +1 -1
- package/dist/gate-health.js +26 -0
- package/dist/gate-health.js.map +1 -1
- package/dist/grant-waiting-wiring.d.ts +5 -0
- package/dist/grant-waiting-wiring.d.ts.map +1 -1
- package/dist/grant-waiting-wiring.js +5 -0
- package/dist/grant-waiting-wiring.js.map +1 -1
- package/dist/run-cmd.d.ts.map +1 -1
- package/dist/run-cmd.js +60 -6
- package/dist/run-cmd.js.map +1 -1
- package/dist/tool-bridge.d.ts.map +1 -1
- package/dist/tool-bridge.js +7 -2
- package/dist/tool-bridge.js.map +1 -1
- package/dist/trusted-git.d.ts.map +1 -1
- package/dist/trusted-git.js +6 -1
- package/dist/trusted-git.js.map +1 -1
- package/dist/untrusted-exec.d.ts +37 -0
- package/dist/untrusted-exec.d.ts.map +1 -1
- package/dist/untrusted-exec.js +46 -2
- package/dist/untrusted-exec.js.map +1 -1
- package/dist/verifier.d.ts +2 -0
- package/dist/verifier.d.ts.map +1 -1
- package/dist/verifier.js +4 -1
- package/dist/verifier.js.map +1 -1
- package/dist/verify-cmd.d.ts +15 -1
- package/dist/verify-cmd.d.ts.map +1 -1
- package/dist/verify-cmd.js +21 -3
- package/dist/verify-cmd.js.map +1 -1
- package/dist/verify-pass.d.ts +6 -1
- package/dist/verify-pass.d.ts.map +1 -1
- package/dist/verify-pass.js +4 -1
- package/dist/verify-pass.js.map +1 -1
- package/dist/visual-proof-run.d.ts +6 -0
- package/dist/visual-proof-run.d.ts.map +1 -1
- package/dist/visual-proof-run.js +26 -1
- package/dist/visual-proof-run.js.map +1 -1
- package/dist/visual-proof-store.d.ts +8 -0
- package/dist/visual-proof-store.d.ts.map +1 -1
- package/dist/visual-proof-store.js +5 -0
- package/dist/visual-proof-store.js.map +1 -1
- package/dist/visual-proof.d.ts.map +1 -1
- package/dist/visual-proof.js +1 -0
- package/dist/visual-proof.js.map +1 -1
- package/dist/workspace-provisioner.d.ts +1 -0
- package/dist/workspace-provisioner.d.ts.map +1 -1
- package/dist/workspace-provisioner.js +2 -1
- package/dist/workspace-provisioner.js.map +1 -1
- package/dist/workspace.d.ts +21 -0
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +59 -0
- package/dist/workspace.js.map +1 -1
- package/package.json +2 -2
- package/win/acl-grant.ps1 +96 -0
- package/win/appcontainer.ps1 +27 -5
package/dist/run-cmd.js
CHANGED
|
@@ -28,6 +28,7 @@ const evidence_cache_1 = require("./evidence-cache");
|
|
|
28
28
|
const control_file_1 = require("./control-file");
|
|
29
29
|
const git_driver_1 = require("./git-driver");
|
|
30
30
|
const untrusted_gate_1 = require("./untrusted-gate");
|
|
31
|
+
const checkout_deps_1 = require("./checkout-deps");
|
|
31
32
|
const model_transport_1 = require("./model-transport");
|
|
32
33
|
const agent_envelope_1 = require("./agent-envelope");
|
|
33
34
|
const provider_limit_1 = require("./provider-limit");
|
|
@@ -2862,6 +2863,10 @@ async function runLoop(opts) {
|
|
|
2862
2863
|
const adaptiveTier = adaptiveBudget.compile;
|
|
2863
2864
|
let compileTimedOut = false;
|
|
2864
2865
|
let checkTimedOut = false;
|
|
2866
|
+
// RBB-B-218: the step check's own tier, and whether a pass this run checked nothing in time.
|
|
2867
|
+
const verifyKey = binding.kind === 'bound' ? (0, verify_cmd_2.verifyTimeoutKey)(binding.goal.id, binding.goal.version) : null;
|
|
2868
|
+
const verifyTier = (0, verify_cmd_2.verifierTierFor)(verifyKey === null ? 0 : (0, planner_timeouts_1.plannerTimeoutsFor)(projectStateDirPath, verifyKey));
|
|
2869
|
+
let verifyTimedOut = false;
|
|
2865
2870
|
/**
|
|
2866
2871
|
* A PLANNER THAT RAN OUT OF TIME IS THE MACHINE'S LIMIT, NOT THE GOAL'S FAULT: the run leaves
|
|
2867
2872
|
* with `environment` / `planner_timeout`, so the controller voids this Start (it costs no try),
|
|
@@ -2873,6 +2878,16 @@ async function runLoop(opts) {
|
|
|
2873
2878
|
* at the same eight minutes again — finished work that is never judged is never delivered.
|
|
2874
2879
|
*/
|
|
2875
2880
|
const plannerTimedOut = (message) => {
|
|
2881
|
+
/**
|
|
2882
|
+
* A STEP CHECK THAT RAN OUT OF TIME, with nothing made ready (RBB-B-218): the machine's limit.
|
|
2883
|
+
* The goal is neither judged nor re-planned on it — four plans were spent that way on steps
|
|
2884
|
+
* never tried, and the goal ended "plan_limit_reached" with nothing delivered.
|
|
2885
|
+
*/
|
|
2886
|
+
if (verifyTimedOut && verifyKey !== null) {
|
|
2887
|
+
const n = (0, planner_timeouts_1.notePlannerTimeout)(projectStateDirPath, verifyKey);
|
|
2888
|
+
return new RunRefused(`${message} — checking this plan's steps against the code took longer than its limit; the next Start checks each with ` +
|
|
2889
|
+
`${Math.round((0, verify_cmd_2.verifierTierFor)(n).timeoutMs / 60000)} minutes, and this Start does not count`, 'environment', undefined, undefined, 'planner_timeout');
|
|
2890
|
+
}
|
|
2876
2891
|
if (checkTimedOut && binding.kind === 'bound') {
|
|
2877
2892
|
const n = (0, planner_timeouts_1.notePlannerTimeout)(projectStateDirPath, (0, adaptive_budget_1.goalCheckTimeoutKey)(binding.goal.id, binding.goal.version));
|
|
2878
2893
|
return new RunRefused(`${message} — the goal check took longer than its limit; the next Start checks with ${Math.round((0, goal_gap_1.goalCheckTimeoutFor)(n) / 60000)} minutes, ` +
|
|
@@ -2885,7 +2900,7 @@ async function runLoop(opts) {
|
|
|
2885
2900
|
return new RunRefused(`${message} — planning took longer than its limit; the next Start plans with ${Math.round(next.timeoutMs / 60000)} minutes ` +
|
|
2886
2901
|
`for at most ${next.maxSteps} steps, and this Start does not count`, 'environment', undefined, undefined, 'planner_timeout');
|
|
2887
2902
|
};
|
|
2888
|
-
let verifyBudget = Math.min(verify_cmd_2.VERIFY_MAX_PER_RUN, compileTier.maxSteps);
|
|
2903
|
+
let verifyBudget = Math.min(verify_cmd_2.VERIFY_MAX_PER_RUN, compileTier.maxSteps, verifyTier.maxPerRun);
|
|
2889
2904
|
/**
|
|
2890
2905
|
* EVERYTHING A START DOES BEFORE THE RUN, under one guard.
|
|
2891
2906
|
*
|
|
@@ -3308,7 +3323,7 @@ async function runLoop(opts) {
|
|
|
3308
3323
|
const pass = await (0, verify_pass_1.verifyDrafts)({
|
|
3309
3324
|
queue: runQueue,
|
|
3310
3325
|
ledger: ledgerForRun,
|
|
3311
|
-
verify: (0, verify_cmd_1.makeItemVerifier)(verifyAgent, queue),
|
|
3326
|
+
verify: (0, verify_cmd_1.makeItemVerifier)(verifyAgent, queue, verifyTier.timeoutMs),
|
|
3312
3327
|
cachePut: (id, head, ev) => evidence.put(id, head, ev),
|
|
3313
3328
|
headSha: () => git.headSha(),
|
|
3314
3329
|
projectId,
|
|
@@ -3329,6 +3344,8 @@ async function runLoop(opts) {
|
|
|
3329
3344
|
verifyBudget -= pass.checked;
|
|
3330
3345
|
log(`verify : ${pass.ready} of ${pass.checked} are ready to work on`);
|
|
3331
3346
|
pickable = pass.ready;
|
|
3347
|
+
if (pass.ready === 0 && pass.timedOut > 0)
|
|
3348
|
+
verifyTimedOut = true;
|
|
3332
3349
|
}
|
|
3333
3350
|
}
|
|
3334
3351
|
/**
|
|
@@ -3349,7 +3366,8 @@ async function runLoop(opts) {
|
|
|
3349
3366
|
* work, and it is never reached again afterwards. `runner.run()` returns to a
|
|
3350
3367
|
* `finally` that does nothing but clean up.
|
|
3351
3368
|
*/
|
|
3352
|
-
|
|
3369
|
+
// A pass that checked nothing in time judges nothing: the goal check and a new plan wait for a Start that can (RBB-B-218).
|
|
3370
|
+
if (!pickable && scope !== null && binding.kind === 'bound' && !compiledThisRun && !verifyTimedOut) {
|
|
3353
3371
|
const bound = binding.goal;
|
|
3354
3372
|
// Captured, because `scope` moves when a new plan is materialised below and
|
|
3355
3373
|
// the callbacks here must go on describing the goal they were built for.
|
|
@@ -3737,7 +3755,7 @@ async function runLoop(opts) {
|
|
|
3737
3755
|
const pass = await (0, verify_pass_1.verifyDrafts)({
|
|
3738
3756
|
queue: runQueue,
|
|
3739
3757
|
ledger: ledgerForRun,
|
|
3740
|
-
verify: (0, verify_cmd_1.makeItemVerifier)(verifyAgent, queue),
|
|
3758
|
+
verify: (0, verify_cmd_1.makeItemVerifier)(verifyAgent, queue, verifyTier.timeoutMs),
|
|
3741
3759
|
cachePut: (id, head, ev) => evidence.put(id, head, ev),
|
|
3742
3760
|
headSha: () => git.headSha(),
|
|
3743
3761
|
projectId,
|
|
@@ -3750,6 +3768,8 @@ async function runLoop(opts) {
|
|
|
3750
3768
|
verifyBudget -= pass.checked;
|
|
3751
3769
|
log(`verify : ${pass.ready} of ${pass.checked} are ready to work on`);
|
|
3752
3770
|
pickable = pass.ready;
|
|
3771
|
+
if (pass.ready === 0 && pass.timedOut > 0)
|
|
3772
|
+
verifyTimedOut = true;
|
|
3753
3773
|
}
|
|
3754
3774
|
}
|
|
3755
3775
|
}
|
|
@@ -3771,6 +3791,8 @@ async function runLoop(opts) {
|
|
|
3771
3791
|
return reproAsks;
|
|
3772
3792
|
if (seamFailure !== null)
|
|
3773
3793
|
return `could not check this goal — ${seamFailure}`;
|
|
3794
|
+
if (verifyTimedOut && adaptive === null)
|
|
3795
|
+
return `no step of this plan could be checked against the code in time — ${(0, queue_summary_1.describeNoReady)(runQueue.list())}`;
|
|
3774
3796
|
const said = adaptive === null ? null : (0, goal_adaptive_1.describeAdaptive)(adaptive, attestedNow(), coverage);
|
|
3775
3797
|
if (said !== null)
|
|
3776
3798
|
return said.message;
|
|
@@ -3906,6 +3928,12 @@ async function runLoop(opts) {
|
|
|
3906
3928
|
throw said.terminal ? new RunRefused(said.message, said.code, refusedOn, delivery) : (plannerTimedOut(said.message) ?? new Error(said.message));
|
|
3907
3929
|
}
|
|
3908
3930
|
}
|
|
3931
|
+
if (verifyTimedOut) {
|
|
3932
|
+
// Before the work-set exits: a step left `unclear` by a timeout is not a person's question.
|
|
3933
|
+
await releaseHold();
|
|
3934
|
+
const unchecked = `no step of this plan could be checked against the code in time — ${(0, queue_summary_1.describeNoReady)(runQueue.list())}`;
|
|
3935
|
+
throw plannerTimedOut(unchecked) ?? new Error(unchecked);
|
|
3936
|
+
}
|
|
3909
3937
|
const left = scope === null ? null : (0, core_1.workLeft)(runQueue.list());
|
|
3910
3938
|
if (left === 'finished') {
|
|
3911
3939
|
// A WORK-SET fact, not a goal verdict: every row reached a terminal state.
|
|
@@ -4417,6 +4445,26 @@ async function runLoop(opts) {
|
|
|
4417
4445
|
* not when AutoRyn or the file switched it off (`gates.baseCheck`, `run.base_check`).
|
|
4418
4446
|
*/
|
|
4419
4447
|
const baseCheckWanted = binding.kind === 'bound' && effectiveGates.baseCheck && config.run.baseCheck !== false;
|
|
4448
|
+
/**
|
|
4449
|
+
* THE CHECKS' DEPENDENCIES, BEFORE ANYTHING IS JUDGED (AUT-B-62, `checkout-deps.ts`): a package folder the
|
|
4450
|
+
* gates run in, with a lockfile but no `node_modules`, is installed from its lockfile in the checkout's
|
|
4451
|
+
* sandbox — with internet access, which the gates themselves never get. A failed install is a machine
|
|
4452
|
+
* fault in the package manager's own words, never a red base.
|
|
4453
|
+
*/
|
|
4454
|
+
const depsWanted = binding.kind === 'bound';
|
|
4455
|
+
let depsInstalled = false;
|
|
4456
|
+
const dependenciesBeforeFirstRound = async () => {
|
|
4457
|
+
const plan = (0, checkout_deps_1.dependencyInstallPlan)(config.gates, (0, checkout_deps_1.checkoutDepsFs)(cwd));
|
|
4458
|
+
if (plan.length === 0)
|
|
4459
|
+
return { ok: true };
|
|
4460
|
+
const out = await (0, checkout_deps_1.installDependencies)({ plan, runner: (0, untrusted_gate_1.makeUntrustedGateRunner)(cwd, { network: 'internet-client' }), log });
|
|
4461
|
+
if (out.kind === 'failed') {
|
|
4462
|
+
log(`deps : ${out.because}`);
|
|
4463
|
+
return { ok: false, because: out.because };
|
|
4464
|
+
}
|
|
4465
|
+
depsInstalled = out.kind === 'installed';
|
|
4466
|
+
return { ok: true };
|
|
4467
|
+
};
|
|
4420
4468
|
const baseHealthBeforeFirstRound = async () => {
|
|
4421
4469
|
const steps = config.gates;
|
|
4422
4470
|
let record;
|
|
@@ -4424,7 +4472,8 @@ async function runLoop(opts) {
|
|
|
4424
4472
|
const treeSha = await git.headTreeSha();
|
|
4425
4473
|
const key = (0, gate_health_1.baseHealthKey)(treeSha, steps);
|
|
4426
4474
|
record = (0, gate_health_1.readBaseHealth)(projectStateDirPath);
|
|
4427
|
-
|
|
4475
|
+
// Dependencies installed this run: what any earlier check of this base said was said without them.
|
|
4476
|
+
if (!depsInstalled && (0, gate_health_1.reusable)(record, key, Date.now())) {
|
|
4428
4477
|
log(`base : the checks on this base were ${record.state} at ${record.checkedAt}`);
|
|
4429
4478
|
}
|
|
4430
4479
|
else {
|
|
@@ -4521,7 +4570,7 @@ async function runLoop(opts) {
|
|
|
4521
4570
|
* The runner calls this after its own preconditions and after an item is
|
|
4522
4571
|
* picked, which is the first moment a round is certain.
|
|
4523
4572
|
*/
|
|
4524
|
-
...((retryToSpend === null || safety === null) && !baseCheckWanted
|
|
4573
|
+
...((retryToSpend === null || safety === null) && !baseCheckWanted && !depsWanted
|
|
4525
4574
|
? {}
|
|
4526
4575
|
: {
|
|
4527
4576
|
beforeFirstRound: async () => {
|
|
@@ -4529,6 +4578,11 @@ async function runLoop(opts) {
|
|
|
4529
4578
|
* THE BASE FIRST: a check red on the unchanged code would throw away every round,
|
|
4530
4579
|
* so it is found here, before the one retry below is spent on a round it would doom.
|
|
4531
4580
|
*/
|
|
4581
|
+
if (depsWanted) {
|
|
4582
|
+
const deps = await dependenciesBeforeFirstRound();
|
|
4583
|
+
if (!deps.ok)
|
|
4584
|
+
return deps;
|
|
4585
|
+
}
|
|
4532
4586
|
if (baseCheckWanted) {
|
|
4533
4587
|
const health = await baseHealthBeforeFirstRound();
|
|
4534
4588
|
if (!health.ok)
|