Files
mesh-catalog/modules/gitea/tools/failedsteps.ts
T
jschoubben bc2e5574ef GIT7, GIT8: the forge module keeps the runner's failed required steps and refuses a head by them; git_failed_steps and git_failed_steps_drop
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
2026-11-11 14:01:27 +01:00

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 };
},
},
];
}