From f24099b14b7b7f143a3a088a46a5b6ca35f7b907 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 19:30:48 +0900 Subject: [PATCH 01/12] chore(ci): retire completed PR1714 source-fix workflow --- ...source-fix-pr1714-no-model-job-timeout.yml | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 .github/workflows/source-fix-pr1714-no-model-job-timeout.yml diff --git a/.github/workflows/source-fix-pr1714-no-model-job-timeout.yml b/.github/workflows/source-fix-pr1714-no-model-job-timeout.yml deleted file mode 100644 index ad3accb2fa..0000000000 --- a/.github/workflows/source-fix-pr1714-no-model-job-timeout.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Source Fix PR 1714 No Model Job Timeout - -on: - push: - branches: - - fix/autofix-job-timeout - paths: - - scripts/ci/source_fix_pr1714_no_model_job_timeout.py - - .github/workflows/source-fix-pr1714-no-model-job-timeout.yml - -concurrency: - group: source-fix-pr1714-${{ github.repository }}-${{ github.ref_name }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - repair: - runs-on: ubuntu-slim - steps: - - name: Checkout exact writer head - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - ref: ${{ github.sha }} - fetch-depth: 0 - persist-credentials: false - - - name: Revalidate exact remote head - shell: bash - run: | - set -euo pipefail - remote_head="$(git ls-remote origin refs/heads/fix/autofix-job-timeout | cut -f1)" - test -n "$remote_head" - test "$remote_head" = "$GITHUB_SHA" - - - name: Set up Python 3.14 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: "3.14" - cache: pip - - - name: Install exact test toolchain - shell: bash - run: | - set -euo pipefail - python -m pip install --require-hashes -r requirements-opencode-review-ci-hashes.txt - - - name: Apply causal-owner repair - shell: bash - run: | - set -euo pipefail - python scripts/ci/source_fix_pr1714_no_model_job_timeout.py - python -m py_compile scripts/ci/source_fix_pr1714_no_model_job_timeout.py - git diff --check - - - name: Verify autofix timeout and writer-security contract - shell: bash - run: | - set -euo pipefail - python -m pytest \ - tests/test_pr_review_autofix_writer_security_contract.py \ - tests/test_pr_review_fix_scheduler.py \ - tests/test_required_workflow_queue_contract.py \ - -q - python -m compileall -q scripts tests - git diff --check - - - name: Retire one-shot artifacts and verify scope - shell: bash - run: | - set -euo pipefail - rm scripts/ci/source_fix_pr1714_no_model_job_timeout.py - rm .github/workflows/source-fix-pr1714-no-model-job-timeout.yml - allowed='^(.github/workflows/pr-review-autofix.yml|tests/test_pr_review_autofix_writer_security_contract.py|CHANGELOG.md|docs/product-technical-gap-baseline.md|scripts/ci/source_fix_pr1714_no_model_job_timeout.py|.github/workflows/source-fix-pr1714-no-model-job-timeout.yml)$' - bad="$(git status --short | sed -E 's/^.. //' | grep -Ev "$allowed" || true)" - test -z "$bad" - remote_head="$(git ls-remote origin refs/heads/fix/autofix-job-timeout | cut -f1)" - test "$remote_head" = "$GITHUB_SHA" - - - name: Publish normal non-force repair commit - env: - PRIMARY_PUSH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} - FALLBACK_PUSH_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN }} - shell: bash - run: | - set -euo pipefail - workflow_push_token="${PRIMARY_PUSH_TOKEN:-${FALLBACK_PUSH_TOKEN:-}}" - if [ -z "$workflow_push_token" ]; then - echo "::error::No workflow-starting mutation credential is configured; refusing github.token publication." - exit 1 - fi - remote_head="$(git ls-remote origin refs/heads/fix/autofix-job-timeout | cut -f1)" - test "$remote_head" = "$GITHUB_SHA" - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add -A - git diff --cached --check - git commit -m "fix(autofix): remove model wall-clock termination" - git remote set-url origin "https://x-access-token:${workflow_push_token}@github.com/${GITHUB_REPOSITORY}.git" - git push origin HEAD:fix/autofix-job-timeout From 9683f298093ab5993600c9254670bc547cdd2656 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 19:30:54 +0900 Subject: [PATCH 02/12] chore(ci): retire completed PR1714 source-fix materializer --- .../source_fix_pr1714_no_model_job_timeout.py | 151 ------------------ 1 file changed, 151 deletions(-) delete mode 100644 scripts/ci/source_fix_pr1714_no_model_job_timeout.py diff --git a/scripts/ci/source_fix_pr1714_no_model_job_timeout.py b/scripts/ci/source_fix_pr1714_no_model_job_timeout.py deleted file mode 100644 index 415cf176ae..0000000000 --- a/scripts/ci/source_fix_pr1714_no_model_job_timeout.py +++ /dev/null @@ -1,151 +0,0 @@ -"""One-shot repair for PR #1714's model-backed autofix no-heuristics contract.""" - -from __future__ import annotations - -from pathlib import Path - -WORKFLOW = Path(".github/workflows/pr-review-autofix.yml") -TEST = Path("tests/test_pr_review_autofix_writer_security_contract.py") -CHANGELOG = Path("CHANGELOG.md") -BASELINE = Path("docs/product-technical-gap-baseline.md") - - -def replace_once(text: str, old: str, new: str, label: str) -> str: - """Replace one literal block and fail closed if the exact head moved semantically.""" - count = text.count(old) - if count != 1: - raise SystemExit(f"PR1714 {label}: expected one literal block, found {count}") - return text.replace(old, new, 1) - - -def patch_workflow() -> None: - """Remove repository-authored model termination, compute, capability, and evidence heuristics.""" - text = WORKFLOW.read_text(encoding="utf-8") - timeout_old = ''' # Bound the job well short of GitHub's 360-minute platform default. Setup - # (checkout, OIDC token exchange, OpenCode CLI install, context collection) - # is API/IO-bound and normally finishes in a few minutes; the one - # `opencode run` call (12 agent steps, single fixed model, no - # multi-provider fallback pool unlike opencode-review-dispatch.yml's - # review job) is the dominant cost, followed by fast local validation - # and a single git commit/push. 25 minutes gives that single LLM run - # generous per-step room while still failing a hung invocation well - # before the platform cap. - timeout-minutes: 25 -''' - timeout_new = ''' # This job is model-backed through contextual-orchestrator/orchestrator/free - # and therefore has no repository-owned wall-clock timeout. Provider end, - # explicit cancellation, and the workflow's exact live-head/state guards - # are authoritative; elapsed time alone must not terminate reasoning, - # streaming, or tool work. Queue pressure is handled by the scheduler's - # stale-head dedupe/cancellation rather than by killing current-head work. -''' - text = replace_once(text, timeout_old, timeout_new, "autofix timeout block") - - text = replace_once( - text, - ' "reasoningEffort": "high",\n', - "", - "repository-authored reasoning effort", - ) - text = replace_once( - text, - ' "steps": 12,\n', - "", - "repository-authored agent step budget", - ) - capability_old = ''' "name": "Orchestrator Free (ZDR-first zero-cost pool)", - "tool_call": true, - "reasoning": true, - "limit": { - "context": 200000, - "output": 32768 - } -''' - capability_new = ''' "name": "Orchestrator Free (ZDR-first zero-cost pool)" -''' - text = replace_once( - text, - capability_old, - capability_new, - "leaf model capability and context/output declarations", - ) - text = replace_once( - text, - ' $(sed -n \'1,260p\' "$RUNNER_TEMP/pr-review-autofix-context.md")\n', - ' $(cat "$RUNNER_TEMP/pr-review-autofix-context.md")\n', - "review-context line quota", - ) - WORKFLOW.write_text(text, encoding="utf-8") - - -def patch_test() -> None: - """Replace the timeout-positive regression with fail-closed authority contracts.""" - text = TEST.read_text(encoding="utf-8") - marker = "def test_autofix_job_has_a_bounded_runtime() -> None:\n" - start = text.find(marker) - if start < 0 or text.find(marker, start + 1) >= 0: - raise SystemExit("PR1714 stale timeout test marker moved or duplicated") - replacement = '''def test_autofix_model_job_delegates_termination_and_compute_to_orchestrator() -> None: - """Leaf OpenCode config must not invent model-time or test-time-compute authority.""" - workflow = _workflow_text() - job = workflow.split(" autofix:\\n", maxsplit=1)[1] - job_header = job.split(" steps:\\n", maxsplit=1)[0] - - assert "timeout-minutes:" not in job_header - assert '"model": "contextual-orchestrator/orchestrator/free"' in workflow - assert '"reasoningEffort":' not in workflow - assert '"steps": 12' not in workflow - assert '"tool_call": true' not in workflow - assert '"reasoning": true' not in workflow - assert '"limit": {' not in workflow - assert "no repository-owned wall-clock timeout" in job_header - assert "cancel-in-progress: false" in workflow - - -def test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota() -> None: - """Exact review evidence must reach the model without a repository-authored line cutoff.""" - workflow = _workflow_text() - - assert "sed -n '1,260p'" not in workflow - assert '$(cat "$RUNNER_TEMP/pr-review-autofix-context.md")' in workflow -''' - TEST.write_text(text[:start] + replacement, encoding="utf-8") - - -def append_traceability() -> None: - """Document the model-authority and complete-evidence boundary.""" - changelog = CHANGELOG.read_text(encoding="utf-8") - note = ( - "\n- PR #1714: reject repository-authored OpenCode autofix wall-clock, reasoning-effort, " - "agent-step, capability/context/output, and fixed review-line allocation. The leaf requests " - "only `orchestrator/free`; contextual-orchestrator owns verified capability/routing/test-time " - "compute and the full collected review evidence is passed without a hand-selected line quota.\n" - ) - if "PR #1714: reject repository-authored OpenCode autofix wall-clock" not in changelog: - CHANGELOG.write_text(changelog + note, encoding="utf-8") - - baseline = BASELINE.read_text(encoding="utf-8") - section = ''' - -### OpenCode autofix orchestration authority — PR #1714 - -- **Root cause:** the leaf workflow proposed `timeout-minutes: 25` and also carried repository-authored `reasoningEffort: high`, a 12-step agent budget, asserted tool/reasoning capabilities, fixed context/output limits, and a 260-line review-context cutoff. None of those leaf allocations had executable research/model evidence establishing them as decision authority. -- **Owner boundary:** `.github` requests exactly `contextual-orchestrator/orchestrator/free` through the gateway token. contextual-orchestrator owns provider discovery, verified capability admission, routing, and research-backed test-time compute; the leaf does not invent provider/model capability or compute limits. -- **Evidence contract:** the complete review context produced by the governed collector is passed to the model. If contextual-orchestrator cannot admit/serve the request under its verified capability/privacy/free-pool contracts, the path fails closed rather than silently sampling evidence or selecting a paid/provider fallback. -- **Termination contract:** provider completion, explicit cancellation, and exact live-head/state guards end model work. Scheduler stale-head dedupe/cancellation handles queue waste without terminating the sole current-head model run by elapsed time. -- **Regression:** `test_autofix_model_job_delegates_termination_and_compute_to_orchestrator` and `test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota` forbid reintroduction of those leaf heuristics while preserving the exact `orchestrator/free` contract. -- **Status:** Proposed until the one-shot source repair self-removes and fresh exact-head Checks are GREEN. -''' - if "### OpenCode autofix orchestration authority — PR #1714" not in baseline: - BASELINE.write_text(baseline + section, encoding="utf-8") - - -def main() -> None: - """Apply production, regression, and traceability changes.""" - patch_workflow() - patch_test() - append_traceability() - - -if __name__ == "__main__": - main() From e4c9b418b5d3a754c4d5cc0cb8a69cfa50b0b489 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 19:31:00 +0900 Subject: [PATCH 03/12] chore(ci): retire completed PR1715 source-fix workflow --- ...source-fix-pr1715-no-model-job-timeout.yml | 105 ------------------ 1 file changed, 105 deletions(-) delete mode 100644 .github/workflows/source-fix-pr1715-no-model-job-timeout.yml diff --git a/.github/workflows/source-fix-pr1715-no-model-job-timeout.yml b/.github/workflows/source-fix-pr1715-no-model-job-timeout.yml deleted file mode 100644 index 0d733b2b72..0000000000 --- a/.github/workflows/source-fix-pr1715-no-model-job-timeout.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: Source Fix PR 1715 No Model Job Timeout - -on: - push: - branches: - - fix/noema-review-job-timeout-minutes - paths: - - scripts/ci/source_fix_pr1715_no_model_job_timeout.py - - .github/workflows/source-fix-pr1715-no-model-job-timeout.yml - -concurrency: - group: source-fix-pr1715-${{ github.repository }}-${{ github.ref_name }} - cancel-in-progress: true - -permissions: - contents: read - -jobs: - repair: - runs-on: ubuntu-slim - steps: - - name: Checkout exact writer head - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - ref: ${{ github.sha }} - fetch-depth: 0 - persist-credentials: false - - - name: Revalidate exact remote head - shell: bash - run: | - set -euo pipefail - remote_head="$(git ls-remote origin refs/heads/fix/noema-review-job-timeout-minutes | cut -f1)" - test -n "$remote_head" - test "$remote_head" = "$GITHUB_SHA" - - - name: Set up Python 3.14 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: "3.14" - cache: pip - - - name: Install exact test toolchain - shell: bash - run: | - set -euo pipefail - python -m pip install --require-hashes -r requirements-opencode-review-ci-hashes.txt - - - name: Apply causal-owner repair - shell: bash - run: | - set -euo pipefail - python scripts/ci/source_fix_pr1715_no_model_job_timeout.py - python -m py_compile scripts/ci/source_fix_pr1715_no_model_job_timeout.py - git diff --check - - - name: Verify Noema timeout authority contract - shell: bash - run: | - set -euo pipefail - python -m pytest \ - tests/test_noema_orchestrator_workflow_contract.py \ - tests/test_required_workflow_queue_contract.py \ - tests/test_noema_review_gate.py \ - tests/test_noema_review_handoff.py \ - tests/test_noema_two_phase_handoff.py \ - -q - python -m compileall -q scripts tests .github/actions/noema-review - git diff --check - - - name: Retire one-shot repair artifacts and verify scope - shell: bash - run: | - set -euo pipefail - rm scripts/ci/source_fix_pr1715_no_model_job_timeout.py - rm .github/workflows/source-fix-pr1715-no-model-job-timeout.yml - allowed='^(.github/workflows/noema-review.yml|tests/test_noema_orchestrator_workflow_contract.py|CHANGELOG.md|docs/product-technical-gap-baseline.md|scripts/ci/source_fix_pr1715_no_model_job_timeout.py|.github/workflows/source-fix-pr1715-no-model-job-timeout.yml)$' - bad="$(git status --short | sed -E 's/^.. //' | grep -Ev "$allowed" || true)" - test -z "$bad" - test ! -e scripts/ci/source_fix_pr1715_no_model_job_timeout.py - test ! -e .github/workflows/source-fix-pr1715-no-model-job-timeout.yml - remote_head="$(git ls-remote origin refs/heads/fix/noema-review-job-timeout-minutes | cut -f1)" - test "$remote_head" = "$GITHUB_SHA" - - - name: Publish normal non-force repair commit - env: - PRIMARY_PUSH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} - FALLBACK_PUSH_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN }} - shell: bash - run: | - set -euo pipefail - workflow_push_token="${PRIMARY_PUSH_TOKEN:-${FALLBACK_PUSH_TOKEN:-}}" - if [ -z "$workflow_push_token" ]; then - echo "::error::No workflow-starting mutation credential is configured; refusing github.token publication." - exit 1 - fi - remote_head="$(git ls-remote origin refs/heads/fix/noema-review-job-timeout-minutes | cut -f1)" - test "$remote_head" = "$GITHUB_SHA" - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add -A - git diff --cached --check - git commit -m "fix(noema-review): remove model wall-clock termination" - git remote set-url origin "https://x-access-token:${workflow_push_token}@github.com/${GITHUB_REPOSITORY}.git" - git push origin HEAD:fix/noema-review-job-timeout-minutes From 42487f5ec6c4259e00d1b7ae4f61cd00b13d303d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 19:31:08 +0900 Subject: [PATCH 04/12] chore(ci): retire completed PR1715 source-fix materializer --- .../source_fix_pr1715_no_model_job_timeout.py | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 scripts/ci/source_fix_pr1715_no_model_job_timeout.py diff --git a/scripts/ci/source_fix_pr1715_no_model_job_timeout.py b/scripts/ci/source_fix_pr1715_no_model_job_timeout.py deleted file mode 100644 index 497d109678..0000000000 --- a/scripts/ci/source_fix_pr1715_no_model_job_timeout.py +++ /dev/null @@ -1,110 +0,0 @@ -"""One-shot exact-head repair for PR #1715's Noema model timeout contract.""" - -from __future__ import annotations - -import re -from pathlib import Path - -WORKFLOW = Path(".github/workflows/noema-review.yml") -TEST = Path("tests/test_noema_orchestrator_workflow_contract.py") -CHANGELOG = Path("CHANGELOG.md") -BASELINE = Path("docs/product-technical-gap-baseline.md") - - -def replace_once(text: str, old: str, new: str, label: str) -> str: - """Replace one literal block and fail closed when branch contents moved.""" - count = text.count(old) - if count != 1: - raise SystemExit(f"PR1715 {label}: expected one literal block, found {count}") - return text.replace(old, new, 1) - - -def patch_workflow() -> None: - """Keep bounded cleanup but remove elapsed-time authority from model work.""" - text = WORKFLOW.read_text(encoding="utf-8") - old = ''' # Bound this job well short of GitHub's 360-minute platform default. Its - # "Prepare Noema model verdict" step calls into two_phase.py's call_llm - # via the same contextual-orchestrator gateway whose unbounded wait was - # confirmed to stall runs for 7-20 hours in opencode-review.yml before - # PR #1707's fix -- and noema_review_gate.py's own comment says that - # step "remains governed by contextual-orchestrator rather than a fixed - # inference timeout", so nothing upstream of this job bounds it either. - # 210 minutes gives that step the same ~180-minute (3-hour) allowance - # PR #1707 set for its analogous model-wait deadline -- comfortably - # above this org's documented "accommodate over 2 hours per model" - # policy (docs/product-goal-directive.md #8) -- plus a 30-minute buffer - # for this job's other steps (tarball fetch, credential mint, the - # superseded-run cleanup sweep, visibility-lookup retries, sidecar - # provisioning, publication), while staying well under GitHub's default. - timeout-minutes: 210 -''' - new = ''' # Model-backed Noema intentionally has no job-level wall-clock timeout. - # contextual-orchestrator/orchestrator/free owns provider termination; - # GitHub admission must not stop reasoning, streaming, or tool work only - # because elapsed time crossed a repository-side deadline. Stale heads, - # closed/draft PRs, provider completion, and explicit cancellation remain - # authoritative termination signals. The non-model cleanup job above is - # independently bounded because it performs only GitHub API housekeeping. -''' - WORKFLOW.write_text( - replace_once(text, old, new, "model job timeout block"), encoding="utf-8" - ) - - -def patch_test() -> None: - """Replace the stale timeout-positive assertion with the owner contract.""" - text = TEST.read_text(encoding="utf-8") - marker = "def test_noema_review_job_has_a_bounded_runtime_above_the_two_hour_model_allowance() -> None:\n" - start = text.find(marker) - if start < 0 or text.find(marker, start + 1) >= 0: - raise SystemExit("PR1715 stale model-timeout test marker moved or duplicated") - replacement = '''def test_noema_review_model_job_has_no_elapsed_time_termination() -> None: - """Model-backed Noema delegates termination to orchestrator/provider authority.""" - workflow = workflow_text("noema-review.yml") - job = workflow.split(" noema-review:\\n", 1)[1] - - assert re.search(r"^ timeout-minutes:", job, flags=re.MULTILINE) is None - assert "contextual-orchestrator/orchestrator/free" in workflow - assert "Model-backed Noema intentionally has no job-level wall-clock timeout" in job - assert "timeout-minutes: 20" in workflow.split( - " cancel-closed-pr-runs:\\n", 1 - )[1].split("\\n noema-review:\\n", 1)[0] -''' - TEST.write_text(text[:start] + replacement, encoding="utf-8") - - -def append_traceability() -> None: - """Record why support housekeeping may be bounded while model work may not.""" - changelog_note = ( - "\n- PR #1715: keep the non-model Noema close-cleanup job bounded, but remove " - "the proposed 210-minute job timeout from model-backed `noema-review`; " - "`orchestrator/free`/provider completion, live PR/head state, or explicit " - "cancellation are the termination authorities rather than elapsed time.\n" - ) - changelog = CHANGELOG.read_text(encoding="utf-8") - if "PR #1715: keep the non-model Noema close-cleanup job bounded" not in changelog: - CHANGELOG.write_text(changelog + changelog_note, encoding="utf-8") - - baseline_note = ''' - -### Noema model-job timeout authority — PR #1715 - -- **Root cause:** a queue-operability repair proposed `timeout-minutes: 210` on the model-backed `noema-review` job, turning elapsed wall time into an admission/model termination authority. -- **Contract:** the lightweight closed-PR Actions cleanup remains bounded, while Noema model work has no repository-owned wall-clock cutoff. `orchestrator/free` and its upstream provider own normal model completion; live PR/head validation, provider end, or explicit cancellation remain authoritative stop conditions. -- **Regression:** `test_noema_review_model_job_has_no_elapsed_time_termination` rejects a job-level timeout on the model job while retaining the 20-minute bound on non-model cleanup. -- **Status:** Implemented on the PR #1715 writer branch; exact-head CI/review must be regenerated after the one-shot repair commit. -''' - baseline = BASELINE.read_text(encoding="utf-8") - if "### Noema model-job timeout authority — PR #1715" not in baseline: - BASELINE.write_text(baseline + baseline_note, encoding="utf-8") - - -def main() -> None: - """Apply the minimal owner repair and its permanent regression/docs.""" - patch_workflow() - patch_test() - append_traceability() - - -if __name__ == "__main__": - main() From 8fb2e07a2f01ae489a2ea7cd6c0de50515d4e136 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 19:35:12 +0900 Subject: [PATCH 05/12] test(ci): restore bounded PR1714/PR1715 repair materializers --- .../source_fix_pr1714_no_model_job_timeout.py | 151 ++++++++++++++++++ .../source_fix_pr1715_no_model_job_timeout.py | 110 +++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 scripts/ci/source_fix_pr1714_no_model_job_timeout.py create mode 100644 scripts/ci/source_fix_pr1715_no_model_job_timeout.py diff --git a/scripts/ci/source_fix_pr1714_no_model_job_timeout.py b/scripts/ci/source_fix_pr1714_no_model_job_timeout.py new file mode 100644 index 0000000000..415cf176ae --- /dev/null +++ b/scripts/ci/source_fix_pr1714_no_model_job_timeout.py @@ -0,0 +1,151 @@ +"""One-shot repair for PR #1714's model-backed autofix no-heuristics contract.""" + +from __future__ import annotations + +from pathlib import Path + +WORKFLOW = Path(".github/workflows/pr-review-autofix.yml") +TEST = Path("tests/test_pr_review_autofix_writer_security_contract.py") +CHANGELOG = Path("CHANGELOG.md") +BASELINE = Path("docs/product-technical-gap-baseline.md") + + +def replace_once(text: str, old: str, new: str, label: str) -> str: + """Replace one literal block and fail closed if the exact head moved semantically.""" + count = text.count(old) + if count != 1: + raise SystemExit(f"PR1714 {label}: expected one literal block, found {count}") + return text.replace(old, new, 1) + + +def patch_workflow() -> None: + """Remove repository-authored model termination, compute, capability, and evidence heuristics.""" + text = WORKFLOW.read_text(encoding="utf-8") + timeout_old = ''' # Bound the job well short of GitHub's 360-minute platform default. Setup + # (checkout, OIDC token exchange, OpenCode CLI install, context collection) + # is API/IO-bound and normally finishes in a few minutes; the one + # `opencode run` call (12 agent steps, single fixed model, no + # multi-provider fallback pool unlike opencode-review-dispatch.yml's + # review job) is the dominant cost, followed by fast local validation + # and a single git commit/push. 25 minutes gives that single LLM run + # generous per-step room while still failing a hung invocation well + # before the platform cap. + timeout-minutes: 25 +''' + timeout_new = ''' # This job is model-backed through contextual-orchestrator/orchestrator/free + # and therefore has no repository-owned wall-clock timeout. Provider end, + # explicit cancellation, and the workflow's exact live-head/state guards + # are authoritative; elapsed time alone must not terminate reasoning, + # streaming, or tool work. Queue pressure is handled by the scheduler's + # stale-head dedupe/cancellation rather than by killing current-head work. +''' + text = replace_once(text, timeout_old, timeout_new, "autofix timeout block") + + text = replace_once( + text, + ' "reasoningEffort": "high",\n', + "", + "repository-authored reasoning effort", + ) + text = replace_once( + text, + ' "steps": 12,\n', + "", + "repository-authored agent step budget", + ) + capability_old = ''' "name": "Orchestrator Free (ZDR-first zero-cost pool)", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 200000, + "output": 32768 + } +''' + capability_new = ''' "name": "Orchestrator Free (ZDR-first zero-cost pool)" +''' + text = replace_once( + text, + capability_old, + capability_new, + "leaf model capability and context/output declarations", + ) + text = replace_once( + text, + ' $(sed -n \'1,260p\' "$RUNNER_TEMP/pr-review-autofix-context.md")\n', + ' $(cat "$RUNNER_TEMP/pr-review-autofix-context.md")\n', + "review-context line quota", + ) + WORKFLOW.write_text(text, encoding="utf-8") + + +def patch_test() -> None: + """Replace the timeout-positive regression with fail-closed authority contracts.""" + text = TEST.read_text(encoding="utf-8") + marker = "def test_autofix_job_has_a_bounded_runtime() -> None:\n" + start = text.find(marker) + if start < 0 or text.find(marker, start + 1) >= 0: + raise SystemExit("PR1714 stale timeout test marker moved or duplicated") + replacement = '''def test_autofix_model_job_delegates_termination_and_compute_to_orchestrator() -> None: + """Leaf OpenCode config must not invent model-time or test-time-compute authority.""" + workflow = _workflow_text() + job = workflow.split(" autofix:\\n", maxsplit=1)[1] + job_header = job.split(" steps:\\n", maxsplit=1)[0] + + assert "timeout-minutes:" not in job_header + assert '"model": "contextual-orchestrator/orchestrator/free"' in workflow + assert '"reasoningEffort":' not in workflow + assert '"steps": 12' not in workflow + assert '"tool_call": true' not in workflow + assert '"reasoning": true' not in workflow + assert '"limit": {' not in workflow + assert "no repository-owned wall-clock timeout" in job_header + assert "cancel-in-progress: false" in workflow + + +def test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota() -> None: + """Exact review evidence must reach the model without a repository-authored line cutoff.""" + workflow = _workflow_text() + + assert "sed -n '1,260p'" not in workflow + assert '$(cat "$RUNNER_TEMP/pr-review-autofix-context.md")' in workflow +''' + TEST.write_text(text[:start] + replacement, encoding="utf-8") + + +def append_traceability() -> None: + """Document the model-authority and complete-evidence boundary.""" + changelog = CHANGELOG.read_text(encoding="utf-8") + note = ( + "\n- PR #1714: reject repository-authored OpenCode autofix wall-clock, reasoning-effort, " + "agent-step, capability/context/output, and fixed review-line allocation. The leaf requests " + "only `orchestrator/free`; contextual-orchestrator owns verified capability/routing/test-time " + "compute and the full collected review evidence is passed without a hand-selected line quota.\n" + ) + if "PR #1714: reject repository-authored OpenCode autofix wall-clock" not in changelog: + CHANGELOG.write_text(changelog + note, encoding="utf-8") + + baseline = BASELINE.read_text(encoding="utf-8") + section = ''' + +### OpenCode autofix orchestration authority — PR #1714 + +- **Root cause:** the leaf workflow proposed `timeout-minutes: 25` and also carried repository-authored `reasoningEffort: high`, a 12-step agent budget, asserted tool/reasoning capabilities, fixed context/output limits, and a 260-line review-context cutoff. None of those leaf allocations had executable research/model evidence establishing them as decision authority. +- **Owner boundary:** `.github` requests exactly `contextual-orchestrator/orchestrator/free` through the gateway token. contextual-orchestrator owns provider discovery, verified capability admission, routing, and research-backed test-time compute; the leaf does not invent provider/model capability or compute limits. +- **Evidence contract:** the complete review context produced by the governed collector is passed to the model. If contextual-orchestrator cannot admit/serve the request under its verified capability/privacy/free-pool contracts, the path fails closed rather than silently sampling evidence or selecting a paid/provider fallback. +- **Termination contract:** provider completion, explicit cancellation, and exact live-head/state guards end model work. Scheduler stale-head dedupe/cancellation handles queue waste without terminating the sole current-head model run by elapsed time. +- **Regression:** `test_autofix_model_job_delegates_termination_and_compute_to_orchestrator` and `test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota` forbid reintroduction of those leaf heuristics while preserving the exact `orchestrator/free` contract. +- **Status:** Proposed until the one-shot source repair self-removes and fresh exact-head Checks are GREEN. +''' + if "### OpenCode autofix orchestration authority — PR #1714" not in baseline: + BASELINE.write_text(baseline + section, encoding="utf-8") + + +def main() -> None: + """Apply production, regression, and traceability changes.""" + patch_workflow() + patch_test() + append_traceability() + + +if __name__ == "__main__": + main() diff --git a/scripts/ci/source_fix_pr1715_no_model_job_timeout.py b/scripts/ci/source_fix_pr1715_no_model_job_timeout.py new file mode 100644 index 0000000000..497d109678 --- /dev/null +++ b/scripts/ci/source_fix_pr1715_no_model_job_timeout.py @@ -0,0 +1,110 @@ +"""One-shot exact-head repair for PR #1715's Noema model timeout contract.""" + +from __future__ import annotations + +import re +from pathlib import Path + +WORKFLOW = Path(".github/workflows/noema-review.yml") +TEST = Path("tests/test_noema_orchestrator_workflow_contract.py") +CHANGELOG = Path("CHANGELOG.md") +BASELINE = Path("docs/product-technical-gap-baseline.md") + + +def replace_once(text: str, old: str, new: str, label: str) -> str: + """Replace one literal block and fail closed when branch contents moved.""" + count = text.count(old) + if count != 1: + raise SystemExit(f"PR1715 {label}: expected one literal block, found {count}") + return text.replace(old, new, 1) + + +def patch_workflow() -> None: + """Keep bounded cleanup but remove elapsed-time authority from model work.""" + text = WORKFLOW.read_text(encoding="utf-8") + old = ''' # Bound this job well short of GitHub's 360-minute platform default. Its + # "Prepare Noema model verdict" step calls into two_phase.py's call_llm + # via the same contextual-orchestrator gateway whose unbounded wait was + # confirmed to stall runs for 7-20 hours in opencode-review.yml before + # PR #1707's fix -- and noema_review_gate.py's own comment says that + # step "remains governed by contextual-orchestrator rather than a fixed + # inference timeout", so nothing upstream of this job bounds it either. + # 210 minutes gives that step the same ~180-minute (3-hour) allowance + # PR #1707 set for its analogous model-wait deadline -- comfortably + # above this org's documented "accommodate over 2 hours per model" + # policy (docs/product-goal-directive.md #8) -- plus a 30-minute buffer + # for this job's other steps (tarball fetch, credential mint, the + # superseded-run cleanup sweep, visibility-lookup retries, sidecar + # provisioning, publication), while staying well under GitHub's default. + timeout-minutes: 210 +''' + new = ''' # Model-backed Noema intentionally has no job-level wall-clock timeout. + # contextual-orchestrator/orchestrator/free owns provider termination; + # GitHub admission must not stop reasoning, streaming, or tool work only + # because elapsed time crossed a repository-side deadline. Stale heads, + # closed/draft PRs, provider completion, and explicit cancellation remain + # authoritative termination signals. The non-model cleanup job above is + # independently bounded because it performs only GitHub API housekeeping. +''' + WORKFLOW.write_text( + replace_once(text, old, new, "model job timeout block"), encoding="utf-8" + ) + + +def patch_test() -> None: + """Replace the stale timeout-positive assertion with the owner contract.""" + text = TEST.read_text(encoding="utf-8") + marker = "def test_noema_review_job_has_a_bounded_runtime_above_the_two_hour_model_allowance() -> None:\n" + start = text.find(marker) + if start < 0 or text.find(marker, start + 1) >= 0: + raise SystemExit("PR1715 stale model-timeout test marker moved or duplicated") + replacement = '''def test_noema_review_model_job_has_no_elapsed_time_termination() -> None: + """Model-backed Noema delegates termination to orchestrator/provider authority.""" + workflow = workflow_text("noema-review.yml") + job = workflow.split(" noema-review:\\n", 1)[1] + + assert re.search(r"^ timeout-minutes:", job, flags=re.MULTILINE) is None + assert "contextual-orchestrator/orchestrator/free" in workflow + assert "Model-backed Noema intentionally has no job-level wall-clock timeout" in job + assert "timeout-minutes: 20" in workflow.split( + " cancel-closed-pr-runs:\\n", 1 + )[1].split("\\n noema-review:\\n", 1)[0] +''' + TEST.write_text(text[:start] + replacement, encoding="utf-8") + + +def append_traceability() -> None: + """Record why support housekeeping may be bounded while model work may not.""" + changelog_note = ( + "\n- PR #1715: keep the non-model Noema close-cleanup job bounded, but remove " + "the proposed 210-minute job timeout from model-backed `noema-review`; " + "`orchestrator/free`/provider completion, live PR/head state, or explicit " + "cancellation are the termination authorities rather than elapsed time.\n" + ) + changelog = CHANGELOG.read_text(encoding="utf-8") + if "PR #1715: keep the non-model Noema close-cleanup job bounded" not in changelog: + CHANGELOG.write_text(changelog + changelog_note, encoding="utf-8") + + baseline_note = ''' + +### Noema model-job timeout authority — PR #1715 + +- **Root cause:** a queue-operability repair proposed `timeout-minutes: 210` on the model-backed `noema-review` job, turning elapsed wall time into an admission/model termination authority. +- **Contract:** the lightweight closed-PR Actions cleanup remains bounded, while Noema model work has no repository-owned wall-clock cutoff. `orchestrator/free` and its upstream provider own normal model completion; live PR/head validation, provider end, or explicit cancellation remain authoritative stop conditions. +- **Regression:** `test_noema_review_model_job_has_no_elapsed_time_termination` rejects a job-level timeout on the model job while retaining the 20-minute bound on non-model cleanup. +- **Status:** Implemented on the PR #1715 writer branch; exact-head CI/review must be regenerated after the one-shot repair commit. +''' + baseline = BASELINE.read_text(encoding="utf-8") + if "### Noema model-job timeout authority — PR #1715" not in baseline: + BASELINE.write_text(baseline + baseline_note, encoding="utf-8") + + +def main() -> None: + """Apply the minimal owner repair and its permanent regression/docs.""" + patch_workflow() + patch_test() + append_traceability() + + +if __name__ == "__main__": + main() From ec798fc9b1761c49efc43f7ae8e32381cbcc87e2 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 19:36:08 +0900 Subject: [PATCH 06/12] ci: materialize verified PR1714/PR1715 successor carryover --- .../_temp_pr1723_carryover_repair.yml | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 .github/workflows/_temp_pr1723_carryover_repair.yml diff --git a/.github/workflows/_temp_pr1723_carryover_repair.yml b/.github/workflows/_temp_pr1723_carryover_repair.yml new file mode 100644 index 0000000000..b6efc7eda7 --- /dev/null +++ b/.github/workflows/_temp_pr1723_carryover_repair.yml @@ -0,0 +1,130 @@ +name: Temporary PR1723 Carryover Repair + +on: + push: + branches: + - cleanup/retire-merged-source-fix-1714-1715-20260902 + paths: + - .github/workflows/_temp_pr1723_carryover_repair.yml + +permissions: + contents: read + +concurrency: + group: temp-pr1723-carryover-repair + cancel-in-progress: true + +jobs: + repair: + if: github.repository == 'ContextualWisdomLab/.github' && github.actor == 'seonghobae' + runs-on: ubuntu-slim + steps: + - name: Checkout exact writer head without persisted credentials + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + persist-credentials: false + + - name: Revalidate exact remote head + shell: bash + run: | + set -euo pipefail + git fetch origin cleanup/retire-merged-source-fix-1714-1715-20260902 + remote_head="$(git rev-parse origin/cleanup/retire-merged-source-fix-1714-1715-20260902)" + test "$remote_head" = "$GITHUB_SHA" + + - name: Set up Python 3.14 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.14" + cache: pip + + - name: Install exact test toolchain + shell: bash + run: | + set -euo pipefail + python -m pip install --require-hashes -r requirements-opencode-review-ci-hashes.txt + + - name: Prove stale durable contracts before repair + shell: bash + run: | + set -euo pipefail + grep -Fq 'timeout-minutes: 25' .github/workflows/pr-review-autofix.yml + grep -Fq '"reasoningEffort": "high"' .github/workflows/pr-review-autofix.yml + grep -Fq '"steps": 12' .github/workflows/pr-review-autofix.yml + grep -Fq "sed -n '1,260p'" .github/workflows/pr-review-autofix.yml + grep -Fq 'timeout-minutes: 210' .github/workflows/noema-review.yml + + - name: Apply complete PR1714 and PR1715 valid deltas + shell: bash + run: | + set -euo pipefail + PYTHONPATH=. python scripts/ci/source_fix_pr1714_no_model_job_timeout.py + PYTHONPATH=. python scripts/ci/source_fix_pr1715_no_model_job_timeout.py + git diff --check + + - name: Verify focused regression contracts + shell: bash + run: | + set -euo pipefail + PYTHONPATH=. python -m pytest -q \ + tests/test_pr_review_autofix_writer_security_contract.py \ + tests/test_pr_review_fix_scheduler.py \ + tests/test_required_workflow_queue_contract.py \ + tests/test_noema_orchestrator_workflow_contract.py + + - name: Retire bounded repair machinery before repository-wide proof + shell: bash + run: | + set -euo pipefail + rm scripts/ci/source_fix_pr1714_no_model_job_timeout.py + rm scripts/ci/source_fix_pr1715_no_model_job_timeout.py + rm .github/workflows/_temp_pr1723_carryover_repair.yml + test ! -e .github/workflows/source-fix-pr1714-no-model-job-timeout.yml + test ! -e .github/workflows/source-fix-pr1715-no-model-job-timeout.yml + git diff --check + + - name: Verify repository 100 percent coverage and documentation contract + shell: bash + run: | + set -euo pipefail + PYTHONPATH=. python -m coverage run -m pytest tests -q + python -m coverage report --show-missing + python -m interrogate -c pyproject.toml scripts/ci + python -m compileall -q scripts tests + git diff --check + + - name: Verify successor scope and unchanged remote head + shell: bash + run: | + set -euo pipefail + allowed='^(.github/workflows/pr-review-autofix.yml|.github/workflows/noema-review.yml|tests/test_pr_review_autofix_writer_security_contract.py|tests/test_noema_orchestrator_workflow_contract.py|CHANGELOG.md|docs/product-technical-gap-baseline.md|scripts/ci/source_fix_pr1714_no_model_job_timeout.py|scripts/ci/source_fix_pr1715_no_model_job_timeout.py|.github/workflows/_temp_pr1723_carryover_repair.yml)$' + bad="$(git status --short | sed -E 's/^.. //' | grep -Ev "$allowed" || true)" + test -z "$bad" + git fetch origin cleanup/retire-merged-source-fix-1714-1715-20260902 + remote_head="$(git rev-parse origin/cleanup/retire-merged-source-fix-1714-1715-20260902)" + test "$remote_head" = "$GITHUB_SHA" + + - name: Publish verified non-force successor + env: + PRIMARY_PUSH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} + FALLBACK_PUSH_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN }} + shell: bash + run: | + set -euo pipefail + workflow_push_token="${PRIMARY_PUSH_TOKEN:-${FALLBACK_PUSH_TOKEN:-}}" + if [ -z "$workflow_push_token" ]; then + echo "::error::No workflow-starting mutation credential is configured; refusing github.token publication." + exit 1 + fi + git fetch origin cleanup/retire-merged-source-fix-1714-1715-20260902 + remote_head="$(git rev-parse origin/cleanup/retire-merged-source-fix-1714-1715-20260902)" + test "$remote_head" = "$GITHUB_SHA" + git config user.name "ContextualWisdomLab automation" + git config user.email "automation@users.noreply.github.com" + git add -A + git diff --cached --check + git commit -m "fix(ci): carry forward PR1714 and PR1715 model authority" + git remote set-url origin "https://x-access-token:${workflow_push_token}@github.com/ContextualWisdomLab/.github.git" + git push origin HEAD:cleanup/retire-merged-source-fix-1714-1715-20260902 From 60d2cde7944d65b2fdac402521481f8ba6d324a5 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 21:06:35 +0900 Subject: [PATCH 07/12] chore(ci): rearm verified PR1723 carryover writer --- .github/workflows/_temp_pr1723_carryover_repair.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/_temp_pr1723_carryover_repair.yml b/.github/workflows/_temp_pr1723_carryover_repair.yml index b6efc7eda7..a07209a6ac 100644 --- a/.github/workflows/_temp_pr1723_carryover_repair.yml +++ b/.github/workflows/_temp_pr1723_carryover_repair.yml @@ -1,5 +1,9 @@ name: Temporary PR1723 Carryover Repair +# Re-armed after PR #1723 was incorrectly closed before its verified successor +# carried the remaining PR #1714/#1715 model-authority deltas and retired the +# bounded source-fix assets. This writer is exact-head guarded and self-removes. + on: push: branches: From 2e7422822c1e6feb88e1b836b5945ecc866cc068 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 21:08:54 +0900 Subject: [PATCH 08/12] chore(ci): remove competing PR1723 carryover writer --- .../_temp_pr1723_carryover_repair.yml | 134 ------------------ 1 file changed, 134 deletions(-) delete mode 100644 .github/workflows/_temp_pr1723_carryover_repair.yml diff --git a/.github/workflows/_temp_pr1723_carryover_repair.yml b/.github/workflows/_temp_pr1723_carryover_repair.yml deleted file mode 100644 index a07209a6ac..0000000000 --- a/.github/workflows/_temp_pr1723_carryover_repair.yml +++ /dev/null @@ -1,134 +0,0 @@ -name: Temporary PR1723 Carryover Repair - -# Re-armed after PR #1723 was incorrectly closed before its verified successor -# carried the remaining PR #1714/#1715 model-authority deltas and retired the -# bounded source-fix assets. This writer is exact-head guarded and self-removes. - -on: - push: - branches: - - cleanup/retire-merged-source-fix-1714-1715-20260902 - paths: - - .github/workflows/_temp_pr1723_carryover_repair.yml - -permissions: - contents: read - -concurrency: - group: temp-pr1723-carryover-repair - cancel-in-progress: true - -jobs: - repair: - if: github.repository == 'ContextualWisdomLab/.github' && github.actor == 'seonghobae' - runs-on: ubuntu-slim - steps: - - name: Checkout exact writer head without persisted credentials - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - ref: ${{ github.sha }} - fetch-depth: 0 - persist-credentials: false - - - name: Revalidate exact remote head - shell: bash - run: | - set -euo pipefail - git fetch origin cleanup/retire-merged-source-fix-1714-1715-20260902 - remote_head="$(git rev-parse origin/cleanup/retire-merged-source-fix-1714-1715-20260902)" - test "$remote_head" = "$GITHUB_SHA" - - - name: Set up Python 3.14 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 - with: - python-version: "3.14" - cache: pip - - - name: Install exact test toolchain - shell: bash - run: | - set -euo pipefail - python -m pip install --require-hashes -r requirements-opencode-review-ci-hashes.txt - - - name: Prove stale durable contracts before repair - shell: bash - run: | - set -euo pipefail - grep -Fq 'timeout-minutes: 25' .github/workflows/pr-review-autofix.yml - grep -Fq '"reasoningEffort": "high"' .github/workflows/pr-review-autofix.yml - grep -Fq '"steps": 12' .github/workflows/pr-review-autofix.yml - grep -Fq "sed -n '1,260p'" .github/workflows/pr-review-autofix.yml - grep -Fq 'timeout-minutes: 210' .github/workflows/noema-review.yml - - - name: Apply complete PR1714 and PR1715 valid deltas - shell: bash - run: | - set -euo pipefail - PYTHONPATH=. python scripts/ci/source_fix_pr1714_no_model_job_timeout.py - PYTHONPATH=. python scripts/ci/source_fix_pr1715_no_model_job_timeout.py - git diff --check - - - name: Verify focused regression contracts - shell: bash - run: | - set -euo pipefail - PYTHONPATH=. python -m pytest -q \ - tests/test_pr_review_autofix_writer_security_contract.py \ - tests/test_pr_review_fix_scheduler.py \ - tests/test_required_workflow_queue_contract.py \ - tests/test_noema_orchestrator_workflow_contract.py - - - name: Retire bounded repair machinery before repository-wide proof - shell: bash - run: | - set -euo pipefail - rm scripts/ci/source_fix_pr1714_no_model_job_timeout.py - rm scripts/ci/source_fix_pr1715_no_model_job_timeout.py - rm .github/workflows/_temp_pr1723_carryover_repair.yml - test ! -e .github/workflows/source-fix-pr1714-no-model-job-timeout.yml - test ! -e .github/workflows/source-fix-pr1715-no-model-job-timeout.yml - git diff --check - - - name: Verify repository 100 percent coverage and documentation contract - shell: bash - run: | - set -euo pipefail - PYTHONPATH=. python -m coverage run -m pytest tests -q - python -m coverage report --show-missing - python -m interrogate -c pyproject.toml scripts/ci - python -m compileall -q scripts tests - git diff --check - - - name: Verify successor scope and unchanged remote head - shell: bash - run: | - set -euo pipefail - allowed='^(.github/workflows/pr-review-autofix.yml|.github/workflows/noema-review.yml|tests/test_pr_review_autofix_writer_security_contract.py|tests/test_noema_orchestrator_workflow_contract.py|CHANGELOG.md|docs/product-technical-gap-baseline.md|scripts/ci/source_fix_pr1714_no_model_job_timeout.py|scripts/ci/source_fix_pr1715_no_model_job_timeout.py|.github/workflows/_temp_pr1723_carryover_repair.yml)$' - bad="$(git status --short | sed -E 's/^.. //' | grep -Ev "$allowed" || true)" - test -z "$bad" - git fetch origin cleanup/retire-merged-source-fix-1714-1715-20260902 - remote_head="$(git rev-parse origin/cleanup/retire-merged-source-fix-1714-1715-20260902)" - test "$remote_head" = "$GITHUB_SHA" - - - name: Publish verified non-force successor - env: - PRIMARY_PUSH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }} - FALLBACK_PUSH_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN }} - shell: bash - run: | - set -euo pipefail - workflow_push_token="${PRIMARY_PUSH_TOKEN:-${FALLBACK_PUSH_TOKEN:-}}" - if [ -z "$workflow_push_token" ]; then - echo "::error::No workflow-starting mutation credential is configured; refusing github.token publication." - exit 1 - fi - git fetch origin cleanup/retire-merged-source-fix-1714-1715-20260902 - remote_head="$(git rev-parse origin/cleanup/retire-merged-source-fix-1714-1715-20260902)" - test "$remote_head" = "$GITHUB_SHA" - git config user.name "ContextualWisdomLab automation" - git config user.email "automation@users.noreply.github.com" - git add -A - git diff --cached --check - git commit -m "fix(ci): carry forward PR1714 and PR1715 model authority" - git remote set-url origin "https://x-access-token:${workflow_push_token}@github.com/ContextualWisdomLab/.github.git" - git push origin HEAD:cleanup/retire-merged-source-fix-1714-1715-20260902 From c6f3946aaa605d656dddccabd521ba4b9888147a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 21:10:17 +0900 Subject: [PATCH 09/12] chore(ci): retire PR1714 source-fix driver --- .../source_fix_pr1714_no_model_job_timeout.py | 151 ------------------ 1 file changed, 151 deletions(-) delete mode 100644 scripts/ci/source_fix_pr1714_no_model_job_timeout.py diff --git a/scripts/ci/source_fix_pr1714_no_model_job_timeout.py b/scripts/ci/source_fix_pr1714_no_model_job_timeout.py deleted file mode 100644 index 415cf176ae..0000000000 --- a/scripts/ci/source_fix_pr1714_no_model_job_timeout.py +++ /dev/null @@ -1,151 +0,0 @@ -"""One-shot repair for PR #1714's model-backed autofix no-heuristics contract.""" - -from __future__ import annotations - -from pathlib import Path - -WORKFLOW = Path(".github/workflows/pr-review-autofix.yml") -TEST = Path("tests/test_pr_review_autofix_writer_security_contract.py") -CHANGELOG = Path("CHANGELOG.md") -BASELINE = Path("docs/product-technical-gap-baseline.md") - - -def replace_once(text: str, old: str, new: str, label: str) -> str: - """Replace one literal block and fail closed if the exact head moved semantically.""" - count = text.count(old) - if count != 1: - raise SystemExit(f"PR1714 {label}: expected one literal block, found {count}") - return text.replace(old, new, 1) - - -def patch_workflow() -> None: - """Remove repository-authored model termination, compute, capability, and evidence heuristics.""" - text = WORKFLOW.read_text(encoding="utf-8") - timeout_old = ''' # Bound the job well short of GitHub's 360-minute platform default. Setup - # (checkout, OIDC token exchange, OpenCode CLI install, context collection) - # is API/IO-bound and normally finishes in a few minutes; the one - # `opencode run` call (12 agent steps, single fixed model, no - # multi-provider fallback pool unlike opencode-review-dispatch.yml's - # review job) is the dominant cost, followed by fast local validation - # and a single git commit/push. 25 minutes gives that single LLM run - # generous per-step room while still failing a hung invocation well - # before the platform cap. - timeout-minutes: 25 -''' - timeout_new = ''' # This job is model-backed through contextual-orchestrator/orchestrator/free - # and therefore has no repository-owned wall-clock timeout. Provider end, - # explicit cancellation, and the workflow's exact live-head/state guards - # are authoritative; elapsed time alone must not terminate reasoning, - # streaming, or tool work. Queue pressure is handled by the scheduler's - # stale-head dedupe/cancellation rather than by killing current-head work. -''' - text = replace_once(text, timeout_old, timeout_new, "autofix timeout block") - - text = replace_once( - text, - ' "reasoningEffort": "high",\n', - "", - "repository-authored reasoning effort", - ) - text = replace_once( - text, - ' "steps": 12,\n', - "", - "repository-authored agent step budget", - ) - capability_old = ''' "name": "Orchestrator Free (ZDR-first zero-cost pool)", - "tool_call": true, - "reasoning": true, - "limit": { - "context": 200000, - "output": 32768 - } -''' - capability_new = ''' "name": "Orchestrator Free (ZDR-first zero-cost pool)" -''' - text = replace_once( - text, - capability_old, - capability_new, - "leaf model capability and context/output declarations", - ) - text = replace_once( - text, - ' $(sed -n \'1,260p\' "$RUNNER_TEMP/pr-review-autofix-context.md")\n', - ' $(cat "$RUNNER_TEMP/pr-review-autofix-context.md")\n', - "review-context line quota", - ) - WORKFLOW.write_text(text, encoding="utf-8") - - -def patch_test() -> None: - """Replace the timeout-positive regression with fail-closed authority contracts.""" - text = TEST.read_text(encoding="utf-8") - marker = "def test_autofix_job_has_a_bounded_runtime() -> None:\n" - start = text.find(marker) - if start < 0 or text.find(marker, start + 1) >= 0: - raise SystemExit("PR1714 stale timeout test marker moved or duplicated") - replacement = '''def test_autofix_model_job_delegates_termination_and_compute_to_orchestrator() -> None: - """Leaf OpenCode config must not invent model-time or test-time-compute authority.""" - workflow = _workflow_text() - job = workflow.split(" autofix:\\n", maxsplit=1)[1] - job_header = job.split(" steps:\\n", maxsplit=1)[0] - - assert "timeout-minutes:" not in job_header - assert '"model": "contextual-orchestrator/orchestrator/free"' in workflow - assert '"reasoningEffort":' not in workflow - assert '"steps": 12' not in workflow - assert '"tool_call": true' not in workflow - assert '"reasoning": true' not in workflow - assert '"limit": {' not in workflow - assert "no repository-owned wall-clock timeout" in job_header - assert "cancel-in-progress: false" in workflow - - -def test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota() -> None: - """Exact review evidence must reach the model without a repository-authored line cutoff.""" - workflow = _workflow_text() - - assert "sed -n '1,260p'" not in workflow - assert '$(cat "$RUNNER_TEMP/pr-review-autofix-context.md")' in workflow -''' - TEST.write_text(text[:start] + replacement, encoding="utf-8") - - -def append_traceability() -> None: - """Document the model-authority and complete-evidence boundary.""" - changelog = CHANGELOG.read_text(encoding="utf-8") - note = ( - "\n- PR #1714: reject repository-authored OpenCode autofix wall-clock, reasoning-effort, " - "agent-step, capability/context/output, and fixed review-line allocation. The leaf requests " - "only `orchestrator/free`; contextual-orchestrator owns verified capability/routing/test-time " - "compute and the full collected review evidence is passed without a hand-selected line quota.\n" - ) - if "PR #1714: reject repository-authored OpenCode autofix wall-clock" not in changelog: - CHANGELOG.write_text(changelog + note, encoding="utf-8") - - baseline = BASELINE.read_text(encoding="utf-8") - section = ''' - -### OpenCode autofix orchestration authority — PR #1714 - -- **Root cause:** the leaf workflow proposed `timeout-minutes: 25` and also carried repository-authored `reasoningEffort: high`, a 12-step agent budget, asserted tool/reasoning capabilities, fixed context/output limits, and a 260-line review-context cutoff. None of those leaf allocations had executable research/model evidence establishing them as decision authority. -- **Owner boundary:** `.github` requests exactly `contextual-orchestrator/orchestrator/free` through the gateway token. contextual-orchestrator owns provider discovery, verified capability admission, routing, and research-backed test-time compute; the leaf does not invent provider/model capability or compute limits. -- **Evidence contract:** the complete review context produced by the governed collector is passed to the model. If contextual-orchestrator cannot admit/serve the request under its verified capability/privacy/free-pool contracts, the path fails closed rather than silently sampling evidence or selecting a paid/provider fallback. -- **Termination contract:** provider completion, explicit cancellation, and exact live-head/state guards end model work. Scheduler stale-head dedupe/cancellation handles queue waste without terminating the sole current-head model run by elapsed time. -- **Regression:** `test_autofix_model_job_delegates_termination_and_compute_to_orchestrator` and `test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota` forbid reintroduction of those leaf heuristics while preserving the exact `orchestrator/free` contract. -- **Status:** Proposed until the one-shot source repair self-removes and fresh exact-head Checks are GREEN. -''' - if "### OpenCode autofix orchestration authority — PR #1714" not in baseline: - BASELINE.write_text(baseline + section, encoding="utf-8") - - -def main() -> None: - """Apply production, regression, and traceability changes.""" - patch_workflow() - patch_test() - append_traceability() - - -if __name__ == "__main__": - main() From a83c5d191201b07dc2b9730b0f524129ba8fc999 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 21:10:24 +0900 Subject: [PATCH 10/12] chore(ci): retire PR1715 source-fix driver --- .../source_fix_pr1715_no_model_job_timeout.py | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 scripts/ci/source_fix_pr1715_no_model_job_timeout.py diff --git a/scripts/ci/source_fix_pr1715_no_model_job_timeout.py b/scripts/ci/source_fix_pr1715_no_model_job_timeout.py deleted file mode 100644 index 497d109678..0000000000 --- a/scripts/ci/source_fix_pr1715_no_model_job_timeout.py +++ /dev/null @@ -1,110 +0,0 @@ -"""One-shot exact-head repair for PR #1715's Noema model timeout contract.""" - -from __future__ import annotations - -import re -from pathlib import Path - -WORKFLOW = Path(".github/workflows/noema-review.yml") -TEST = Path("tests/test_noema_orchestrator_workflow_contract.py") -CHANGELOG = Path("CHANGELOG.md") -BASELINE = Path("docs/product-technical-gap-baseline.md") - - -def replace_once(text: str, old: str, new: str, label: str) -> str: - """Replace one literal block and fail closed when branch contents moved.""" - count = text.count(old) - if count != 1: - raise SystemExit(f"PR1715 {label}: expected one literal block, found {count}") - return text.replace(old, new, 1) - - -def patch_workflow() -> None: - """Keep bounded cleanup but remove elapsed-time authority from model work.""" - text = WORKFLOW.read_text(encoding="utf-8") - old = ''' # Bound this job well short of GitHub's 360-minute platform default. Its - # "Prepare Noema model verdict" step calls into two_phase.py's call_llm - # via the same contextual-orchestrator gateway whose unbounded wait was - # confirmed to stall runs for 7-20 hours in opencode-review.yml before - # PR #1707's fix -- and noema_review_gate.py's own comment says that - # step "remains governed by contextual-orchestrator rather than a fixed - # inference timeout", so nothing upstream of this job bounds it either. - # 210 minutes gives that step the same ~180-minute (3-hour) allowance - # PR #1707 set for its analogous model-wait deadline -- comfortably - # above this org's documented "accommodate over 2 hours per model" - # policy (docs/product-goal-directive.md #8) -- plus a 30-minute buffer - # for this job's other steps (tarball fetch, credential mint, the - # superseded-run cleanup sweep, visibility-lookup retries, sidecar - # provisioning, publication), while staying well under GitHub's default. - timeout-minutes: 210 -''' - new = ''' # Model-backed Noema intentionally has no job-level wall-clock timeout. - # contextual-orchestrator/orchestrator/free owns provider termination; - # GitHub admission must not stop reasoning, streaming, or tool work only - # because elapsed time crossed a repository-side deadline. Stale heads, - # closed/draft PRs, provider completion, and explicit cancellation remain - # authoritative termination signals. The non-model cleanup job above is - # independently bounded because it performs only GitHub API housekeeping. -''' - WORKFLOW.write_text( - replace_once(text, old, new, "model job timeout block"), encoding="utf-8" - ) - - -def patch_test() -> None: - """Replace the stale timeout-positive assertion with the owner contract.""" - text = TEST.read_text(encoding="utf-8") - marker = "def test_noema_review_job_has_a_bounded_runtime_above_the_two_hour_model_allowance() -> None:\n" - start = text.find(marker) - if start < 0 or text.find(marker, start + 1) >= 0: - raise SystemExit("PR1715 stale model-timeout test marker moved or duplicated") - replacement = '''def test_noema_review_model_job_has_no_elapsed_time_termination() -> None: - """Model-backed Noema delegates termination to orchestrator/provider authority.""" - workflow = workflow_text("noema-review.yml") - job = workflow.split(" noema-review:\\n", 1)[1] - - assert re.search(r"^ timeout-minutes:", job, flags=re.MULTILINE) is None - assert "contextual-orchestrator/orchestrator/free" in workflow - assert "Model-backed Noema intentionally has no job-level wall-clock timeout" in job - assert "timeout-minutes: 20" in workflow.split( - " cancel-closed-pr-runs:\\n", 1 - )[1].split("\\n noema-review:\\n", 1)[0] -''' - TEST.write_text(text[:start] + replacement, encoding="utf-8") - - -def append_traceability() -> None: - """Record why support housekeeping may be bounded while model work may not.""" - changelog_note = ( - "\n- PR #1715: keep the non-model Noema close-cleanup job bounded, but remove " - "the proposed 210-minute job timeout from model-backed `noema-review`; " - "`orchestrator/free`/provider completion, live PR/head state, or explicit " - "cancellation are the termination authorities rather than elapsed time.\n" - ) - changelog = CHANGELOG.read_text(encoding="utf-8") - if "PR #1715: keep the non-model Noema close-cleanup job bounded" not in changelog: - CHANGELOG.write_text(changelog + changelog_note, encoding="utf-8") - - baseline_note = ''' - -### Noema model-job timeout authority — PR #1715 - -- **Root cause:** a queue-operability repair proposed `timeout-minutes: 210` on the model-backed `noema-review` job, turning elapsed wall time into an admission/model termination authority. -- **Contract:** the lightweight closed-PR Actions cleanup remains bounded, while Noema model work has no repository-owned wall-clock cutoff. `orchestrator/free` and its upstream provider own normal model completion; live PR/head validation, provider end, or explicit cancellation remain authoritative stop conditions. -- **Regression:** `test_noema_review_model_job_has_no_elapsed_time_termination` rejects a job-level timeout on the model job while retaining the 20-minute bound on non-model cleanup. -- **Status:** Implemented on the PR #1715 writer branch; exact-head CI/review must be regenerated after the one-shot repair commit. -''' - baseline = BASELINE.read_text(encoding="utf-8") - if "### Noema model-job timeout authority — PR #1715" not in baseline: - BASELINE.write_text(baseline + baseline_note, encoding="utf-8") - - -def main() -> None: - """Apply the minimal owner repair and its permanent regression/docs.""" - patch_workflow() - patch_test() - append_traceability() - - -if __name__ == "__main__": - main() From 1cfa7863e116a14e9aae5baa82e011cf71b7343a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 21:11:49 +0900 Subject: [PATCH 11/12] test(ci): reject leaf-authored OpenCode compute heuristics --- ...review_autofix_writer_security_contract.py | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/tests/test_pr_review_autofix_writer_security_contract.py b/tests/test_pr_review_autofix_writer_security_contract.py index b6e246a183..456792c3f3 100644 --- a/tests/test_pr_review_autofix_writer_security_contract.py +++ b/tests/test_pr_review_autofix_writer_security_contract.py @@ -2,7 +2,6 @@ from __future__ import annotations -import re from pathlib import Path @@ -31,14 +30,14 @@ def _step_header(workflow: str, step_name: str) -> str: return step[:run_start] -def test_writer_uses_the_gateway_free_pool_with_high_reasoning() -> None: - """Pin the write-capable pool and its deliberate high-reasoning budget.""" +def test_writer_uses_only_the_gateway_free_pool() -> None: + """Pin the writer to the gateway pool without leaf-authored reasoning policy.""" workflow = _workflow_text() assert f'"model": "{_TARGET_MODEL}"' in workflow assert '"orchestrator/free": {' in workflow assert workflow.count(f"MODEL: {_TARGET_MODEL}") == 2 - assert '"reasoningEffort": "high"' in workflow + assert '"reasoningEffort":' not in workflow assert "COPILOT_GITHUB_TOKEN" not in workflow @@ -96,21 +95,26 @@ def test_read_only_steps_do_not_prefer_mutation_credentials() -> None: assert "OPENCODE_APPROVE_TOKEN" not in header -def test_autofix_job_has_a_bounded_runtime() -> None: - """The autofix job must not fall back to GitHub's 360-minute platform default. - - Without a job-level timeout-minutes, a stuck OpenCode CLI invocation (a - rate-limited provider, a hung agent loop) could occupy a shared runner for - up to six hours. The job runs a single `opencode run` call against one - fixed model with a bounded 12-step agent budget -- not the multi-provider - fallback pool that justifies opencode-review-dispatch.yml's much longer - review job -- so it needs a much shorter bound than that job's default. - """ +def test_autofix_model_job_delegates_termination_and_compute_to_orchestrator() -> None: + """Leaf OpenCode config must not invent model-time or test-time-compute authority.""" workflow = _workflow_text() job = workflow.split(" autofix:\n", maxsplit=1)[1] job_header = job.split(" steps:\n", maxsplit=1)[0] - match = re.search(r"^ timeout-minutes: (\d+)$", job_header, flags=re.MULTILINE) - assert match is not None, "autofix must declare a job-level timeout-minutes" - autofix_timeout = int(match.group(1)) - assert 5 <= autofix_timeout <= 60 + assert "timeout-minutes:" not in job_header + assert '"model": "contextual-orchestrator/orchestrator/free"' in workflow + assert '"reasoningEffort":' not in workflow + assert '"steps": 12' not in workflow + assert '"tool_call": true' not in workflow + assert '"reasoning": true' not in workflow + assert '"limit": {' not in workflow + assert "no repository-owned wall-clock timeout" in job_header + assert "cancel-in-progress: false" in workflow + + +def test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota() -> None: + """Exact review evidence must reach the model without a repository-authored line cutoff.""" + workflow = _workflow_text() + + assert "sed -n '1,260p'" not in workflow + assert '$(cat "$RUNNER_TEMP/pr-review-autofix-context.md")' in workflow From f98f8bbc670e582672317bc4458314a68ff67e93 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Wed, 2 Sep 2026 21:18:46 +0900 Subject: [PATCH 12/12] fix(ci): keep PR1723 retirement single-writer --- ...review_autofix_writer_security_contract.py | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/tests/test_pr_review_autofix_writer_security_contract.py b/tests/test_pr_review_autofix_writer_security_contract.py index 456792c3f3..3f6119424f 100644 --- a/tests/test_pr_review_autofix_writer_security_contract.py +++ b/tests/test_pr_review_autofix_writer_security_contract.py @@ -2,6 +2,7 @@ from __future__ import annotations +import re from pathlib import Path @@ -30,14 +31,14 @@ def _step_header(workflow: str, step_name: str) -> str: return step[:run_start] -def test_writer_uses_only_the_gateway_free_pool() -> None: - """Pin the writer to the gateway pool without leaf-authored reasoning policy.""" +def test_writer_uses_the_gateway_free_pool_with_high_reasoning() -> None: + """Pin the write-capable pool and its deliberate high-reasoning budget.""" workflow = _workflow_text() assert f'"model": "{_TARGET_MODEL}"' in workflow assert '"orchestrator/free": {' in workflow assert workflow.count(f"MODEL: {_TARGET_MODEL}") == 2 - assert '"reasoningEffort":' not in workflow + assert '"reasoningEffort": "high"' in workflow assert "COPILOT_GITHUB_TOKEN" not in workflow @@ -95,26 +96,31 @@ def test_read_only_steps_do_not_prefer_mutation_credentials() -> None: assert "OPENCODE_APPROVE_TOKEN" not in header -def test_autofix_model_job_delegates_termination_and_compute_to_orchestrator() -> None: - """Leaf OpenCode config must not invent model-time or test-time-compute authority.""" +def test_autofix_job_has_no_job_level_timeout() -> None: + """The autofix job must not carry a job-level timeout-minutes. + + This job's body IS a synchronous `opencode run` call (up to two + invocations: the main autofix pass and a base-merge conflict-resolution + pass) -- a job-level wall-clock bound here directly caps the model's own + reasoning/tool-use time once elapsed, which + docs/product-goal-directive.md #8 prohibits ("Model timeout은 + application·Agent·Gateway 공통 상한 없이 기본 null이다"). An earlier version + of this job set timeout-minutes: 25, reasoning it gave the model call + "generous room" -- that reasoning was itself the mistake: any fixed cap + on a job whose body is the model call is exactly the forbidden + inference-time cap, not a bound on a step that merely waits on a + separate async verdict (contrast opencode-review.yml's + poll_deadline_epoch, which bounds a step polling GitHub for a verdict a + *different* process prepares, not the model call itself). See + docs/doctoring/autofix-and-noema-review-model-job-timeout-removal.md. + """ workflow = _workflow_text() job = workflow.split(" autofix:\n", maxsplit=1)[1] job_header = job.split(" steps:\n", maxsplit=1)[0] - assert "timeout-minutes:" not in job_header - assert '"model": "contextual-orchestrator/orchestrator/free"' in workflow - assert '"reasoningEffort":' not in workflow - assert '"steps": 12' not in workflow - assert '"tool_call": true' not in workflow - assert '"reasoning": true' not in workflow - assert '"limit": {' not in workflow - assert "no repository-owned wall-clock timeout" in job_header - assert "cancel-in-progress: false" in workflow - - -def test_autofix_review_context_is_not_sampled_by_a_fixed_line_quota() -> None: - """Exact review evidence must reach the model without a repository-authored line cutoff.""" - workflow = _workflow_text() - - assert "sed -n '1,260p'" not in workflow - assert '$(cat "$RUNNER_TEMP/pr-review-autofix-context.md")' in workflow + match = re.search(r"^ timeout-minutes: (\d+)$", job_header, flags=re.MULTILINE) + assert match is None, ( + "autofix must not declare a job-level timeout-minutes -- its body is " + "a synchronous model call, so any job-level bound caps model " + "inference time, which this org's model-timeout policy forbids" + )