@uchibeke/gallivant 0.2.0 → 0.2.1
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 +93 -55
- package/bin/gallivant.mjs +8 -4
- package/docs/README.md +4 -2
- package/docs/agent-setup.md +55 -41
- package/docs/commands.md +38 -9
- package/docs/config.md +10 -3
- package/docs/execution.md +1 -1
- package/docs/install.md +123 -63
- package/docs/launch.md +7 -4
- package/docs/openai-agents.md +1 -1
- package/docs/preparation.md +1 -1
- package/docs/releasing.md +31 -22
- package/docs/task-delivery.md +1 -1
- package/lib/commands/doctor.mjs +15 -6
- package/lib/commands/init.mjs +238 -27
- package/lib/commands/register.mjs +56 -2
- package/lib/context.mjs +5 -3
- package/lib/execution.mjs +84 -8
- package/lib/fs.mjs +10 -3
- package/lib/task_delivery_contract.mjs +1 -1
- package/lib/tick.mjs +21 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/lib/tick.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import { ROUND_MARKER, NUDGE_MARKER, READY_LABEL, NEEDS_LABEL, actor, normalizeL
|
|
|
20
20
|
import { publicPrViolations, publicCommentViolations, publicCorrection, publicReviewHash } from "./public_output.mjs";
|
|
21
21
|
import { hasLegacyStatusLabels } from "./public-format.mjs";
|
|
22
22
|
import { adapterFor, buildRun, capabilitiesFor } from "./harness.mjs";
|
|
23
|
-
import { executionRunner, unsubmittedInitialDispatch } from "./execution.mjs";
|
|
23
|
+
import { executionRunner, reserveExecutionEpoch, unsubmittedInitialDispatch } from "./execution.mjs";
|
|
24
24
|
import { reconcileExecutionResult, executionResultCheckpoint, requireVerificationSandbox } from "./execution_result.mjs";
|
|
25
25
|
import { readJson } from "./fs.mjs";
|
|
26
26
|
import { join } from "node:path";
|
|
@@ -453,6 +453,16 @@ export function makeTick(deps) {
|
|
|
453
453
|
prompt = `THE BRIEF HAS CHANGED. Reread the brief and its carried files in the worktree.\n${entry.brief_changes.join("\n")}\n\n${prompt}`;
|
|
454
454
|
}
|
|
455
455
|
const execution = runnerFor(id), remote = execution.capabilities?.transport === "remote";
|
|
456
|
+
if (execution.ledgerEpoch > 0) reserveExecutionEpoch({ root: execution.root, taskId: id,
|
|
457
|
+
provider: entry.harness, account: execution.account, epoch: execution.ledgerEpoch, pr: entry.pr });
|
|
458
|
+
// A registration made by older code can be recognized from its exact settled
|
|
459
|
+
// old ledger without modifying that ledger. Persist the chosen new epoch
|
|
460
|
+
// before the first launch changes `last` and `execution`, which are the
|
|
461
|
+
// evidence the read-only recovery rule needs on later process starts.
|
|
462
|
+
if (execution.ledgerEpoch > 0 && entry.execution_epoch == null) {
|
|
463
|
+
entry = state.update(id, { execution_epoch: execution.ledgerEpoch,
|
|
464
|
+
execution_handoff: { from: entry.execution?.provider, to: entry.harness, previousRun: entry.last?.run ?? null, at: now() } });
|
|
465
|
+
}
|
|
456
466
|
const mode = entry.session ? "resume" : "start";
|
|
457
467
|
const session = entry.session || entry.learning_continuity?.newSession || (remote ? null : adapterFor(entry.harness).newSession());
|
|
458
468
|
// Extra read-only directories, resolved in one place (lib/config.mjs) from the operator's config list plus the
|
|
@@ -924,9 +934,16 @@ export function makeTick(deps) {
|
|
|
924
934
|
// would undo the record that was just made.
|
|
925
935
|
if (merged?.merged) entry = state.get(id) ?? entry;
|
|
926
936
|
const fix = { repo: entry.repo, pr: entry.pr, headSha: pr.headRefOid, events, receipt: receiptFor(id), denials, merged: merged?.merged ? merged : null };
|
|
937
|
+
const previousHarness = entry.execution_handoff?.from ?? (entry.execution?.provider !== entry.harness ? entry.execution?.provider : null);
|
|
938
|
+
// Recovery from a lost registry rebuilds the entry from the PR block, so
|
|
939
|
+
// neither of those fields survives. The durable ledger epoch still proves
|
|
940
|
+
// this is a cross-harness takeover and calls for the same context prompt.
|
|
941
|
+
const handoff = !entry.session && (previousHarness || runnerFor(id).ledgerEpoch > 0)
|
|
942
|
+
? `The operator switched this PR from ${previousHarness || "a previous harness"} to ${entry.harness}. This is a new provider session; the previous conversation is unavailable. Before editing, read the approved brief${entry.prd ? ` at ${entry.prd}` : " if one is recorded"}, its carried files, the PR and review threads, and the local checkout's status and unpushed commits. Preserve existing work and review unresolved feedback. The brief's original harness field records its starting route; this explicit PR reset selected ${entry.harness} for subsequent work.`
|
|
943
|
+
: null;
|
|
927
944
|
const prompt = entry.session
|
|
928
945
|
? fixPrompt({ ...fix, verify: verifyFor(id) })
|
|
929
|
-
: `${registerPrompt({ repo: entry.repo, pr: entry.pr })}\n\n${fixPrompt({ ...fix, verify: [] })}`;
|
|
946
|
+
: `${registerPrompt({ repo: entry.repo, pr: entry.pr })}${handoff ? `\n\n${handoff}` : ""}\n\n${fixPrompt({ ...fix, verify: [] })}`;
|
|
930
947
|
// The invariant: a spawned run must be recorded before anything else can fail. Everything that can throw goes
|
|
931
948
|
// above the spawn, and the state that owns the run is saved immediately below it with no await in between. A
|
|
932
949
|
// process running that the registry does not know about is the worst state this function can leave: `settleRun`
|
|
@@ -1152,6 +1169,8 @@ export function makeTick(deps) {
|
|
|
1152
1169
|
if (await cancelControl(deps, id)) return;
|
|
1153
1170
|
if (!settleOnly && await recoverControl(deps, id)) return;
|
|
1154
1171
|
const execution = runnerFor(id);
|
|
1172
|
+
if (execution.ledgerEpoch > 0) reserveExecutionEpoch({ root: execution.root, taskId: id,
|
|
1173
|
+
provider: entry.harness, account: execution.account, epoch: execution.ledgerEpoch, pr: entry.pr });
|
|
1155
1174
|
if (execution.reconcile) {
|
|
1156
1175
|
if (!skipReconciliation) await execution.reconcile({ force: startupReconciliation.delete(id) });
|
|
1157
1176
|
const pending = execution.current();
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uchibeke/gallivant",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@uchibeke/gallivant",
|
|
9
|
-
"version": "0.2.
|
|
9
|
+
"version": "0.2.1",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"smol-toml"
|
|
12
12
|
],
|
package/package.json
CHANGED