diff --git a/.github/GOVERNANCE.md b/.github/GOVERNANCE.md index 5c1273f068..aba5c2f9a5 100644 --- a/.github/GOVERNANCE.md +++ b/.github/GOVERNANCE.md @@ -208,7 +208,7 @@ access, and takes effect only when the invited contributor accepts it. | [`@hhyykk`](https://github.com/hhyykk) | Write | Active external collaborator; the 2026-10-21 organization invitation is no longer pending, and active organization membership was not established | | [`@maxliux5`](https://github.com/maxliux5) | Write | Active; external collaborator | | [`@JackyCSer`](https://github.com/JackyCSer) | Write | Active; organization Member | -| [`@cocolord`](https://github.com/cocolord) | Write | Active; organization Member | +| [`@cocolord`](https://github.com/cocolord) | Maintain | Active organization Member; repository role updated 2026-11-07 | | [`@wujc12`](https://github.com/wujc12) | Write | Active; organization Member | | [`@songoow`](https://github.com/songoow) | Maintain | Active; organization Member | | [`@now-ing`](https://github.com/now-ing) | Write | Active; organization Member | @@ -274,6 +274,19 @@ Update this snapshot through a pull request when invitations are accepted, expire or are otherwise resolved. Maintainer appointments follow the separate process below. +On 2026-11-07, the lead maintainer granted `@cocolord` repository Maintain +to help carry the small-kernel refactors through review and merge. Recent +work includes deferred loading at the Host and process boundaries in +[#8185](https://github.com/loopx-project/loopx/pull/8185) and CLI registry +inspection in [#8233](https://github.com/loopx-project/loopx/pull/8233). +The existing [main ruleset](https://github.com/loopx-project/loopx/rules/18121976) +allows Maintain holders to bypass branch rules when merging through a PR. +The [repository merge policy](../AGENTS.md#merge-authority-and-validation) +still requires explicit maintainer authorization, review of the proposed +revision and validation for core refactors. Its limits on merging one's own +PRs continue to apply. Code ownership and release authority follow their +separate procedures. + ## Subsystem Maintainers A subsystem maintainer is accountable for review quality and contract diff --git a/apps/presentation/dashboard/smoke/goal-acceptance-contract-smoke.mjs b/apps/presentation/dashboard/smoke/goal-acceptance-contract-smoke.mjs index 9cd8ec23b1..f1a326f38e 100644 --- a/apps/presentation/dashboard/smoke/goal-acceptance-contract-smoke.mjs +++ b/apps/presentation/dashboard/smoke/goal-acceptance-contract-smoke.mjs @@ -31,6 +31,9 @@ for (const copy of Object.values(deliveryReviewCopy)) { scope: { kind: "selected_work", todo_ids: ["todo_confirmed"] } }), snapshot.goal_id); assert.ok(deliveryReviewMarkdown(selected, copy).includes(copy.contract.selectedWork)); assert.ok(deliveryReviewMarkdown(parseDeliveryReview(withContract(contract), snapshot.goal_id), copy).includes(copy.contract.allWork)); + const goalOnly = parseDeliveryReview(withContract({ ...contract, + scope: { kind: "goal" }, tasks: [], held_todo_ids: [] }), snapshot.goal_id); + assert.ok(deliveryReviewMarkdown(goalOnly, copy).includes(copy.contract.goalOnly)); const empty = parseDeliveryReview(withContract({ ...contract, criteria: [], tasks: [] }), snapshot.goal_id); assert.ok(deliveryReviewMarkdown(empty, copy).includes(copy.contract.noTasks)); assert.ok(deliveryReviewMarkdown(empty, copy).includes(copy.contract.noCriteria)); diff --git a/apps/presentation/dashboard/smoke/research-analysis-read-smoke.mjs b/apps/presentation/dashboard/smoke/research-analysis-read-smoke.mjs index 66e9854990..edc67d2be8 100644 --- a/apps/presentation/dashboard/smoke/research-analysis-read-smoke.mjs +++ b/apps/presentation/dashboard/smoke/research-analysis-read-smoke.mjs @@ -5,8 +5,10 @@ import {mkdtemp, mkdir, readFile, writeFile, rm} from "node:fs/promises"; import {tmpdir} from "node:os"; import {resolve} from "node:path"; import {createInterface} from "node:readline"; +import {createElement} from "react"; +import {renderToStaticMarkup} from "react-dom/server"; import {resolveTestPython} from "../../../../scripts/test-python.mjs"; -import {readAnalysisSnapshot} from "../src/features/personal-workspace/goal-research-analysis.tsx"; +import {readAnalysisSnapshot, ResearchAnalysisPanel} from "../src/features/personal-workspace/goal-research-analysis.tsx"; // A language-specific cache miss must not hide the same registered pack's // older, unspecified-language result or turn a read into model execution. @@ -86,6 +88,25 @@ try { failOriginal = false; assert.deepEqual((await read()).originalPack, original, "The ordinary read retries recovery without execution"); + // A failed/in-flight observation is unknown; only a successful empty read + // supports the absence message. Keep the existing read retry as recovery. + for (const zh of [true, false]) { + const empty = {...pack, availability: "available", selection: {exhaustive: false}, episode_count: 0}; + const controller = {zh, pack: empty, requestPack: empty, location: {open: true}, panel: {current: null}, + readOnly: true, loading: false, snapshot: {catalog: {}}, read: async () => {}, close: () => {}}; + const noSaved = zh ? "此来源尚无已保存的分析。" : "This source has no saved analysis yet."; + const render = state => renderToStaticMarkup(createElement(ResearchAnalysisPanel, {analysis: {...controller, ...state}})); + assert.ok(render({}).includes(noSaved), "A successful empty source retains its ordinary absence state"); + for (const state of [{loading: true}, {readError: "Source unavailable"}, {snapshot: {catalog: {}, originalReadError: "Original unavailable"}}]) { + const html = render(state); + assert.ok(!html.includes(noSaved), "An incomplete source read must not claim that no saved analysis exists"); + if (!state.loading) { + assert.ok(html.includes('role="alert"')); + assert.ok(html.includes(zh ? 'aria-label="重试读取"' : 'aria-label="Retry reading"')); + } + } + } + for (const options of [{current: () => false}, {signal: AbortSignal.abort()}]) { reset("zh"); value = await read(true, undefined, options.signal, options.current); diff --git a/apps/presentation/dashboard/src/data/delivery-review.ts b/apps/presentation/dashboard/src/data/delivery-review.ts index ad2b7a2a92..4986e2f37a 100644 --- a/apps/presentation/dashboard/src/data/delivery-review.ts +++ b/apps/presentation/dashboard/src/data/delivery-review.ts @@ -138,7 +138,7 @@ export function reviewNodeColumn(node: ReviewNode) { } type ConfiguredContract = GoalAcceptanceChecks; -type ContractExportLabels = Record<"title" | "boundary" | "scope" | "selectedWork" | "allWork" | "source" | "revision" | "digest" | "objective" | "criteria" +type ContractExportLabels = Record<"title" | "boundary" | "scope" | "goalOnly" | "selectedWork" | "allWork" | "source" | "revision" | "digest" | "objective" | "criteria" | "nonGoals" | "tasks" | "verification" | "unknown" | "noTasks" | "noCriteria" | "notApplicable" | "heldTasks" | "receipt" | "receiptNote" | "operation" | "verificationScope" | "allCriteria" | "passed" | "failed" | "exitCode" | "oracleChecker" | "oracleSourceDigest" | "oracleCheckedAt" | "oracleInputVersions" | "oracleOutputVersions", string> & { @@ -236,7 +236,7 @@ export function deliveryReviewMarkdown(snapshot: DeliveryReviewSnapshot, labels: if (hasConfiguredGoalChecks(contract)) { const copy = labels.contract; rows.push("", `## ${copy.title}`, "", copy.boundary, - `${copy.scope}: ${contract.scope?.kind === "selected_work" ? copy.selectedWork : copy.allWork}`, + `${copy.scope}: ${contract.scope?.kind === "goal" ? copy.goalOnly : contract.scope?.kind === "selected_work" ? copy.selectedWork : copy.allWork}`, `${copy.source}: ${line(snapshot.goal_id)}`, `${copy.revision}: ${contract.revision}`, `${copy.digest}: ${line(contract.digest)}`, "", `### ${copy.objective}`, line(contract.objective || copy.unknown), "", `### ${copy.criteria}`); if (contract.non_goals.length) rows.push(`${copy.nonGoals}: ${line(contract.non_goals.join("; "))}`); @@ -246,8 +246,8 @@ export function deliveryReviewMarkdown(snapshot: DeliveryReviewSnapshot, labels: if (criterion.oracle) rows.push(` ${copy.oracleChecker}: ${line(criterion.oracle.source_id)} · ${copy.oracleState[criterion.oracle.state]}`, ` ${copy.oracleSourceDigest}: ${line(criterion.oracle.source_digest)}`); } - rows.push("", `### ${copy.tasks}`); - if (!contract.tasks.length) rows.push(copy.noTasks); + if (contract.tasks.length || contract.scope?.kind !== "goal") rows.push("", `### ${copy.tasks}`); + if (!contract.tasks.length && contract.scope?.kind !== "goal") rows.push(copy.noTasks); for (const task of contract.tasks) { rows.push(`- ${line(task.todo_id)}: ${copy.taskState[task.state]}`, ` ${copy.criteria}: ${line(task.criterion_ids.join(", ") || copy.unknown)}`); diff --git a/apps/presentation/dashboard/src/data/fixtures/edgebench-ad-20261023-history.json b/apps/presentation/dashboard/src/data/fixtures/edgebench-ad-20261023-history.json index e411881ddd..7c2117859b 100644 --- a/apps/presentation/dashboard/src/data/fixtures/edgebench-ad-20261023-history.json +++ b/apps/presentation/dashboard/src/data/fixtures/edgebench-ad-20261023-history.json @@ -22,6 +22,12 @@ "Native and local measurement scopes remain distinct. Cancelled or invalid runs do not qualify a scientific comparison." ], "redactions": [], + "trajectory_archive": { + "url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/resolve/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/ad_placement_optimization.zip", + "sha256": "45ce26e44a59587b5a086d3aabde9bba9899b184abd6a21029f75c8b6695a44b", + "manifest_url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/blob/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/manifest.json", + "redactions_url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/blob/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/redactions.json" + }, "boundary": "Display-state events only. No authority or credential store, raw session transcript, hidden evaluator, workspace or model weights are included." }, "source_counts": { diff --git a/apps/presentation/dashboard/src/data/fixtures/edgebench-grid-context-on-20261103-history.json b/apps/presentation/dashboard/src/data/fixtures/edgebench-grid-context-on-20261103-history.json index dc64720394..93b4599ac6 100644 --- a/apps/presentation/dashboard/src/data/fixtures/edgebench-grid-context-on-20261103-history.json +++ b/apps/presentation/dashboard/src/data/fixtures/edgebench-grid-context-on-20261103-history.json @@ -21,6 +21,12 @@ "These runs include operational interventions and are not a qualified causal comparison. Local and native measurements retain separate scopes." ], "redactions": [], + "trajectory_archive": { + "url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/resolve/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/grid_turing_robot.zip", + "sha256": "ea147c9ae7173e3f1ce9ca6e0bbda5e0103e2be035b8e6d0658dd35a2d282c8d", + "manifest_url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/blob/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/manifest.json", + "redactions_url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/blob/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/redactions.json" + }, "boundary": "Display-state events only. No execution/authority store, credentials, raw session transcript, hidden evaluator, workspace or model weights are included." }, "source_counts": { diff --git a/apps/presentation/dashboard/src/data/fixtures/edgebench-schema-20261025-history.json b/apps/presentation/dashboard/src/data/fixtures/edgebench-schema-20261025-history.json index c4b3f81750..060a2356aa 100644 --- a/apps/presentation/dashboard/src/data/fixtures/edgebench-schema-20261025-history.json +++ b/apps/presentation/dashboard/src/data/fixtures/edgebench-schema-20261025-history.json @@ -22,6 +22,12 @@ "Native and local measurement scopes remain distinct. Cancelled or invalid runs do not qualify a scientific comparison." ], "redactions": [], + "trajectory_archive": { + "url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/resolve/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/schemathesis_config_modernization.zip", + "sha256": "e892d3b9569d84c7fff8ce80c2a0ae9f9a801d5f745eb980bfc918835327b2ea", + "manifest_url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/blob/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/manifest.json", + "redactions_url": "https://huggingface.co/datasets/huangrt01/loopx-edgebench-research-checkpoints-20261015/blob/a97e88f951deb6827d7051a59927860e9e4c4476/20261107-real-benchmark-trajectories/redactions.json" + }, "boundary": "Display-state events only. No authority or credential store, raw session transcript, hidden evaluator, workspace or model weights are included." }, "source_counts": { diff --git a/apps/presentation/dashboard/src/data/goal-acceptance-actions.ts b/apps/presentation/dashboard/src/data/goal-acceptance-actions.ts index 00ebe4c742..c956403af4 100644 --- a/apps/presentation/dashboard/src/data/goal-acceptance-actions.ts +++ b/apps/presentation/dashboard/src/data/goal-acceptance-actions.ts @@ -17,7 +17,7 @@ export async function acceptanceRequest(goalId: string, operation?: Record void operate("clear-checks")}>{zh ? "移除检查配置" : "Remove check configuration"}
{copy.source}
{goalId}
- {checksConfigured ? <>
{copy.scope}
{contract.scope?.kind === "selected_work" ? copy.selectedWork : copy.allWork}
+ {checksConfigured ? <>
{copy.scope}
{contract.scope?.kind === "goal" ? copy.goalOnly : contract.scope?.kind === "selected_work" ? copy.selectedWork : copy.allWork}
{copy.revision}
{contract.revision}
{copy.digest}
{contract.digest}
: null}
- {checksConfigured ? <>

{contract.non_goals.join(" · ")}

{copy.tasks}

+ {checksConfigured ? <>

{contract.non_goals.join(" · ")}

{contract.tasks.length ?

{copy.tasks}

: null}