diff --git a/.github/scripts/agents_pr_meta_update_body.js b/.github/scripts/agents_pr_meta_update_body.js index 3e987c10c..8d0bed771 100644 --- a/.github/scripts/agents_pr_meta_update_body.js +++ b/.github/scripts/agents_pr_meta_update_body.js @@ -706,7 +706,25 @@ function upsertBlock(body, marker, replacement) { const startIndex = body.indexOf(start); const endIndex = body.indexOf(end); if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) { - return `${body.slice(0, startIndex)}${replacement}${body.slice(endIndex + end.length)}`; + // Replace the first marker pair in place + let result = `${body.slice(0, startIndex)}${replacement}${body.slice(endIndex + end.length)}`; + + // Remove any duplicate marker pairs left by concurrent writers + let hadDuplicates = false; + let limit = 10; + while (limit-- > 0) { + const dupStart = result.indexOf(start, startIndex + replacement.length); + const dupEnd = result.indexOf(end, dupStart + start.length); + if (dupStart !== -1 && dupEnd !== -1 && dupEnd > dupStart) { + result = `${result.slice(0, dupStart)}${result.slice(dupEnd + end.length)}`; + hadDuplicates = true; + } else { + break; + } + } + + // Collapse triple+ newlines left by removed blocks + return hadDuplicates ? result.replace(/\n{3,}/g, '\n\n') : result; } const trimmed = body.trimEnd(); diff --git a/.github/scripts/agents_verifier_context.js b/.github/scripts/agents_verifier_context.js index 79eefbd09..e2e8195a1 100644 --- a/.github/scripts/agents_verifier_context.js +++ b/.github/scripts/agents_verifier_context.js @@ -378,28 +378,10 @@ async function buildVerifierContext({ github, context, core, ciWorkflows }) { }; } - const baseRef = pr.base?.ref || ''; - const defaultBranch = context.payload?.repository?.default_branch || DEFAULT_BRANCH; - if (baseRef && baseRef !== defaultBranch) { - const skipReason = `Pull request base ref ${baseRef} does not match default branch ${defaultBranch}; skipping verifier.`; - core?.notice?.(skipReason); - core?.setOutput?.('should_run', 'false'); - core?.setOutput?.('skip_reason', skipReason); - core?.setOutput?.('pr_number', String(pr.number || '')); - core?.setOutput?.('issue_numbers', '[]'); - core?.setOutput?.('pr_html_url', pr.html_url || ''); - core?.setOutput?.('target_sha', pr.merge_commit_sha || pr.head?.sha || context.sha || ''); - core?.setOutput?.('context_path', ''); - core?.setOutput?.('acceptance_count', '0'); - core?.setOutput?.('ci_results', '[]'); - core?.setOutput?.('diff_summary_path', ''); - core?.setOutput?.('diff_path', ''); - core?.setOutput?.('chain_depth', '0'); - return { shouldRun: false, reason: skipReason, ciResults: [] }; - } - const prDetails = await github.rest.pulls.get({ owner, repo, pull_number: pr.number }); const pull = prDetails?.data || pr; + const baseRef = pull.base?.ref || pr.base?.ref || ''; + const defaultBranch = context.payload?.repository?.default_branch || DEFAULT_BRANCH; if (isForkPullRequest(pull)) { const skipReason = 'Pull request is from a fork; skipping verifier.'; diff --git a/CLAUDE.md b/CLAUDE.md index 1010de58c..685aac408 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -87,32 +87,6 @@ See `docs/INTEGRATION_GUIDE.md` in Workflows repo. - Fix in Workflows repo → sync will propagate here - Or request manual sync: `gh workflow run maint-68-sync-consumer-repos.yml --repo stranske/Workflows` -## Slow Test Strategy - -This repo uses a `slow` pytest marker to keep PR Gate fast (~4 min) while -ensuring heavyweight tests still run on Main CI. - -**How it works:** - -- `pyproject.toml` registers the `slow` marker. -- `pr-00-gate.yml` passes `pytest_markers: "not release and not slow"` to - exclude slow tests from PR feedback. -- `ci.yml` (Main CI) runs the **full** suite including slow tests. -- Locally, `make test` also excludes slow tests for fast iteration. - -**Currently marked slow:** - -- `tests/pipeline/test_run_pipeline.py` — auto-marked by - `tests/pipeline/conftest.py` (each test runs the full pipeline with - real Excel fixtures, 100-170 s each). -- `tests/spec/test_macro_spec_fixtures.py` — module-level - `pytestmark = pytest.mark.slow` (session fixture parses three NISA - workbooks, ~85 s). - -**Rule for agents:** any new test that parses real workbooks or calls -`run_pipeline()` **must** be marked `@pytest.mark.slow`. Omitting the -marker will silently regress Gate duration for every open PR. - ## Reference Implementation **Travel-Plan-Permission** is the reference consumer repo. When debugging: diff --git a/scripts/langchain/capability_check.py b/scripts/langchain/capability_check.py index 61269c690..ef64b889a 100755 --- a/scripts/langchain/capability_check.py +++ b/scripts/langchain/capability_check.py @@ -139,9 +139,7 @@ def _build_llm_config( issue_or_pr = ( str(issue_number) if issue_number is not None - else env_issue - if env_issue.isdigit() - else "unknown" + else env_issue if env_issue.isdigit() else "unknown" ) metadata = { "repo": repo, diff --git a/scripts/langchain/issue_optimizer.py b/scripts/langchain/issue_optimizer.py index 3a7d6b5ed..12d74802e 100755 --- a/scripts/langchain/issue_optimizer.py +++ b/scripts/langchain/issue_optimizer.py @@ -319,9 +319,7 @@ def _build_llm_config( issue_or_pr = ( str(issue_number) if issue_number is not None - else env_issue - if env_issue.isdigit() - else "unknown" + else env_issue if env_issue.isdigit() else "unknown" ) metadata = { "repo": repo, diff --git a/tools/langchain_client.py b/tools/langchain_client.py index 2e8ee842c..124f4197a 100644 --- a/tools/langchain_client.py +++ b/tools/langchain_client.py @@ -148,12 +148,6 @@ def _resolve_slots() -> list[SlotDefinition]: return _apply_slot_env_overrides(_load_slot_config()) -def list_slot_definitions() -> list[SlotDefinition]: - """Return configured LLM slot definitions after env overrides.""" - - return list(_resolve_slots()) - - def get_provider_model_catalog() -> dict[str, set[str]]: """Return provider->model mappings from configured slots."""