merge-pull refuses a head at whose fingerprint a run failed a required step (policy-failed, naming run, module, step), from the module's own state failed-steps kept from step-ended, with the seen keys of every step end and the deletion once no watched branch's head nor open pull request's head names a commit. The two tools read it with its fill and drop a key after the hand act. Builds: design 47 G §39, §83, §84, §85, §135, §475, §487, §548 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
45 lines
2.7 KiB
TypeScript
45 lines
2.7 KiB
TypeScript
// The tools of the forge module's state `failed-steps` (novox/hq design 47 §83, §84): the read of everything it holds, with the
|
|
// store's fill against its cap, and the one recovery, dropping a held key, written in the hand-act log before it is done.
|
|
|
|
import type { ToolDefinition } from "@novox/mesh-sdk/tools";
|
|
import { callerOf } from "@novox/mesh-sdk/callers";
|
|
import type { HandAct } from "@novox/mesh-sdk/views";
|
|
import type { FailedSteps } from "../failedsteps.js";
|
|
|
|
export function failedStepsTools(kept: FailedSteps, acts: (act: HandAct) => Promise<void>): ToolDefinition[] {
|
|
return [
|
|
{
|
|
name: "git_failed_steps",
|
|
description: "The failed required steps the forge module holds, by module and fingerprint, each with the run that failed it, the commits it was seen at and why; " +
|
|
"the `seen` keys (each commit's fingerprints, a commit's with `commit`); and the store's fill against its cap (design 47 §83, §487).",
|
|
input: { type: "object", properties: { commit: { type: "string", description: "only what names this commit" } } },
|
|
run: async (args: Record<string, unknown>) => {
|
|
const commit = typeof args.commit === "string" && args.commit !== "" ? args.commit : undefined;
|
|
const held = await kept.held(commit);
|
|
return { failed: held.failed.map((f) => ({ ...f, key: `${f.module}.${f.fingerprint}.${f.step}` })), seen: held.seen, fill: held.fill };
|
|
},
|
|
},
|
|
{
|
|
name: "git_failed_steps_drop",
|
|
description: "Drops one held key of the state failed-steps, a failed step by its key (<module>.<fingerprint>.<step>) or a seen key (seen.<commit>.<module>), with why; " +
|
|
"the head it refused merges. Written in the hand-act log first (design 47 §84).",
|
|
input: {
|
|
type: "object", required: ["key", "why"],
|
|
properties: { key: { type: "string", description: "the key, as git_failed_steps shows it" }, why: { type: "string", description: "why it is dropped, in plain words" } },
|
|
},
|
|
run: async (args: Record<string, unknown>) => {
|
|
const key = typeof args.key === "string" ? args.key.trim() : "";
|
|
const why = typeof args.why === "string" ? args.why.trim() : "";
|
|
if (!key || !why) throw new Error("git_failed_steps_drop names the key and why");
|
|
const by = callerOf(args);
|
|
try {
|
|
await acts({ what: `dropped the held ${key} of the forge module's failed-steps`, why: `${why} (${by})`, cause: "failed-step-dropped", verb: "git_failed_steps_drop" });
|
|
} catch (err) {
|
|
throw new Error(`the hand act was not recorded, so nothing was dropped: ${err instanceof Error ? err.message : String(err)}`);
|
|
}
|
|
return { dropped: await kept.drop(key), key, why, by };
|
|
},
|
|
},
|
|
];
|
|
}
|