Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
69813c8
chore(harness): activate the 0.0.6 internals lane run with executed b…
rickylabs Aug 12, 2026
96a8c2f
chore(harness): commit the quality-rail plan and the run's first re-p…
rickylabs Aug 12, 2026
9c3cdfe
chore(harness): record the attached-slice timeout hazard and correct …
rickylabs Aug 12, 2026
3289ad2
chore(harness): record that the ready-merge label is not a workflow t…
rickylabs Aug 12, 2026
ff100fd
chore(harness): record the first merge of the internals lane
rickylabs Aug 12, 2026
1815193
chore(harness): record the rail FAIL_PLAN and the unverified claim it…
rickylabs Aug 12, 2026
c800680
chore(harness): land the rail PLAN-EVAL verdict (FAIL_PLAN, 6 blocking)
rickylabs Aug 12, 2026
112c167
chore(harness): revise the quality rail against the FAIL_PLAN verdict
rickylabs Aug 12, 2026
585df07
chore(harness): record the rail replan and refresh the resumable state
rickylabs Aug 12, 2026
64c091c
chore(harness): record cycle-2 FAIL_PLAN and stop the rail for owner …
rickylabs Aug 12, 2026
83adb22
chore(harness): consolidate the rail plan into revision 3 and resolve…
rickylabs Aug 12, 2026
13e020a
chore(harness): adopt the label-triggered evaluation policy for the r…
rickylabs Aug 12, 2026
c1ebfa5
chore(harness): refine R-11 after #1524 landed and made the labeled c…
rickylabs Aug 12, 2026
25e5758
chore(harness): record cycle-3 FAIL_PLAN and escalate #1378 as a scop…
rickylabs Aug 12, 2026
2a9c674
chore(harness): rescope the rail to #1549 and fix the three carried d…
rickylabs Aug 12, 2026
ce011b5
chore(harness): record the rescope decision and its per-criterion rea…
rickylabs Aug 12, 2026
7675842
chore(harness): record cycle-4 dispatch through the automated phase-e…
rickylabs Aug 12, 2026
69ef5f1
chore(harness): reconcile companion prose to the rescoped surface (cy…
rickylabs Aug 12, 2026
4215f81
chore(harness): PLAN-EVAL PASS at cycle 5 -- Plan-Gate cleared
rickylabs Aug 12, 2026
6544130
chore(harness): refine D-10's remedy -- re-run, do not push, once a v…
rickylabs Aug 12, 2026
f794038
chore(harness): add the asset-barrel gate that PR-E's CI found missing
rickylabs Aug 12, 2026
bdcc6df
chore(harness): re-evaluate PR-E rather than merge on a superseded ve…
rickylabs Aug 12, 2026
0b0835b
chore(harness): record gh-watch reporting a superseded verdict as ter…
rickylabs Aug 12, 2026
7d91066
chore(harness): reconcile the watcher findings against executed state
rickylabs Aug 12, 2026
d8a04ca
chore(harness): record that the two IMPL-EVAL verdicts disagree and t…
rickylabs Aug 12, 2026
d737aa1
chore(harness): correct an overstated gate citation -- quality:gate m…
rickylabs Aug 12, 2026
d44079c
chore(harness): correct D-28 with the probe -- pathspec plus a silent…
rickylabs Aug 12, 2026
08aa156
chore(harness): record a third quality:scan failure mode and my own m…
rickylabs Aug 12, 2026
561ffac
chore(harness): record PR-E merged and main's quality gate green
rickylabs Aug 12, 2026
8b8362f
chore(harness): rebind the two Fable review lanes to their documented…
rickylabs Aug 12, 2026
72cef4e
chore(harness): record that #1566's 404 was a symptom of bookkeeping …
rickylabs Aug 12, 2026
175d167
chore(harness): record that dispatch depends on the transition via ev…
rickylabs Aug 12, 2026
763c8f1
chore(harness): record the hard Fable prohibition in the run worklog
rickylabs Aug 12, 2026
c21b568
chore(harness): record that Canary.3 cut ownership is the runtime lane's
rickylabs Aug 12, 2026
2cac13d
chore(harness): record that resume is prohibited too and this lane ha…
rickylabs Aug 12, 2026
1961e77
chore(harness): record #1566 merged and the follow-up now unblocked
rickylabs Aug 12, 2026
ba80d2a
chore(harness): record #1580 as the owner of #1570's fresh-ui red, an…
rickylabs Aug 12, 2026
d9c306c
chore(harness): record the control rule and the merge-forward safety …
rickylabs Aug 12, 2026
ffb5879
chore(harness): record #1403 closed and arch:check gating 36 units
rickylabs Aug 12, 2026
ceb47f9
chore(harness): record the shallow-clone trap and withdraw the false …
rickylabs Aug 12, 2026
814aeff
chore(harness): record the shallow-clone trap and gh-watch's third st…
rickylabs Aug 12, 2026
83015d0
chore(harness): record #1380 closed and dispatch the lane's last issue
rickylabs Aug 12, 2026
551fb8c
chore(harness): record the explicit scope authorization on PR #1596
rickylabs Aug 12, 2026
5b5f91b
chore(harness): record that the authorization steer never arrived
rickylabs Aug 12, 2026
2dc604a
docs(harness): record D-42 watch false-green and draft the lane retro…
rickylabs Aug 12, 2026
c4367a4
docs(harness): record the consumer-bundle closure gap and brief its fix
rickylabs Aug 12, 2026
86c23f0
docs(harness): measure the bundle closure before briefing its guard
rickylabs Aug 12, 2026
915ea61
docs(harness): record gh-watch matching the orchestrator's own review…
rickylabs Aug 12, 2026
524d0bd
docs(harness): correct the verdict-detection rule and map the correct…
rickylabs Aug 12, 2026
7562609
docs(harness): map the correction brief to verdict findings F1/F2
rickylabs Aug 12, 2026
3c22aaa
docs(harness): record that re-syncing a leaf orphans the hashes its e…
rickylabs Aug 12, 2026
85a2358
docs(harness): record the flake-consumed evaluation and my own poller…
rickylabs Aug 12, 2026
b725f24
docs(harness): record the transport flake window and its recovery rules
rickylabs Aug 12, 2026
66e2f88
docs(harness): close the 0.0.6 internals lane -- merge 6, assumptions…
rickylabs Aug 12, 2026
1f7546b
docs(harness): dispatch PR-G for #1612 with the sweep already measured
rickylabs Aug 12, 2026
e7ab15b
docs(harness): record PR-G merge and the duplicate-evidence failure mode
rickylabs Aug 12, 2026
bddad90
docs(harness): finalise the 0.0.6 internals retrospective
rickylabs Aug 12, 2026
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
59 changes: 59 additions & 0 deletions .github/scripts/phase-eval-status.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/** Prefix reserved for the single lifecycle status label. */
export const STATUS_PREFIX = 'status:';

/** Terminal status entered before dispatching IMPL-EVAL. */
export const IMPL_EVAL_STATUS = 'status:impl-eval';

/** GitHub's exact response message when a label is absent from an issue. */
export const MISSING_LABEL_MESSAGE = 'Label does not exist';

/**
* Decide the idempotent status-label transition from a live issue-label set.
*
* @param {readonly string[]} liveLabels
* @returns {{ remove: string[], add: string[] }}
*/
export function decideImplEvalStatusTransition(liveLabels) {
return {
remove: liveLabels.filter((label) => label.startsWith(STATUS_PREFIX)),
add: [IMPL_EVAL_STATUS],
};
}

/**
* Apply the IMPL-EVAL transition through injected GitHub label operations.
*
* @param {{
* listLabelsOnIssue: () => Promise<string[]>,
* removeLabel: (label: string) => Promise<void>,
* addLabels: (labels: string[]) => Promise<void>,
* }} operations
*/
export async function applyImplEvalStatusTransition(operations) {
const liveLabels = await operations.listLabelsOnIssue();
const decision = decideImplEvalStatusTransition(liveLabels);

for (const label of decision.remove) {
try {
await operations.removeLabel(label);
} catch (error) {
if (!isMissingLabelError(error)) throw error;
}
}

await operations.addLabels(decision.add);
}

/** @param {unknown} error */
function isMissingLabelError(error) {
if (!isRecord(error) || error.status !== 404) return false;
const response = error.response;
if (!isRecord(response)) return false;
const data = response.data;
return isRecord(data) && data.message === MISSING_LABEL_MESSAGE;
}

/** @param {unknown} value */
function isRecord(value) {
return typeof value === 'object' && value !== null;
}
166 changes: 166 additions & 0 deletions .github/scripts/phase-eval-status.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { assertEquals, assertRejects, assertStringIncludes } from '@std/assert';
import {
applyImplEvalStatusTransition,
decideImplEvalStatusTransition,
IMPL_EVAL_STATUS,
MISSING_LABEL_MESSAGE,
} from './phase-eval-status.mjs';

interface IssueLabelOperations {
listLabelsOnIssue(): Promise<string[]>;
removeLabel(label: string): Promise<void>;
addLabels(labels: string[]): Promise<void>;
}

function workflowStep(source: string, name: string): string {
const lines = source.split('\n');
const start = lines.indexOf(` - name: ${name}`);
if (start < 0) throw new Error(`Missing workflow step: ${name}`);
let end = lines.length;
for (let index = start + 1; index < lines.length; index += 1) {
if (lines[index].startsWith(' - name: ')) {
end = index;
break;
}
}
return lines.slice(start, end).join('\n');
}

function operations(
labels: string[],
removeError?: (label: string) => unknown,
) {
const removed: string[] = [];
const added: string[][] = [];
const client: IssueLabelOperations = {
listLabelsOnIssue: () => Promise.resolve(labels),
removeLabel: (label: string) => {
const error = removeError?.(label);
if (error !== undefined) return Promise.reject(error);
removed.push(label);
return Promise.resolve();
},
addLabels: (next: string[]) => {
added.push(next);
return Promise.resolve();
},
};
return { client, removed, added };
}

Deno.test('race regression: a concurrently removed status label does not fail cleanup', async () => {
const { client, removed, added } = operations(
['status:impl', 'area:tooling'],
() => ({ status: 404, response: { data: { message: 'Label does not exist' } } }),
);

await applyImplEvalStatusTransition(client);

assertEquals(removed, []);
assertEquals(added, [['status:impl-eval']]);
});

Deno.test('narrow tolerance: permission failures still fail cleanup', async () => {
const { client } = operations(
['status:impl'],
() => ({
status: 403,
response: { data: { message: 'Resource not accessible by integration' } },
}),
);

await assertRejects(() => applyImplEvalStatusTransition(client));
});

Deno.test('narrow tolerance: an unrelated 404 still fails cleanup', async () => {
const { client } = operations(
['status:impl'],
() => ({ status: 404, response: { data: { message: 'Not Found' } } }),
);

await assertRejects(() => applyImplEvalStatusTransition(client));
});

Deno.test('terminal decision contains exactly one status label', () => {
const decision = decideImplEvalStatusTransition([
'type:fix',
'status:impl',
'status:plan-eval',
'area:tooling',
]);

assertEquals(decision, {
remove: ['status:impl', 'status:plan-eval'],
add: ['status:impl-eval'],
});
const terminal = [
'type:fix',
'area:tooling',
...decision.add,
];
assertEquals(terminal.filter((label) => label.startsWith('status:')), ['status:impl-eval']);
});

Deno.test('generation deduplication remains before trigger creation', async () => {
const workflow = await Deno.readTextFile('.github/workflows/openhands-phase-eval.yml');
const marker =
'const marker = `<!-- openhands-phase-eval generation=${generationEvent.id} phase=${phase} head=${pr.head.sha} -->`;';
const claim = "String(comment.body ?? '').includes(marker)";
const earlyReturn = 'if (existing) {';
const create = 'github.rest.issues.createComment({';

assertStringIncludes(workflow, marker);
assertStringIncludes(workflow, claim);
assertStringIncludes(workflow, earlyReturn);
assertStringIncludes(workflow, create);
assertEquals(workflow.indexOf(marker) < workflow.indexOf(claim), true);
assertEquals(workflow.indexOf(claim) < workflow.indexOf(earlyReturn), true);
assertEquals(workflow.indexOf(earlyReturn) < workflow.indexOf(create), true);
});

Deno.test('status bookkeeping failures are attributed and dispatch remains conditionally eligible', async () => {
const workflow = await Deno.readTextFile('.github/workflows/openhands-phase-eval.yml');
const transition = workflowStep(workflow, 'Enter IMPL-EVAL status on ready transition');
const diagnostic = workflowStep(
workflow,
'Record attributed IMPL-EVAL status-transition failure',
);
const dispatch = workflowStep(workflow, 'Resolve and dispatch exactly one evaluator');

assertStringIncludes(transition, 'id: enter_impl_eval_status');
assertStringIncludes(transition, 'continue-on-error: true');
assertStringIncludes(transition, 'core.setOutput(');
assertStringIncludes(transition, "'failure_reason'");
assertStringIncludes(diagnostic, "steps.enter_impl_eval_status.outcome == 'failure'");
assertStringIncludes(diagnostic, 'evaluator dispatch attempt continues');
assertStringIncludes(diagnostic, 'REQUEST_ACTOR: ${{ github.actor }}');
assertStringIncludes(diagnostic, 'FAILURE_REASON:');
assertStringIncludes(dispatch, '!cancelled()');
assertStringIncludes(
dispatch,
"steps.require_chainable_trigger_token.outcome == 'success'",
);
assertEquals(dispatch.includes('enter_impl_eval_status.outcome'), false);
});

Deno.test('inline cleanup transcription matches helper contract literals', async () => {
const workflow = await Deno.readTextFile('.github/workflows/openhands-phase-eval.yml');
const transition = workflowStep(workflow, 'Enter IMPL-EVAL status on ready transition');

assertEquals(workflow.includes('Check out trusted phase-eval scripts'), false);
assertEquals(transition.includes('await import('), false);
assertStringIncludes(transition, 'github.rest.issues.listLabelsOnIssue');
assertStringIncludes(
transition,
`const IMPL_EVAL_STATUS = '${IMPL_EVAL_STATUS}';`,
);
assertStringIncludes(
transition,
`const MISSING_LABEL_MESSAGE = '${MISSING_LABEL_MESSAGE}';`,
);
assertStringIncludes(
transition,
'error?.response?.data?.message === MISSING_LABEL_MESSAGE',
);
assertStringIncludes(transition, 'labels: [IMPL_EVAL_STATUS]');
});
Loading