Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .audit/evidence/antigravity-receipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "fc9258dd04cfc5bde2a02e9e8f9ae57f1c1f9aa224a36fb5e754a2a37f73b4a2",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "6f52fd4f83e334a9486d679ea10ae8697c7f4fadc9f60ca089458b1734d60157",
Expand Down
2 changes: 1 addition & 1 deletion .audit/evidence/codex-receipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "6508f23e3fd2e3558706b36bcf9e16a5430cc6d6dea1a793ed1ad62d67710d0c",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "c49bb63726171f13f4390a60291cd60baf8e95b947b28a225dec9c1ce699e42c",
Expand Down
2 changes: 1 addition & 1 deletion .audit/evidence/grok-receipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "8843a79c3bc719865a29ae9028b91743d7e3c2db18d11ce038f2c51fe62bdf5a",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "7a376b005b83bf64c2d37729be88328f393bfad25b4e666c5eb2f78633def037",
Expand Down
10 changes: 5 additions & 5 deletions .audit/evidence/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "8843a79c3bc719865a29ae9028b91743d7e3c2db18d11ce038f2c51fe62bdf5a",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "7a376b005b83bf64c2d37729be88328f393bfad25b4e666c5eb2f78633def037",
Expand All @@ -40,7 +40,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "6508f23e3fd2e3558706b36bcf9e16a5430cc6d6dea1a793ed1ad62d67710d0c",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "c49bb63726171f13f4390a60291cd60baf8e95b947b28a225dec9c1ce699e42c",
Expand All @@ -64,7 +64,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "1c56d0d43197fceb1f48d4c7195ea2df0d25463a3364ab3eb7fd998d94a8cd86",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "ce6115598948c4b9c508a4fb143528f38d5452792a6b08c49ae4c8c42ba10243",
Expand All @@ -88,7 +88,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "76a2fc4a240a3b64da37275a6216c1e930e78bea8c215cff35e0d0f04690d073",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "a1c76eac8dc853128e63609d0f5bea60ae4e128de7a8577ca58730a297d8af0e",
Expand All @@ -112,7 +112,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "fc9258dd04cfc5bde2a02e9e8f9ae57f1c1f9aa224a36fb5e754a2a37f73b4a2",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "6f52fd4f83e334a9486d679ea10ae8697c7f4fadc9f60ca089458b1734d60157",
Expand Down
2 changes: 1 addition & 1 deletion .audit/evidence/omp-receipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "1c56d0d43197fceb1f48d4c7195ea2df0d25463a3364ab3eb7fd998d94a8cd86",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "ce6115598948c4b9c508a4fb143528f38d5452792a6b08c49ae4c8c42ba10243",
Expand Down
2 changes: 1 addition & 1 deletion .audit/evidence/opencode-receipt.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"canonical_pin": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"upstream_head": "88d47514b82e7c44f00f2b2a72ff6dd12158038c",
"spec_hash": "f403a35e9ce91413047544cd3cbfc1bba3baf9d56bd90a2e3863432d3fc5bf63",
"skills_tree_hash": "b56c01974623e7b66ae449aa83580787d4eecafc85a22954320e5a59744f1d0a",
"skills_tree_hash": "a6e1c952923504d7a836b183f267b2812c50c73b3f83e5e90802317c45d9d1ff",
"profile_hash": "76a2fc4a240a3b64da37275a6216c1e930e78bea8c215cff35e0d0f04690d073",
"package_descriptor_hash": "bfcfbca94227eb86857af749c975b55240f0c656d01b51e8349ad2780233ce99",
"manifest_hash": "a1c76eac8dc853128e63609d0f5bea60ae4e128de7a8577ca58730a297d8af0e",
Expand Down
299 changes: 299 additions & 0 deletions skills/poteto-mode/scripts/orch/frontier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
import { execFileSync } from "node:child_process";
import {
type Forge,
type FrontierPr,
type FrontierPrState,
UserError,
errorMessage,
isRecord,
isUnknownArray,
} from "./types.ts";

interface ForgePullRequestQuery {
readonly stateField: string;
readonly headField: string;
readonly baseField: string;
readonly states: ReadonlyMap<string, FrontierPrState>;
}

export const FORGE_PULL_REQUEST_QUERIES: Readonly<
Record<Forge, ForgePullRequestQuery>
> = {
gh: {
stateField: "state",
headField: "headRefName",
baseField: "baseRefName",
states: new Map<string, FrontierPrState>([
["OPEN", "OPEN"],
["MERGED", "MERGED"],
["CLOSED", "CLOSED"],
]),
},
origin: {
stateField: "status",
headField: "headRef",
baseField: "baseRef",
states: new Map<string, FrontierPrState>([
["open", "OPEN"],
["draft", "OPEN"],
["merged", "MERGED"],
["closed", "CLOSED"],
]),
},
};

interface ForgePullRequest {
readonly pr: number;
readonly state: FrontierPrState;
readonly branch: string;
readonly base: string;
}

export function runTool({
command,
args,
repo,
}: {
command: string;
args: readonly string[];
repo: string;
}): string {
try {
return execFileSync(command, args, {
cwd: repo,
encoding: "utf8",
env: process.env,
stdio: ["ignore", "pipe", "pipe"],
});
} catch (error) {
throw new UserError(
`${command} ${args.join(" ")} failed: ${errorMessage(error)}`
);
}
}

export function listPullRequests({
filter,
branch,
forge,
repo,
}: {
filter: "--head" | "--base";
branch: string;
forge: Forge;
repo: string;
}): readonly ForgePullRequest[] {
const query = FORGE_PULL_REQUEST_QUERIES[forge];
const command = `${forge} pr list ${filter} ${branch}`;
// Every state is fetched because a merged or closed PR still anchors the
// chain, and a draft counts as OPEN.
const raw = runTool({
command: forge,
args: [
"pr",
"list",
filter,
branch,
"--state",
"all",
"--json",
["number", query.stateField, query.headField, query.baseField].join(
","
),
],
repo,
});
let value: unknown;
try {
value = JSON.parse(raw);
} catch {
throw new UserError(`${command} output is not valid JSON`);
}
if (!isUnknownArray(value)) {
throw new UserError(`${command} output is not a JSON array`);
}
return value.map((row) => {
const status = isRecord(row) ? row[query.stateField] : undefined;
const state =
typeof status === "string" ? (query.states.get(status) ?? null) : null;
const head = isRecord(row) ? row[query.headField] : undefined;
const base = isRecord(row) ? row[query.baseField] : undefined;
if (
!isRecord(row) ||
typeof row.number !== "number" ||
!Number.isSafeInteger(row.number) ||
row.number < 1 ||
state === null ||
typeof head !== "string" ||
head.length === 0 ||
typeof base !== "string" ||
base.length === 0
) {
throw new UserError(`${command} output has an invalid PR row`);
}
return { pr: row.number, state, branch: head, base };
});
}

export function branchPullRequest({
branch,
forge,
repo,
}: {
branch: string;
forge: Forge;
repo: string;
}): ForgePullRequest {
const rows = listPullRequests({ filter: "--head", branch, forge, repo });
const row = rows[0];
if (row === undefined) {
throw new UserError(
`branch ${branch} has no pull request; open one with ${forge} pr create, or resolve the frontier from a branch whose chain is fully submitted`
);
}
if (rows.length > 1) {
throw new UserError(
`branch ${branch} has multiple pull requests (${rows.map((item) => `#${item.pr}`).join(", ")}); close the stale ones first`
);
}
return row;
}

export function openChildren({
branch,
forge,
repo,
}: {
branch: string;
forge: Forge;
repo: string;
}): readonly ForgePullRequest[] {
return listPullRequests({ filter: "--base", branch, forge, repo }).filter(
(row) => row.state === "OPEN"
);
}

export function runGit({
args,
repo,
}: {
args: readonly string[];
repo: string;
}): string {
return runTool({ command: "git", args, repo }).trim();
}

export function branchSha({
branch,
repo,
}: {
branch: string;
repo: string;
}): string {
const sha = runGit({ args: ["rev-parse", branch], repo });
if (!/^[0-9a-f]{40,64}$/i.test(sha)) {
throw new UserError(`git rev-parse ${branch} returned an invalid SHA`);
}
return sha;
}

export function currentBranch(repo: string): string {
return runGit({ args: ["symbolic-ref", "--short", "HEAD"], repo });
}

export function trunkBranch(repo: string): string {
try {
return runGit({
args: ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"],
repo,
}).replace(/^origin\//, "");
} catch {
// Init-plus-fetch checkouts and local fixtures lack origin/HEAD.
return "main";
}
}

export function resolveFrontier(repo: string, forge: Forge): readonly FrontierPr[] {
const trunk = trunkBranch(repo);
const current = currentBranch(repo);
if (current === trunk) {
return [];
}
const seen = new Set([current]);
let bottom = branchPullRequest({ branch: current, forge, repo });
const chain = [bottom];
while (bottom.base !== trunk) {
if (seen.has(bottom.base)) {
throw new UserError(
`pull request base chain loops at branch ${bottom.base}`
);
}
seen.add(bottom.base);
bottom = branchPullRequest({ branch: bottom.base, forge, repo });
chain.unshift(bottom);
}
let tip = current;
for (;;) {
const children = openChildren({ branch: tip, forge, repo });
const child = children[0];
if (child === undefined) {
break;
}
if (children.length > 1) {
throw new UserError(
`stack is not linear: branches ${children.map((row) => row.branch).join(", ")} all target ${tip}`
);
}
if (seen.has(child.branch)) {
throw new UserError(
`pull request base chain loops at branch ${child.branch}`
);
}
seen.add(child.branch);
chain.push(child);
tip = child.branch;
}
if (new Set(chain.map((row) => row.pr)).size !== chain.length) {
throw new UserError(
"pull request base chain contains duplicate pull requests"
);
}
return chain.map((row) => ({
pr: row.pr,
branches: row.branch,
sha: branchSha({ branch: row.branch, repo }),
state: row.state,
}));
}

export function validateFrontierPin({
actual,
expected,
}: {
actual: readonly number[];
expected: readonly number[];
}): void {
if (
actual.length === expected.length &&
actual.every((pr, index) => pr === expected[index])
) {
return;
}
const actualSet = new Set(actual);
const expectedSet = new Set(expected);
const missing = expected.filter((pr) => !actualSet.has(pr));
const extra = actual.filter((pr) => !expectedSet.has(pr));
const drift: string[] = [];
if (missing.length > 0) {
drift.push(`missing from resolved chain: ${missing.join(",")}`);
}
if (extra.length > 0) {
drift.push(`extra in resolved chain: ${extra.join(",")}`);
}
if (missing.length === 0 && extra.length === 0) {
drift.push(
`order differs: expected ${expected.join(",")}; resolved ${actual.join(",")}`
);
}
throw new UserError(`frontier pin mismatch: ${drift.join("; ")}`);
}
Loading
Loading